C++/Lua Request Thread

Although the Barbarians were at first uncooperative, by doing your proposed method it was confirmed that: yes, the code does indeed work. Thanks mate!
 
How do I use this function:

OpenRangedAttackModifier()

the wiki doesn't help in the slightest on what it even does; I'm looking for ways to dynamically increase a unit's ranged attack
 
How do I use this function:

OpenRangedAttackModifier()

the wiki doesn't help in the slightest on what it even does; I'm looking for ways to dynamically increase a unit's ranged attack

It's a read-only to get the unit's modifier for "Open" Terrain Ranged Attacks.

There does not appear to be any direct way to alter a unit's Ranged Attack Strength via lua. It looks like the only options to do so are promotions that add a % change to the unit's ranged attack combat strength. The problem is you cannot add multiple copies of the same promotion to the same unit, so you'd have to make multiple promotions in the increments you are after, and add the correct one and eliminate any of the others.

So you'd have to set up a series of Promotions in XML, something like this:
Promotion Effect
PROMOTION_RANGED_05 + 5 % Ranged Attack
PROMOTION_RANGED_10 + 10 % Ranged Attack
PROMOTION_RANGED_15 + 15 % Ranged Attack
PROMOTION_RANGED_20 + 20 % Ranged Attack
And then give the apporiate one as needed to Ranged Units, and remove any of the others.
 
So, I'm trying to get this statement to work:

pUnit:SetHasPromotion(GameInfoTypes["PPROMOTION_MENTAL_RANGEDBOOST_LEVEl"..iSlot],true)

but it doesn't seem to be working, can I not use brackets for this?
 
So, I'm trying to get this statement to work:

pUnit:SetHasPromotion(GameInfoTypes["PPROMOTION_MENTAL_RANGEDBOOST_LEVEl"..iSlot],true)

but it doesn't seem to be working, can I not use brackets for this?

when you do
Code:
print("PPROMOTION_MENTAL_RANGEDBOOST_LEVEl"..iSlot)
does this print out the valid name of a promotion <Type> from table <UnitPromotions> ?

If the answer is no, then this is your problem. You are getting either "nil" or "-1" as the result of
Code:
GameInfoTypes["PPROMOTION_MENTAL_RANGEDBOOST_LEVEl"..iSlot]
Capitalization will matter, as well as whether or not the promotion as defined in the XML starts with "PP" instead of just "P".
 
Hello! I have a quick question:

How do I add a City State to the list of selectable City States with LUA? I'd like to make a specific City State mutually exclusive with a specific major civ, so that if someone is playing as that civ, the CS won't be selected.
 
