Can construct building if you have a resource without consuming it

Ulixes

Prince
Joined
May 2, 2010
Messages
312
Hi guys, I hope this is the right place.

I play (and love) civ since many years and the discovery of the modding community has been one of the most interesting things in the videogame world in years

In the last months I begun to learn how to do a mod and I'm currently creating a huge ovehaul. I'm good with xml/sql and I used and manipulated (within the boundaries of my limited knowledge) all the lua codes I found useful.

Sadly I'm not able to write a lua code from the scratch and I don't have the time to learn a such complicated language.
There is a feature (similar to civ4 corporations) that I really wish to see but that can't be done in xml/sql or with the lua codes I found out there.

I thought about a very nice feature useful by itself or working in conjuction with the amazing Envoy's Corporations mod.

I know we all have limited time and I usually always try to do things by myself but this time, I really can't.

I hope some of the very good modders on this site find this idea interesting as I do and wants to help me.

So, that's my request:

1) a lua code that allow the construction of a building only if you have at least one of "x" resources (doesn't matters if you've imported it from another civ or if you have it near one of your cities), without consuming those resources.

2) a lua code that grants a bonus yield for having a specific resource

For example:

"Weavers Market" can be built only if you have at least one of these reources: Silk, Cotton, Sheeps, Dyes, Furs
None of these resources get consumed, and you can, for example, buy silk from another civ in order to build this building

In Addition: you get a bonus of, for example, gold if you have more of one of the requested resources:
only silk: 1 gold
silk and cotton: 2 gold
silk, cotton, Sheeps: 3 gold
all 5 resources: 5 gold

As I said, I really hope someone of you find this idea interesting enough to spend his time to realize it.

P.S.: :) I promise to put among the great people who succeed, seriously, I will.
 
1) a lua code that allow the construction of a building only if you have at least one of "x" resources (doesn't matters if you've imported it from another civ or if you have it near one of your cities), without consuming those resources.
Only strategic resources come in quantities, so your "weaver's market" example wouldn't require anything special. You can use the Building_LocalResourceOrs to cover the prereqs and Building_ResourceYieldChanges to provide the yield changes. If you have something that would consume an iron to build, you can have it grant an iron. See the recycling center providing aluminum for an example of how to have a building provide strategic resources.

If you just want to test if a player has the resource without caring about locality than you can use a "CanBuild" check. This approach will require a bit of simple lua.

As for providing a benefit that changes based on the resources a player has access to, that shouldn't be too hard. You can hook into PlayerDoTurn and test to see if the player has the building. If so, look at what resources they have and provide the gold/culture/etc.
 
But desn't "Building_LocalResourceOrs" refer to resources within city radius ?
I meant that the building require the civilization has the resource, even if imported from another civ.

About the "simple" lua code, I envy you, but I'm not currently able to follow your precius advices.

I learned in a very empirical way.
I was just smart enough to do little and very simple modifications to some lua code as "resource on improvement" by redox or delete some line to make a lua code made for a single civilization avalaible for all (and I'm not sure I succeed entirely, I have still to test it on an entire game).

So, sadly, I have no idea what are you talking about.
I understand if you or others have no time or willing to do this.
But given my ignorance, and lack of time, I'm forced to ask if someone is interested in doing it
 
By the way, I really appreciate your work on uploading modders resources on steam, it's really helpful for who lacks lua skills.
 
You are correct that using the XML tables will only work for resources within the city's limits.

The untested code below will only allow players to build the Weaver's market if they have Silk or Cotton. The second argument to GetNumResourceAvailable is includeImport which presumably means if it is true than players who have traded for cotten will be considered to "have" cotton.

This code assumes you've defined the weaver's market building elsewhere.
Code:
function WeaverMarketTest(playerID, buildingType)
  local player = Players[playerID];

  -- Only care if we are looking at a weaver market (section 1)
  if(buildingType ~= GameInfoTypes["BUILDING_WEAVER_MARKET"]) then
    return true;
  end

  -- Only let the player build it if they have Silk or Cotton (section 2)
  if(player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_SILK"], true) > 0 or player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_COTTON"], true) > 0) then
    return true;
  end

  -- Player can't build the weaver market
  return false;
end
GameEvents.PlayerCanConstruct.Add(WeaverMarketTest);

PlayerCanConstruct allows you to put restrictions on when any building can be built. If any PlayerCanConstruct check returns false the player won't be able to build the building. If every check returns true than the player will be able to build the building.

Section 1 ensures that you are only putting a restriction on Weaver market and not impacting any other building.

Section 2 ensures that only players who have certain resources will be able to build the Weaver market.
--------------------------------
The above is very similar to the question you asked on the Steam comment. Your question was:

