How to restrict buildings to AI/human?

arloir

Chieftain
Joined
Apr 4, 2018
Messages
8
Goal: I'd like to duplicate a few wonders where one version is only available to a Human player and the other to the AI players. Why? Well, there are certain wonders I always build first and I'd like to give one AI player the same benefits (without giving up my wonder!)

One fairly easy way to achieve this would be to duplicate the wonders and give them a prereq building that is only available to a single Civ (using either <Building_PrereqBuildingClasses> or <Building_ClassesNeededInCity>), and eliminate the original wonders for that Civ (using <Civilization_BuildingClassOverrides>). But... that would restrict this mod to a single Civ for the "Human".

Any suggestions for how to make this generic? I could see doing the same prereq building trick on a building that has no Flavor - I think that would make the AI ignore it (not sure?)
But then the human would be able to build both versions of the wonder. (Not horrible - the human could choose not to - but not ideal either).

TIA for any suggestions,

arloir
 
Thanks Nutty - I haven't played with the Civ 5 Lua for years, so I was doing a bunch of digging. Am I on the right track with the following:

There's Player:CanConstruct and City:CanConstruct... I believe I'd attach through GameEvents.PlayerCanConstruct.Add() (or City). (My C++ brain keeps thinking of method overrides to still call the default version but change certain answers...)

I can find places where City CanConstruct is called, but not Player. Is there somewhere that describes the relationship between the two?

(I was trying to find the original Modbuddy tutorials.. but the links to 2kgames are no longer valid :( )

cheers,

arloir
 
Code:
function HumanCanBuildWorldWonders(iPlayer, BuildingType)
	if (BuildingType == GameInfoTypes.BUILDING_SOMETHING_OR_OTHER) then
		return (Players[iPlayer]:IsHuman())
	end
	return true
end
GameEvents.PlayerCanConstruct.Add(HumanCanBuildWorldWonders)
  1. limits based on whether the player is human or not and will return boolean true (ie, the player can go ahead and construct the building) for humans
  2. remember that wonders are just buildings
  3. the final "return true" line is needed because the game will check every "BuildingType" registered in the database against your function, and you want all those that are not BUILDING_SOMETHING_OR_OTHER to contunue to be buildable
  4. you cannot override anything in the game database that already disallows the given player from constructing the building, such as a TechPrereq or a Civilization_BuildingClassOverride row. This is also true of the "city" version of the test event.
To make it so that only an AI can construct a wonder (or building) you would simple alter to as
Code:
function AI_CanBuildWorldWonders(iPlayer, BuildingType)
	if (BuildingType == GameInfoTypes.BUILDING_SOMETHING_OR_OTHER) then
		return (Players[iPlayer]:IsHuman() == false)
	end
	return true
end
GameEvents.PlayerCanConstruct.Add(AI_CanBuildWorldWonders)
 
Thanks for the code, LeeS! More detailed than I expected ;)
I'm still not quite sure of the interaction between Player & City can build, but (in spite of that) I have a little mod working.

For those who are curious:
  • Modbuddy + sqlitespy were crucial, of course.
  • I also forgot to follow the instructions here by whoward69 for properly setting up files in the modbuddy project (SQL needs the "OnModActivated -> UpdateDatabase" and the Lua an "InGameUIAddin" entry in the project properties), which gave me some headache.

SQL Code which creates a new column in the BuildingClasses table "AICanBuild", which defaults to 1 (true), then creates dupes of everything with MaxInstanceCount = 1, appending "_DUPE" to the class name and the default building. I then create a temp table for the duplicate building, where I clear the ID and append the _DUPE to their name and class before inserting them into the Buildings table.
Spoiler SQL Code :

Code:
-- 1)
-- add the ability to tag things as AI or not (before we duplicate them)
ALTER TABLE BuildingClasses ADD COLUMN 'AICanBuild' INTEGER DEFAULT 1;      

-- 2)
-- duplicate all the necessary buildings
INSERT INTO BuildingClasses (Type, Description, DefaultBuilding, MaxGlobalInstances, MaxTeamInstances, MaxPlayerInstances, NoLimit, Monument, AICanBuild)
SELECT Type||'_DUPE', Description, DefaultBuilding||'_DUPE', MaxGlobalInstances, MaxTeamInstances, MaxPlayerInstances, NoLimit, Monument, 0
FROM BuildingClasses WHERE MaxGlobalInstances=1 AND AICanBuild=1 AND NOT Type LIKE '%_DUPE';

-- 3)
-- create temp table for duplication?
CREATE TABLE Buildings_DupeTemp    AS
-- select the buildings to dupe
SELECT Buildings.*
FROM Buildings, BuildingClasses
WHERE BuildingClasses.MaxGlobalInstances=1 AND Buildings.Type = BuildingClasses.DefaultBuilding AND NOT Buildings.Type LIKE '%_DUPE';

-- 4)
-- Update those to be "Dupes" AND remove the IDs (which need to be unique)
UPDATE Buildings_DupeTemp
SET Type=Type||'_DUPE', ID=null, BuildingClass=BuildingClass||'_DUPE';

-- 5)
-- move those cleaned up dupes into the buildings
INSERT INTO Buildings
SELECT * FROM Buildings_DupeTemp;

-- 6)
-- Empty that temp table
DELETE FROM Buildings_DupeTemp;


Then the Lua which checks the AICanBuild flag for wonders.
Spoiler Lua Code :
Code:
function AIorHumanPlayerCanBuild(iPlayer, iBuildingID)
    local oBuildingClass = GameInfo.BuildingClasses[GameInfo.Buildings[iBuildingID].BuildingClass];
    if (oBuildingClass.MaxGlobalInstances == 1) then
        if (Players[iPlayer]:IsHuman()) then
            return oBuildingClass.AICanBuild == 0;
        else
            return oBuildingClass.AICanBuild == 1;
        end
    end
    return true;
end

GameEvents.PlayerCanConstruct.Add(AIorHumanPlayerCanBuild);


And Now there are duplicates of all wonders - one version for ALL AI players and another for ALL Human Players. A refinement would be to remove (or even configure) which wonders are duped and which aren't.

The missing bit of functionality is the Triggers required to update those dupes for Wonders created by other mods after this mod is loaded. I've mucked with some CREATE TRIGGER code, but because both BuildingClasses and Buildings need to be updated, there's some challenge to doing things in the right order... and I haven't finished that.
 
Well, played a few more hours with this mod. It works well, but obviously some oddities to be expected...
  • you don't get units granted by a "dupe" wonder (no script written for it...)
  • you can actually end up with two of a wonder (if you capture an AI's wonder...)
  • While the dupes do seem to work for City-State quests... they can also give quests for a wonder you've already built, because someone else has not. (I'm guessing they maybe pick either the original or dupe and give a quest.... but need to confirm)
However, it's been pretty neat to see all the wonders getting built by AI Civs after I've built my version.
 
(facepalm) totally forgot all the Building_ tables that control stuff like free units, etc.

Ok - so, concept tested, functionality needs a bit of work. :mischief:
 
Ok - those problems are fixed by modifying all the Building_ tables. Did that by writing a bit of javascript to iterate through an array of table names and produce the appropriate SQL for each (not quite as ugly as copy/paste... and easier to update).

Will try to post the full code soon if anyone is interested.
 
Back
Top Bottom