So my problem from last time is not quite solved, but I have much more information on it now. In general terms, I want a unit to have a custom mission that steals a great work of art or artifact from another Civ (when close to one of that civ's cities). I have everything in and working fine up to the actual "stealing" of the great work.

My problem lies in the commands to move Great Works and their seeming inability to do this exact thing. As far as I'm aware, there are only 2 functions that deal with moving great works: Network.SendSwapGreatWorks and Network.SendMoveGreatWorks, but there are fatal problems with both.

For Network.SendSwapGreatWorks, you have to preface it with Network.SendSetSwappableGreatWork calls for both players, and you have to specify 2 actual, existing works to swap or nothing will happen in the function (though it doesn't throw any errors). For my function, I don't want the player to send anything to the opponent, just get their work for free. Maybe if I could spontaneously create a work to trade and destroy it immediately afterwards, but then I'd have to find a way to kill the great work popup before or immediately after it appeared, or I if I could destroy the GW I want to steal and recreate it for the player, though both of those options require the deletion of a GW, which I'm not sure is even possible.

For Network.SendMoveGreatWorks, it can run fine, seemingly, but fail to move a great work without sending out any kind of error as well. I've implemented this, and tried every configuration of inputs to the function that I could think of, with no result (I'll attach my mod). If there's something wrong with my code that would make it break, it would be great to fix it easily. Otherwise, I guess the send function can't do what I need it to. Is there, by chance, a way to delete a great work? Maybe deleting the building it's placed in, or would that just move it to an open slot? What if there weren't open slots? Any relevant threads or links floating around out there?

Looking at my code, the relevant code is in CAT_Lua.lua, and is the last function, below the long line of dashes. It uses the custom UnitPanel.lua for custom missions. The 'Action' section, the largest by far at the bottom, has the Network function. (ignore the commented section below it)
 

Attachments

  • Super Civs - Catwoman (v 1).7z
    1.2 MB · Views: 74
Is there, by chance, a way to delete a great work?
Not directly. In fact, there is no direct Lua API for any type of management of great works (create, delete, remove, add, etc) - why would modders possibly want to do anything over and above what Firaxis needed for the base game :mad:
 
Not directly. In fact, there is no direct Lua API for any type of management of great works (create, delete, remove, add, etc) - why would modders possibly want to do anything over and above what Firaxis needed for the base game :mad:

WOW that was fast. But what you're saying is that there is a way to delete a GW? Is it something feasible to do in a small bit of Lua, like just getting rid of the building with the GW in the city? I think, for example, it's possible to lose GWs in the conquest of a City, when its building happens to be destroyed by the occupation, but that might require such specific circumstances that it's basically impossible to do in Lua. And yeah I can certainly relate with the lack of support.
 
The only way to delete a great work is to delete the building it's in - via SetNumRealBuildings() or whatever the method is called.

But that's only a small part of the problem. As you've discovered, you can only move GWs between the same player's cities/buildings, and you can only swap GWs on a one-for-one basis. So, to steal a GW you're going to have to create a fake GW (via a hidden building) for the player doing the stealing and then swap with the GW of the player you're stealing from. So far, so good. You now need to find the fake GW and delete it - but to do this you have to delete the building it's in, so you'll need another hidden building with a single empty GW slot, give that to the target player's city, swap the GW into it and then delete the building. Still not a major problem. But IIRC once a GW is gone you can't get it back, so for every GW you can steal you'll need both a fake GW and a hidden building to put it in. Assuming the player could steal every possibly GW in the base game, that's a heck of a lot of fake GW and hidden buildings. You could limit the number by saying the ability to steal GWs can only be used X times, but you'll still need X fake GWs and X hidden buildings to put them in and the extra (reusable) building to move them to to effect the delete.
 
The only way to delete a great work is to delete the building it's in - via SetNumRealBuildings() or whatever the method is called.

But that's only a small part of the problem. As you've discovered, you can only move GWs between the same player's cities/buildings, and you can only swap GWs on a one-for-one basis. So, to steal a GW you're going to have to create a fake GW (via a hidden building) for the player doing the stealing and then swap with the GW of the player you're stealing from. So far, so good. You now need to find the fake GW and delete it - but to do this you have to delete the building it's in, so you'll need another hidden building with a single empty GW slot, give that to the target player's city, swap the GW into it and then delete the building. Still not a major problem. But IIRC once a GW is gone you can't get it back, so for every GW you can steal you'll need both a fake GW and a hidden building to put it in. Assuming the player could steal every possibly GW in the base game, that's a heck of a lot of fake GW and hidden buildings. You could limit the number by saying the ability to steal GWs can only be used X times, but you'll still need X fake GWs and X hidden buildings to put them in and the extra (reusable) building to move them to to effect the delete.

Yeah, that's pretty much exactly what I was thinking and hoping. As far as the limitations you describe, could you not just use the same building to remove works over and over again, or does the work stay in the building it was created in, and re-enter the game when you give the city the building again? Furthermore, assuming that the answer to that question is that it goes away, even when you give the building back, could you not re-grant the same GW over and over after destroying it? I wouldn't be at all surprised if that's not the case for any number of reasons. Also, I wouldn't be surprised if you didn't know the answer to those questions.

Even if neither of those are possible, though, it wouldn't be impossible to implement, just time consuming. I feel like there's a way to use SQL to take the table of Great Works (or just art and artifacts) and make as many buildings. But in writing that sentence, I realize that artifacts are gonna be a pain, as I believe they aren't indexed in the database. SO. Probably just an arbitrary number (15-20 or so? It's a Great Merchant replacer, it's hard to get that many) of corresponding buildings, dummy GWs, and a way to track that information throughout saving and loading. Probably either the save utilities or another set of dummy buildings.

But, even worst case, that's not an insurmountable task to code that. Hell, I had to copy and replace every unit in the game for Deathstroke, and Deadpool's lua was a mess. I'll see to making this beast over the next few days. I'm kind of surprised no one has taken the time to make it yet, though.
 
The building (type) to delete a GW can be reused, but IIRC you can't re-acquire deleted GWs (this is because deleting the building leaves the GW in limbo - created and held by the Game object but not allocated to any Player object) - so attempting to recreate it will lead to all kinds of issues internally in the C++ code.
 
With my planned final civs well under way, I've realised that I can, and want to, finish one more before Civ 6 sweeps me off my feet. As such, I have one last batch of lua requests because I have somehow managed to stay incompetent for the whole course of the game ;):

  • When a mine is constructed in the territory of CIVILIZATION_SENSHI_CORNWALL, it has a 10% chance of spawning 2 of the Strategic Resource RESOURCE_SENSHI_TIN if Cornwall hasn't discovered Metallurgy, and a copy of the Luxury Resource RESOURCE_SENSHI_TIN_LUX if they have on the tile.
  • After a civilization discovers Metallurgy, sweep each of its cities for copies of RESOURCE_SENSHI_TIN and replace them with RESOURCE_SENSHI_TIN_LUX. Repeat this procedure whenever a civilization captures or founds a city (if it has discovered Metallurgy)
  • When UNIT_SENSHI_DROLL begins a turn within one tile of a city, its owner is provided with +1 Gold and +1 Faith.
  • When UNIT_SENSHI_DROLL begins a turn within one tile of a city without the building BUILDING_SENSHI_VISITED, its owner is provided with +25 Gold and +25 Faith, and BUILDING_SENSHI_VISITED is added to the city.
  • When BUILDING_SENSHI_STANNARY is constructed in a city, check if it's a coastal city. If so, BUILDING_SENSHI_SEA_GOLD is added to the city. Otherwise, BUILDING_SENSHI_LAND_GOLD is added.

Hopefully this is all alright ;)
 
  1. Can any civilization besides CIVILIZATION_SENSHI_CORNWALL get copies of RESOURCE_SENSHI_TIN via this sort of mechanic:
    • When a mine is constructed in the territory of CIVILIZATION_SENSHI_CORNWALL, it has a 10% chance of spawning 2 of the Strategic Resource RESOURCE_SENSHI_TIN if Cornwall hasn't discovered Metallurgy, and a copy of the Luxury Resource RESOURCE_SENSHI_TIN_LUX if they have on the tile.
    This ties into the bullet item about "After a Civilization discovers Metallurgy..."
  2. Who do you mean when you say "its":
    • When UNIT_SENSHI_DROLL begins a turn within one tile of a city, its owner is provided with +1 Gold and +1 Faith.
    • When UNIT_SENSHI_DROLL begins a turn within one tile of a city without the building BUILDING_SENSHI_VISITED, its owner is provided with +25 Gold and +25 Faith, and BUILDING_SENSHI_VISITED is added to the city.
    I also assume you mean "next to" when you say "within one tile of"
  3. How are these two buildings defined in the xml/sql?
    Code:
    BUILDING_SENSHI_SEA_GOLD
    BUILDING_SENSHI_LAND_GOLD
  4. I assume BNW only (yes/no)
 