How do I make a building (Stupa) that can only be built in a city following a specific religion (Buddism)?

This (untested) code assumes you've defined the Stupa building elsewhere.
Code:
function StupaTest(playerID, cityID, buildingType)
  local player = Players[playerID];
  local city = player:GetCityByID(cityID);

  -- Only care if we are looking at a stupa
  if(buildingType ~= GameInfoTypes["BUILDING_STUPA"]) then
    return true;
  end

  -- Only let the player build it if the city is majority buddhism
  if(city:GetReligiousMajority() == GameInfoTypes["RELIGION_BUDDHISM"]) then
    return true;
  end

  -- Player can't build the stupa
  return false;
end
GameEvents.CityCanConstruct.Add(StupaTest);
 
Sadly, the 2 buildings can be constructed without resources the first, without religion the second.

Here's what I did:
Created the buildings in sql (worked)

Spoiler :
INSERT INTO Buildings (Type, BuildingClass, PrereqTech, EnhancedYieldTech, TechEnhancedTourism, PrereqPolicy, PolicyBranchType, Cost, FaithCost, GoldMaintenance, SpecialistType, SpecialistCount, Description, Civilopedia, Strategy, Help, ArtDefineTag, IconAtlas, PortraitIndex, NeverCapture, ConquestProb, HurryCostModifier, UnlockedByBelief, MinAreaSize)
SELECT 'BUILDING_WEAVER_MARKET', 'BUILDINGCLASS_WEAVER_MARKET', NULL, NULL, 0, NULL, NULL, 100, 0, 0, NULL, 0, 'TXT_KEY_BUILDING_WEAVER_MARKET', 'TXT_KEY_BUILDING_WEAVER_MARKET_PEDIA', 'TXT_KEY_BUILDING_WEAVER_MARKET_STRATEGY', 'TXT_KEY_BUILDING_WEAVER_MARKET_HELP', NULL, 'MY_ICON_ATLAS', 20, 1, 0, 25, 0, -1 UNION ALL
SELECT 'BUILDING_STUPA', 'BUILDINGCLASS_STUPA', NULL, NULL, 0, NULL, NULL, 100, 0, 0, NULL, 0, 'TXT_KEY_BUILDING_STUPA', 'TXT_KEY_BUILDING_STUPA_PEDIA', 'TXT_KEY_BUILDING_STUPA_STRATEGY', 'TXT_KEY_BUILDING_STUPA_HELP', NULL, 'MY_ICON_ATLAS', 20, 1, 0, 25, 0, -1 ;


I copied what you wrote in two separate lua files
Put the lua files in modinfo with md5 code as usual
set import="0" for both
create InGameUIAddin for both

This is what the lua log says:

Runtime Error: C:\Users\Windows 7\Desktop\Documents\My Games\Sid Meier's Civilization 5\MODS\Angel of History (v 1)\LUA/BuildingsPrereqReligion.lua:4: Not a valid instance. Either the instance is NULL or you used '.' instead of ':'.

Runtime Error: C:\Users\Windows 7\Desktop\Documents\My Games\Sid Meier's Civilization 5\MODS\Angel of History (v 1)\LUA/BuildingsPrereqGlobalRes.lua:11: Not a valid instance. Either the instance is NULL or you used '.' instead of ':'.

Did I do something wrong? or there is something wrong in the code?
as always thank you in advance
 
BuildingsPrereqReligion.lua line 4: local city = player.GetCityByID(cityID);

BuildingsPrereqGlobalRes.lua line 11: if(player.GetNumResourceAvailable(GameInfoTypes["RESOURCE_SILK"], true) or player.GetNumResourceAvailable(GameInfoTypes["RESOURCE_COTTON"], true)) then
 
Change the player.<stuff> to player:<stuff>. And change city.<stuff> to city:<stuff>. I've edited the code in my last post.
 
The Stupa worked! tested with two different religions, can be built only with buddhism! Great!

The other one doesn't.
no runtime error in lua log, simply, the building can be constructed without the resources

Any clue?

By the way, I like the way you explain things.
 
Try changing:
Code:
  if(player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_SILK"], true) or player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_COTTON"], true)) then
    return true;
  end
To:
Code:
  if(player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_SILK"], true) [COLOR="Red"]> 0[/COLOR] or player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_COTTON"], true) [COLOR="Red"]> 0[/COLOR]) then
    return true;
  end
