• Civilization 7 has been announced. For more info please check the forum here .

C++/Lua Request Thread

Hi all

I'd like to change happiness/unhappiness generation for a custom civ in my line of Warhammer Fantasy civs:

- Generate one unhappiness per turn for every turn in which the player is NOT at war with at least one other civ. Would be good if this could kick in after a certain number of turns, which I could adjust or which could scale to map size/game speed, just so the early game isn't punished.

- Generate one happiness for every kill, to last a certain number of turns (again, I'd like to be able to adjust or scale the number of turns each happiness generated per kill lasts).

Overall intention is obviously to create a civ that needs to be constantly fighting wars in order to stay happy/growing. Unhappiness from annexation still happens so they can't steamroll everyone, and if they wind up being too OP I can reduce the number of turns each happiness per kill lasts. Should be fun, and I think the code ought to be pretty simple.

The above is all I'm desperate for, but I'd also like to experiment with eliminating happiness from luxuries and I can't see if this is possible in XML alone, so if you could include some code that I could comment in/out to let me tinker with that, that'd be brilliant (but not essential).

Reply or PM me if you come up with something. Thanks very much in advance! :goodjob:


- RSJ
 
I've finally hit a wall in my own modding of Civ.

For the life of me I can't seem to find the code associated with assigning embarkment defense, and while I can find it's definition in the xml I imagine there is a logic code assigning it. I am looking to assign combat str the same way (changing when the era changes) for a unit (a combat capable great general). I can get the definition to show in the tables, just don't have the know-how of lua to write the script for it to replace the generals CS.

In addition I am hunting for the code that determines what you get when you 'sell' a unit, as I would like to change it. (In both value and type {i.e. selling units for science instead of gold.})

I would appreciate either (or both) the game code that is relevant or lua code that could achieve what I am looking for. I do not, atm, have access to the dll, but will be fixing that in a few days and will edit if I can fix my own problems. Thanks! ~Jordangander
 
Inightshade, you can add embarkment defense via promotion (EmbarkDefenseModifier). You can also use a promotion to add general combat strength. There is a lua event that fires when an era changes so you just hook into that and add/remove promotions. I have some code in my Titans of Commerce, Science & Industry mod that gives different promotions to Great Merchants depending on the era. You could reuse most of it and edit it to apply the promotion to all military units.

As for selling units for extra Gold or Science, that will require a DLL mod.
 
Thanks a ton Machiavelli24. Managed to get my UU working. Though via a different process, but your code helped me figure out the syntax I was messing up on!

I got my hands into the dll and found the scrap() function (that which grants gold for disbanding units) and wow did they make it a challenge to alter, if only it was called as an event and I could intercept it (Instead it's a closed loop, summoned by some core function, can't edit how I'd like, not without much more experience with C++).
Oh well, I can improvise by just adding science to a civ when one of their units dies, shouldn't be too overwhelming if I keep the formula similar.

Anyways, as a side note, does anyone know if it is feasible to increase the base hp for units? (as a UA, so conditionally.)
 
Hi. I'm an amateur modder. As a graphic designer most of my skills come in composing the art for custom civs and I fumble through making them work. So far this means they look polished but their abilities are quite simple and lackluster due to using exclusively XML.

To the point, I'm working on an idea for a Roman mod. The base Rome civ is nice, but it doesn't quite do it for me. I have the units worked out and I like the idea I have for a custom ability but no idea how to implement it.

So it goes like this, it's somewhere between Brazil's Carnival and Assyria's tech stealing. Conquering cities (only for the first time, like Assyria's ability) grants a variation of a golden age called "Triumph". The amount of turns would be based on population, ideally functioning like this:

Say a city has ten population, if when conquered you have 4 population remaining you would get 4 turns of "Triumph". Ideally, like Carnival, it would also replace the "Golden Age" text on the UI. Make sense?

I would be very appreciative if anyone of you who are Lua masters can lend me a hand. I might be able to repay any help with art for your future mods in return.

Thanks in advance. I realize actually I have such little experience with Lua that I'm not even sure how large a request this is.
 
Wakeup, most of that can be done pretty easily.

There is an event that fires when a city is captured, you can hook into it and if the conqueror is rome, give them Golden Age turns or Golden Age progress.
Code:
function romanTriumph(hexPos, playerID, cityID, newPlayerID)
	local player = Players[newPlayerID];
	local plot = Map.GetPlot(ToGridFromHex(hexPos.x, hexPos.y));
	local city = plot:GetPlotCity();

	if([COLOR="Gray"]player is rome and first time capturing[/COLOR]) then
		[COLOR="Gray"]mark city as providing triumph[/COLOR]
		player:ChangeGoldenAgeTurns(city:GetPopulation());
	end
end
Events.SerialEventCityCaptured.Add(romanTriumph);

You can also use promotions to have units generate Golden Age progress for kills.
 
So that's fantastic, thank you very much for your help. It's easier than I thought to do the code then.

Alright, so here's the rub. Usually when I'm formatting a modded Civilization I'm using XML files to set up the unique ability in the SDK tools. So when I go about setting this up, I'm not sure how to specifically use this piece of code or how to make sure it works properly.

For instance, let's say I set up my Trait information, adding the new Trait, it's text keys, and everything else. I have this Lua script now. How to I make the added trait reference this lua? Import it into the VFS? Or some other method. I assume as long as the Lua is active and the function is correct it would activate regardless of XML and all that would be left to do was handle text keys.

Also, since this isn't a Rome tweak mod, so much as a unique, from the ground up version, would that change how it would need to be referenced in the script?

If you're getting the sense that I don't know enough to even know what to ask, you'd be right. I tried to reference one of JFD's mods to get a sense of how some of it was done but couldn't make enough sense of it to really work it out. In his Charlemagne mod he referenced his civ like this:

if player:GetCivilizationType() == GameInfoTypes["CIVILIZATION_JFD_THE_FRANKS"] then

I assume I would do something similar with mine just with the script you have above? Perhaps something more XML friendly. Apparently to do the really interesting stuff I have a lot left to learn, SQL is also a total mystery to me for the most part, just starting to dabble. Everyone has to start somewhere though, I suppose.

Again, sorry for the hassle. If I get this to work I'll be sure to sing your praises in all sorts of disclaimers.
 
Ok so I did a little research and learned how to to a InGameUIAddin for the lua script, so that's not bad, and seeing as how I'm in over my head as it is I figure it might be best to make it work as a Rome tweak before getting too crazy.

I tried that, adding the InGameUIAddin and following the instructions here: http://forums.civfanatics.com/showthread.php?t=487846

One thing I notice is that even then it doesn't quite work yet. Is this the script I need verbatim if using regular Augustus Rome from the base game?

function romanTriumph(hexPos, playerID, cityID, newPlayerID)
local player = Players[newPlayerID];
local plot = Map.GetPlot(ToGridFromHex(hexPos.x, hexPos.y));
local city = plot:GetPlotCity();

if(player is rome and first time capturing) then
mark city as providing triumph
player:ChangeGoldenAgeTurns(city:GetPopulation());
end
end
Events.SerialEventCityCaptured.Add(romanTriumph);


Or does it require something filled in I've missed? I have the XML to replace the trait, as well as the text, all that works great, just not activating properly.

I do notice in my lua file the script does not appear in brackets of any kind, as if the file isn't formatted just right. Thanks again, hopefully learning about the InGameUIAddin makes it less painful to help. I have half a clue now. Ha.
 
Alright bubbles.

function romanTriumph(hexPos, playerID, cityID, newPlayerID)
local player = Players[newPlayerID];
local plot = Map.GetPlot(ToGridFromHex(hexPos.x, hexPos.y));
local city = plot:GetPlotCity();

if(player is rome and first time capturing) then
mark city as providing triumph
player:ChangeGoldenAgeTurns(city:GetPopulation());
end
end
Events.SerialEventCityCaptured.Add(romanTriumph);

I can (only) assume that what your problem is would be this. Whats colored isn't actual code.
(Thus, syntax errors, thus won't even try to run.)
You can replace the magenta with:
player:GetCivilizationType() == GameInfoTypes.CIVILIZATION_ROME
And for the red, I (might?) could assume that if you set up a variable outside of the function you could use it to keep track of the cities captured, but that might be a bit of a strain. The easiest thing would be using a database table and changing it accordingly, but I have NO clue (if you even can) how to alter database variables from lua script.
You can ditch the red bits for the time being until someone (a little more lua savvy) can help, and it'll just be open to exploitation while you test it. (Alas one of my mods has a serious balance issue, but for the time being it'll have to suffice. The lack of lua functions for adding science is quite annoying. However the fix is a dll mod but at that point I might as well add in my own function and button. {Tho, too busy back with skyrim rtm, and with Civ:BE being around the corner...})

~Jordangander (EDIT: Woah yellow is a blinding color.)
 
Hey guys, I'm looking for some code that will allow a unit to gain a 25% Defensive Bonus and +1 Happiness for the empire when fortified on a Luxury Resource.

We are also looking for some code in which you gain Influence from Friendly City-States if War is declared against you.
 
Bubbles, sorry I forgot to explain that the grey sections were pseudo-code. Inightshade already covered how to test if the civilization is rome but the easist way to ensure that cities only grant triumph once is to mark them with a building that can not be built and does nothing.
-------------
TPangolin, you can use:
Code:
GameEvents.UnitSetXY(PlayerID player, UnitID unit, int x, int y)
To detect when a unit moves into a tile, but you can't tell if they are fortified. Determining when such a unit leaves the tile will also be tricky. You'll need to store the unitIDs of units on luxury tiles and when a unit moves you'll need to see if it was one of the luxury campers. You'll also need to test each turn to see if any of the luxury campers died (there is no easy way to directly detect when a unit dies).
---------
As for gaining Influence when War is declared. Manipulating city-state influence is easy, use:
Code:
minorCiv:ChangeMinorCivFriendshipWithMajor(int majorPlayerID, int influenceChange);
"minorCiv" is the player-object for the minor you want to edit the influence of.

Detecting when war is declared and who declared it is much trickier. You may be able to use:
Code:
Events.WarStateChanged(TeamID team1, TeamID team2, bool war)
However, it is an "event" not a "GameEvent" so I am skeptical that it will work. I've not used it myself so investigation will be required to verify how it works.
 
TPangolin:
Machiavelli has a good start, but there is a GameEvents.PlayerDoTurn that could be used to handle the whole operation. You can start by checking the player, then checking by unit. Starting with GetPlot() (and checkin it has a luxury resource) then you could apply a promotion (with the 25% defense). Finally adding the happiness by counting the number of instances of the promotion. [Actually you would start by removing all instances of said promotion.]
Here I'll provide some scratchy code:

Spoiler :
function UnitLuxuryBonus(playerID)
if(Players[playerID]:GetCivilizationType() ~= GameInfoTypes.CIVILIZATION_MYNAME) then
return;
end

local player = Player[playerID];

for unit in player:Units() do
-- optional if you want only a unique unit
-- if unit:GetUnitType() == GameInfoTypes["UNIT_UNIQUE_UNIT_TYPE"] then

local plot = unit:GetPlot();
local resource = plot:GetResourceType(); -- or GetNonObsoleteResurceType() but I'm not wholly sure of the difference
if resource == GameInfoTypes.INSERT_RESOURCE_HERE or
ect.
unit:SetHasPromotion(GameInfoTypes["PROMOTION_PLACEHOLDER"], true);
end
end

local counter;
for unit in player:Units() do
if unit:IsHasPromotion(GameInfoTypes["PROMOTION_PLACEHOLDER"]) then
counter++;
unit:SetHasPromotion(GameInfoTypes["PROMOTION_PLACEHOLDER"], false);
end
end

-- NOW I am not sure how to add happiness. There is a SetHappines() and a lot of Gets() but I'm not sure that that is what you want here. BUT this might work.
local happiness = player:GetHappiness()+counter;
player:SetHappiness(happiness);

end
GameEvents.PlayerDoTurn.Add(UnitLuxuryBonus);


Sargon the second part of your question is included in this code, but I am not sure how to check worked tiles.
tl;dr: plot:GetResourceType();

~Jordangander
 
However, it is an "event" not a "GameEvent" so I am skeptical that it will work. I've not used it myself so investigation will be required to verify how it works.

It appears to work to a certain extent -- I know JFD has had a couple of civilizations that used the event (such as Lincoln), and I've been working on a civ that uses it as well. On the other hand, I'm still not sure I fully understand its operation, as it appears to fire twice, with each team in each slot -- for example, if I declare war on Civilization X, the event seems to fire once with me in team one and Civ X in team two, and then fire again with Civ X in team two and me in team one.

One option would be to look at the Scotland civ done by the More Civilizations team or JFD's Belgium civ -- they both have Lua code that fires when war is declared against you.
 
On the other hand, I'm still not sure I fully understand its operation, as it appears to fire twice, with each team in each slot -- for example, if I declare war on Civilization X, the event seems to fire once with me in team one and Civ X in team two, and then fire again with Civ X in team two and me in team one.

The DLL supports unilateral wars, ie A can declare war on B without B needing to declare war on A. However, the "declare war" code does not support this, so you get two declarations of war, A declares war on B which immediately causes B to retaliate by declaring war on A
 
Hey everyone, I have a couple of requests, one fairly simple I think, and one probably not so simple.

Firstly, I would like to give a certain civ (say, CIV_XXX) a 25% boost to Great Engineer spawn rates, as though it were a trait bonus, which would be permanent. I've looked in the trait tables, building tables, and policy tables, and as far as I can see the Engineer gets the least love, because there is no % increase only for them. I'd think it'd be fairly simple, but then I barely know Lua at all. I can read it fine, so even a little push in the right direction would be greatly appreciated.

Second, and I don't know how easy/possible this is, I would like a civ (say, CIV_YYY) to have a trait where his units have a combat bonus against civs over which he is culturally influential or dominant, with a higher bonus for dominant (say, 20%/40%). This one seems like somewhat of a doosy,so any help you can give would be VERY greatly appreciated.

These are some of the very last things I need to complete my mod civs, so I would be forever indebted to anyone who can help.
 
Luei333, as you've seen only Great Scientists can be boosted via traits. There is a way to boost Great Engineers via policies however. Give a policy +25% all great people and -25% Merchants, Scientists, Writers, Artists, Musicians. You end up with a policy that nets +25% Great Engineers. I've used this myself so I am confident it will work.

As for your second thing, that will likely require a DLL mod as there isn't a way to give a unit a boost against a specific player (only barbarians).
 
Oh yeah, I noticed that literally everyone else had a boost in the policies, that makes a whole lot of sense. Thank you!

And thanks for letting me know the scope of the latter one. At least I already have a backup ability.
 
Hi all

I'd just like to repeat an unanswered request that I made on the Lua thread. The code will be used for the Orcs & Goblins race from the Warhammer Fantasy tabletop game.

I'm looking to change the way that a civ generates happiness and unhappiness in the following ways:

- Generate one (or perhaps more) unhappiness per turn for every turn in which the player is NOT at war with at least one other civ. Would be good if this could kick in after a certain number of turns, which I could adjust or which could scale to map size/game speed, just so the early game isn't punished.

- Generate one (or perhaps more) happiness for every kill, to last a certain number of turns (again, I'd like to be able to adjust or scale the number of turns each happiness generated per kill lasts).

Overall intention is obviously to create a civ that needs to be constantly fighting wars in order to stay happy/growing. Unhappiness from annexation still happens so they can't steamroll everyone, and if they wind up being too OP I can reduce the number of turns each happiness per kill lasts. Should be fun, and I think the code ought to be pretty simple (?).

The above is all I'm desperate for, but I'd also like to experiment with eliminating happiness from luxuries and I can't see if this is possible in XML alone, so if you could include some code that I could comment in/out to let me tinker with that, that'd be brilliant (but not essential).

Obviously you'd get full credit, I think it'd make a really fun and unique civ, and (if it's an incentive) there are lots of people on Steam asking for an Orc race.

PM me or reply here if you come up with something. Many thanks! :)


- RSJ
 
I'm slightly reworking the unique ability of my Texas civ in the next update. Could someone write some code that grants Texan Siege Units defensive terrain bonuses? (IE, removing the NO_DEFENSIVE_BONUS promotion accordingly.)

Or would there be a non-lua way to do this without, like, adding a bunch of unnecessary UUs?
 
Top Bottom