Last edited:
  1. Can any civilization besides CIVILIZATION_SENSHI_CORNWALL get copies of RESOURCE_SENSHI_TIN via this sort of mechanic: This ties into the bullet item about "After a Civilization discovers Metallurgy..."
They shouldn't be able to normally, but if they capture or otherwise come into possession of a city where Tin has already been spawned, then they would.
[*]Who do you mean when you say "its":
by "its owner" I meant the owner of the Droll Teller, not the City. Sorry, that was a big error on my part.
I also assume you mean "next to" when you say "within one tile of"
Next to or within a city, preferably, but next to is fine.
[*]How are these two buildings defined in the xml/sql?
Code:
BUILDING_SENSHI_SEA_GOLD
BUILDING_SENSHI_LAND_GOLD
They're both generic dummy buildings, with SEA_GOLD having a TradeRouteSeaGoldBonus value of 100 (a la the Harbour), and LAND_GOLD having a TradeRouteLandGoldBonus value of 200 (a la the Caravansary)
[*]I assume BNW only (yes/no)
Yes indeed ;)
 
They shouldn't be able to normally, but if they capture or otherwise come into possession of a city where Tin has already been spawned, then they would. by "its owner" I meant the owner of the Droll Teller, not the City. Sorry, that was a big error on my part. Next to or within a city, preferably, but next to is fine. They're both generic dummy buildings, with SEA_GOLD having a TradeRouteSeaGoldBonus value of 100 (a la the Harbour), and LAND_GOLD having a TradeRouteLandGoldBonus value of 200 (a la the Caravansary)

Yes indeed ;)
I may be able to have time to look at it tomorrow.