If that doesn't work it could be that GetNumResourceAvailable doesn't work for luxury resources (I haven't used it myself). It would be easy to verify. Start up a game with firetuner running and try:
Code:
Players[0]:GetNumResourceAvailable(GameInfoTypes["RESOURCE_GEMS"], true)

(Where gems should be whatever luxury resource is next to your capital). See if it changes before and after you hook up the resource. If it doesn't work for luxuries see if it works for horses.
 
... it could be that GetNumResourceAvailable doesn't work for luxury resources ...

It does work for luxuries (I use it in my "UI - Summary Luxuries" mod)

Edit: and you do need the "> 0" part in the if condition, as, unlike C++, the value 0 is true in Lua (there are only two "false" values in Lua - false and nil)
 
IT WORKS!! :worship:
The "> 0" worked, thank you!

Now, if you are not yet tired of this thread, how about the last part: the bonus for every different resource collected (see first post)? any clue? too hard?

By the way, is it complicated to link this lua to a sql/xml table?
 
To implement:
you get a bonus of, for example, gold if you have more of one of the requested resources:
only silk: 1 gold
silk and cotton: 2 gold
silk, cotton, Sheeps: 3 gold
all 5 resources: 5 gold
There are a couple of different ways you could do it. The following (untested) implements +1 gold if Silk or Cotton, +2 if both.

Code:
function WeaverMarketBonus(playerID)
  local player = Players[playerID];
  local numWeaverMarkets = 0;
  local goldBonus = 0;

  -- Count how many Weaver Markets the player has
  for indexCity in player:Cities() do
    if(indexCity:IsHasBuilding(GameInfoTypes["BUILDING_WEAVER_MARKET"])) then
      numWeaverMarkets = numWeaverMarkets + 1;
    end
  end
  
  -- Calculate the bonus gold to give
  if(numWeaverMarkets > 0) then
    if(player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_SILK"], true) > 0) then
      goldBonus = goldBonus + 1;
    end
    if(player:GetNumResourceAvailable(GameInfoTypes["RESOURCE_COTTON"], true) > 0) then
      goldBonus = goldBonus + 1;
    end

    player:ChangeGold(numWeaverMarkets * goldBonus);
  end
end
GameEvents.PlayerDoTurn.Add(WeaverMarketBonus);
 
YESSSSSSS!!!!!!!! :woohoo::bowdown:

Details (tested with DonQuiche's Ingame Editor):

Built with silk res: +1 gold
added cotton: +1 gold
lost cotton: -1 gold
lost silk: - 1 gold (as never built)

Minor Issue: the additional gold doesn't show up in the top panel or city view,
but I think this would require UI modification like cityview.lua or toppanel.lua and I don't know how hard it is and if it is worth the effort, given the fact that it is only an aestethic issue


Those codes are a step (many steps) towards an improved economic system in Civ5,
just think about the possibilities!

Thank you sir, you are officially my hero, and you are now among the great people (great engineer):hatsoff:

P.S.: You should consider to post those lua codes like you did with the others on steam, I'm sure there are a lot of modders who would find them extremely useful.
 
P.S.2: What about an SQL or XML table creation ? in that case you will deserve a Monument too...
 
The gold won't show up in the per-turn-ui because it isn't being given by "normal" means. It also won't be increased by yield changes (like +25% gold from a market in the city). If you want to get around these limitations you'll need to provide the gold via a noLimit building that provides +1 gold. However, I don't believe it is possible to detect when a player gains or losses a resource (without a DLL mod) so the noLimit building method won't change in the middle of turns if a player connects Silk.

As for SQL or XML, what do you intend for them to do?
 
"CREATE TABLE" or/and "ALTER TABLE" in SQL or XML, a way to insert data without copy/paste the lua code every time (sorry if the terms are not correct).

Looking at your previous works I noticed that you create a table where modders can insert their data (so they don't need to touch the lua code).

I'm happy anyway because I can do what I wanted to do, but surely using sql/xml is more user friendly for everybody (at least, I think).

I don't know if there are any other differences between inserting data in lua or using sql/xml (I usually prefer SQL over xml) and if there are not any major differences, I don't think it is essential.

However, as I said, I was thinking you could consider turning this code in another modder's resource as you did for others lua codes, (so I thought about the "CREATE TABLE" thing), but it is up to you.

I'm really satisfied anyway and I hope you will continue to give us pearls like this, or the others you made, in the future. Modders like you, Whoward, FramedArchitect, Gedemon and others bring the game to an entire other level.

By the way, do you know if someone has made a lua code for making a building require forest or jungle in city radius ? It seems a very ordinary idea, I was wandering if someone already did it.
 
Important Question

Sorry I forgot to ask a very important thing!

I tried to replace gold with food, culture, science, didn't worked. Do I have to use different words or a totally different code is needed to add those yield ?
 
Back
Top Bottom