UU replacing prophets

Homusubi

Lafcadio Hearn Wannabe
Joined
Dec 21, 2012
Messages
1,035
I'm making yet another civ and want to replace the Great Prophet with a different unit. So far, the unit replaces the prophet with LToP and the Liberty finisher, but not when acquiring through faith. How do I make a real prophet replacer?
 
ITS HARDCODED. WHAT THE HELL FIRAXIS.

Code:
/// Time to spawn a Great Prophet?
bool CvGameReligions::CheckSpawnGreatProphet(CvPlayer& kPlayer)
{
	UnitTypes eUnit = (UnitTypes)GC.getInfoTypeForString("UNIT_PROPHET", true);
	if (eUnit == NO_UNIT)
	{
		return false;
	}

...could an XML tag not have been applied here?

Might I also recommend an LUA script to replace the prophet with the correct unit when it's spawned, if that unit belongs to the correct civilization?
 
ITS HARDCODED. WHAT THE HELL FIRAXIS.

Code:
/// Time to spawn a Great Prophet?
bool CvGameReligions::CheckSpawnGreatProphet(CvPlayer& kPlayer)
{
	UnitTypes eUnit = (UnitTypes)GC.getInfoTypeForString("UNIT_PROPHET", true);
	if (eUnit == NO_UNIT)
	{
		return false;
	}

...could an XML tag not have been applied here?

Might I also recommend an LUA script to replace the prophet with the correct unit when it's spawned, if that unit belongs to the correct civilization?

Wow, that's as annoying as whatever finisher it is that grants a free aqueduct in your first 4 cities will always grant the aqueduct and not a UB aqueduct (hardcoded with type not class in DLL). Sadly, in that case, there's no lua function to add/remove free buildings making it pointless to have a ub aqueduct replacement.
 
Wow, that's as annoying as whatever finisher it is that grants a free aqueduct in your first 4 cities will always grant the aqueduct and not a UB aqueduct (hardcoded with type not class in DLL). Sadly, in that case, there's no lua function to add/remove free buildings making it pointless to have a ub aqueduct replacement.

I've fixed that in my DLL
 
I couldn't do Lua if my life depended on it...

Luckily I believe this wouldn't be a travesty to implement. I'm not the best at game event LUA scripting, but I can do interface..."meh".

side note, is it weird to be better at the DLL modification than LUA?

You're looking for an event that triggers when a unit is created. Then you check to see if the unit is UNIT_PROPHET, in which case you kill it, and spawn a new unit UNIT_CUSTOM_PROPHET or whatever in its place.

You can do it! I would imagine this script wouldn't take more than 15 lines and you'll have to start somewhere! Someone must know the LUA event to handle this. I don't. I don't like LUA events at all.
 
Make a new prophet unitclass, set the old prophet unitclass to default to NO_UNIT, and then set your prophet UU to the new unitclass. Make sure the game knows it's a great person for faith buys.

You'll have to make your own little hook into the turn event to figure out whether you want to spawn a prophet or not. Check Project Civ's Sparta for info on how to get a civ's unit for a class. (For instance, the code will return UNIT_CHARIOTARCHER for Greece and UNIT_EGYPTIAN_WARCHARIOT Egypt when given UNITCLASS_CHARIOTARCHER.)
 
Apparently it's hardcoded Irkalla, so that wouldn't work. It says UNIT_PROPHET; if it said UNITCLASS_PROPHET I wouldn't have made the topic.
 
Apparently it's hardcoded Irkalla, so that wouldn't work. It says UNIT_PROPHET; if it said UNITCLASS_PROPHET I wouldn't have made the topic.

Read again. The function returns false if it gets NO_UNIT. The function only works if the unit gotten for the unitclass is UNIT_PROPHET. We set the default for the unitclass to NO_UNIT to disable this hardcoded function, and write our own great prophet spawning function.
 
Let me get this straight. If I fiddle with the unit classes in XML, does it then magically work, or do you still need to use Lua?
 
Let me get this straight. If I fiddle with the unit classes in XML, does it then magically work, or do you still need to use Lua?

What you'd be doing is essentially disabling the function in the C++ Gamerules, and then after that you'd have to write your own Lua function to do the same thing, except correctly this time.
 
Thanks for the help, but I already explained to CivFanatics 142,857 times that I couldn't use Lua if it was essential for my life to continue.
 
Thanks for the help, but I already explained to CivFanatics 142,857 times that I couldn't use Lua if it was essential for my life to continue.

Then learn? It's really not that hard. Get a spoonfeed or something.
 
Don't worry, TBH i'm quite surprised with what I can do with XML. My next civ project for example doesn't require anything out of the ordinary.

If you're wondering what it might be, here's the UA text to help you guess:

+1 Culture from forest and jungle tiles. +2 unique Bears luxury resource in the capital.
 
Although I don't like to Necro old threads or take over other people's threads, I've been trying to do just this (using Putmalk's method.)

This is my first LUA script, so I'm not surprised that although it does load, it doesn't work:

Code:
local sUnitType = "UNIT_PROPHET"
local iProphetID = GameInfoTypes[sUnitType]
local iGodslayer = GameInfo.Units.UNIT_GODSLAYERPRIME.ID
local pPlayer = Players[iPlayer];

print ("Hurrah. Your lousy script actually loaded.")


function ProphetsToGodslayers(iPlayer, iUnitID)
	print ("This script is intended to turn Prophets into other units.")
	print ("Checking to see if the player is Alive...")

	if pPlayer:IsEverAlive() then
		if Players[Game.GetActivePlayer()]:GetCivilizationType() == GameInfo.Civilizations["CIVILIZATION_EVILZANDALARI"].ID then 
			print("This player is Zandalari!")
			print("Let's find out if this unit is a prophet!")
			if iUnitID:GetUnitType() == sUnitType then  
				print("This unit is a prophet. DIE PROPHET DIE")
				local iProphetx = iUnitID:GetX();
				local iProphety = iUnitID:GetY();
				
				iUnitID:Kill(false, -1);
				pPlayer:InitUnit(iGodslayer, iProphetx, iProphety, UNITAI_ATTACK, DirectionTypes.DIRECTION_WEST)
			else print ("This unit is not a prophet, and has been spared the wrath of this script.")
			end
		end
	end
end


GameEvents.SerialEventUnitCreated.Add(ProphetsToGodslayers)

The two things I had to completely guess on were how I determined which unit was being affected, and which variables were passed into ProphetsToGodslayers. I have to admit I didn't have a clue.

Any help would be awesome. I'm trying to learn LUA as fast as I can.
 
local pPlayer = Players[iPlayer];

Where is iPlayer defined?

function ProphetsToGodslayers(iPlayer, iUnitID)

inside the function! But your definition of pPlayer is outside the function, where iPlayer is NOT defined.


if Players[Game.GetActivePlayer()]:GetCivilizationType() == GameInfo.Civilizations["CIVILIZATION_EVILZANDALARI"].ID then

Are you sure you only want this to apply if the (currently active) human is playing CIVILIZATION_EVILZANDALARI? I think you want pPlayer here, not the currently active human.


if iUnitID:GetUnitType() == sUnitType then
etc

iUnitID is a number. You can't call those functions on a number. You have to get the unit object (from the player) and then you can call functions on that.
 
Here's the updated (working, but I think pretty inefficient) version:
Code:
-- ProphetReplacer
-- Author: Neirai the Forgiven
-- DateCreated: 8/24/2013 2:56:18 PM
--------------------------------------------------------------
local sUnitType = "UNIT_PROPHET"
local iProphetID = GameInfo.Units.UNIT_PROPHET.ID
local iGodslayer = GameInfo.Units.UNIT_GODSLAYERPRIME.ID

print ("Hurrah. Your lousy script actually loaded.")


function ProphetsToGodslayers(iPlayer, iUnit)
	print ("This script is intended to turn Prophets into other units.")
	print ("Checking to see if the player is Alive...")
	local pPlayer = Players[iPlayer];
	if (pPlayer:IsEverAlive()) then
		print ("Player is alive, mon")
		print (pPlayer:GetCivilizationType())
		print (GameInfo.Civilizations["CIVILIZATION_EVILZANDALARI"].ID)
		if (pPlayer:GetCivilizationType() == GameInfo.Civilizations["CIVILIZATION_EVILZANDALARI"].ID) then 
			print("This player is Zandalari!")
			print("Let's find out if this unit is a prophet!")
			print(iUnit)
			print(GameInfoTypes["UNIT_PROPHET"])
		--	print(iUnit:GetID())
			for pUnit in pPlayer:Units() do
				print(pUnit:GetUnitType())
				if (pUnit:GetUnitType() == iProphetID) then
				--if (iUnit:GetID() == GameInfoTypes["UNIT_PROPHET"]) then  
					print("This unit is a prophet. DIE PROPHET DIE")
					local iProphetx = pUnit:GetX();
					local iProphety = pUnit:GetY();
					pUnit:Kill(false, -1);
					pPlayer:InitUnit(iGodslayer, iProphetx, iProphety, UNITAI_ATTACK, DirectionTypes.DIRECTION_WEST)
				else print ("This unit is not a prophet, and has been spared the wrath of this script.")
				end
			end
		else print ("This player is scum.")
		end
	end
end


Events.SerialEventUnitCreated.Add(ProphetsToGodslayers)
 
Hmn... Sounds interesting Neirai, but the biggest issue, since you're removing and adding the unit, is that it might not keep its religion...

I've been thinking of an interesting possibility, which is making the Prophet/Missionary, have a fake upgrade unit that can't be achieved. Then use lua to force-upgrade the unit.

The biggest issue would be of course that when the prophet is born it will say "A Great Prophet has been born", but that also happens in your code.
 
Yes, I do still get the Great Prophet warning. I'd probably have to rescript it.

In the case of my mod, the Zandalari trait is about getting a war unit instead of a prophet and never getting a religion at all, so I'm not concerned about loss of religion. But I can see how that could be a problem for other players wanting to use this script. One would have to test to see if the religion jumps between the characters.

Also, thanks for making a bunch of LUA scripts in your mods. They were very helpful in figuring this one out.
 
You don't need to loop through all the players units. You already have the unit ID, iUnit. Just get the unit by using pPlayer:GetUnitByID(iUnit).
 
Top Bottom