For the building then why cannot the same building merely have both commands (land and sea) ?
 
For the building then why cannot the same building merely have both commands (land and sea) ?

The building would then operate as intended in landlocked cities, but provide the additional gold to both land and sea routes in coastal cities.
 
@senshidenshi

Try the attached file (assuming I get it attached correctly)

You have some options for controlling how the code works.
  1. Here you can alter data amounts:
    Code:
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    --  DATA VARIABLES
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    
    local iCornwallCiv = GameInfoTypes.CIVILIZATION_SENSHI_CORNWALL
    local iMetallugyTech = GameInfoTypes.TECH_METALLURGY
    local iMineImprovement = GameInfoTypes.IMPROVEMENT_MINE
    local iResourcePlacementChancePercentage = 10  -- (10 = 10% chance)
    local iResourceStrategicAmountToGive = 2
    local iTinStrategic, iTinLuxury = GameInfoTypes.RESOURCE_SENSHI_TIN, GameInfoTypes.RESOURCE_SENSHI_TIN_LUX
    local iUnitCornwallDroll, iBuildingDrollHasVisitedCity = GameInfoTypes.UNIT_SENSHI_DROLL, GameInfoTypes.BUILDING_SENSHI_VISITED
    local iBuildingCornwallStannary = GameInfoTypes.BUILDING_SENSHI_STANNARY
    local iBuildingCornwallSeaGold, iBuildingCornwallLandGold = GameInfoTypes.BUILDING_SENSHI_SEA_GOLD, GameInfoTypes.BUILDING_SENSHI_LAND_GOLD
    local iDrollFirstVisitGold, iDrollFirstVisitFaith = 25, 25
    local iDrollLaterVisitGold, iDrollLaterVisitFaith = 1, 1
  2. Here you can set 'control conditions' for how the code should work:
    Code:
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    --  BEHAVIOR CONTROL VARIABLES
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    --xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    
    local bDrollEffectOnlyFromForiegnCities = true
     -- should the Droll Teller effect be given only from visiting foriegn cities
    
    local bDrollEffectFromEnemyCities = false
     -- should the Droll Teller effect be given from visiting cities the Cornwall player is at war with
    
    local bDrollEffectFromCityStateCities = true
     -- should the Droll Teller effect be given from visiting city-states
    
    local bTinCannotReplaceOtherResources = true
     -- should 'tin' replace an existing resource
    
    local bMineMustBeInPlayerTerritory = true
     -- does a mine need to be in the territory of a Cornwall player
    
    local bDoDrollEffectFromPassingByCity = false
     --this will turn on a UnitSetXY event for the Droll Teller 'passing by' a city
     --if you turn this on there will be perceptible processing lag when moving a Droll Teller
     --if you turn this on there is a possibility the same Droll Teller will give '1' gold and faith from the same city twice on the same turn
  3. I would have lighlighted the appropriate portions of the code but the new forum software currently just ignores color formatting within code blocks.
[ edit ] I updated the attachment to use a better command in one place.
 

Attachments

  • SenshiCornwall.zip
    3.7 KB · Views: 56
Last edited:
So I'm back, problem not solved at all. In fact, some of the stuff WHoward said was wrong, as I've learned from testing it directly. First, putting a GW in a building then setting the number of that building in the city to 0 does not, in fact, get rid of the GW. The building and GW disappear from the tourism screen and everything, you can't swap the GW around, etc, but it still adds to your culture and tourism. AND, when you re-add the building to the city, it will still be holding the GW! So, short of creating a dummy city and deleting it with the GW in a slot in it (which might not even work), I can't think of a way to get rid of a GW.

Second, any time you add a building that gives a free GW to a city, it will give a GW, even if it already gave a GW!! If you add and remove a building over and over, transferring the GW out to another slot each time, you will get a new instance of a GW every single time. Furthermore, I tried removing and re-adding that building with another (artist-created) GW already in its slot, and its own free GW overwrote the GW it had when it was re-added, essentially getting rid of that GW (but adding another one in the process, so it's not an effective way to delete a GW). This means that you can create any number of free GWs with only a single extra building and GW.

So, I've essentially hit a wall with the ability I want to make (stealing a GW), since if I create a dummy GW to trade with another player, then it can't be deleted from their cities, AFAIK. I really hope someone here can offer another solution/workaround, this is literally the LAST thing I have to finish before I release 8 more civs.
 
Top Bottom