[MOD] MagisterModmod

I've noticed similar strangeness with the Mercurian Gate. In a game last night as the Calabim, I began to build MG and it had a 7000 cost. The next turn, I switched production to a unit. One the turn following that, I switched back to building MG and the cost had reduced to 3500. I'm not sure where these numbers come from.

I suppose the cost could be related to the number of people on a team building MG. The Grigori had vassalized to me in the game - maybe they had also started building?
 
The cost of the Mercurian Gate is modified increased by your possession of evil mana types and decreased by being at war with Infernal or Ashen Veil players or players using evil mana types.

Spoiler :
Code:
	def getBuildingCostMod(self, argsList):
		iPlayer, iCityID, iBuilding = argsList
		pPlayer = gc.getPlayer(iPlayer)
		pCity = pPlayer.getCity(iCityID)
		iCostMod = -1 # Any value > 0 will be used
		if iBuilding == gc.getInfoTypeForString('BUILDING_GAMBLING_HOUSE'):
			if pPlayer.isGamblingRing():
				iCostMod = gc.getBuildingInfo(iBuilding).getProductionCost() / 4

		if iBuilding == gc.getInfoTypeForString('BUILDING_MERCURIAN_GATE'):
##			iCostMod = gc.getBuildingInfo(iBuilding).getProductionCost()
			iCostMod = 1000
			iTeam = pPlayer.getTeam()
			eTeam = gc.getTeam(iTeam)
			if eTeam.getAtWarCount(True) > 0:

				iInfernal = gc.getInfoTypeForString('CIVILIZATION_INFERNAL')
				iAV = gc.getInfoTypeForString('RELIGION_THE_ASHEN_VEIL')

				lMana = [	gc.getInfoTypeForString('BONUS_MANA_CHAOS'),
						gc.getInfoTypeForString('BONUS_MANA_DEATH'),
						gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'),
						gc.getInfoTypeForString('BONUS_MANA_ENTROPY'),]

				for iLoopPlayer in range(gc.getMAX_PLAYERS()):
					pLoopPlayer = gc.getPlayer(iLoopPlayer)
					if pLoopPlayer.isAlive():
						iLoopTeam = pLoopPlayer.getTeam()
						if iTeam == iLoopTeam:
							for iMana in lMana:
								if pLoopPlayer.getNumAvailableBonuses(iMana) > 0:
									iCostMod *= 2
							continue
						if eTeam.isVassal(iTeam):
							continue
						if eTeam.isAtWar(iLoopTeam):
							if pLoopPlayer.getCivilizationType() == iInfernal:
								iCostMod /= 6
							elif pLoopPlayer.getStateReligion() == iAV:
								iCostMod /= 3
							for iMana in lMana:
								if pLoopPlayer.getNumAvailableBonuses(iMana) > 0:
									iCostMod /= 2

		return iCostMod
The effect probably is too extreme, so I'll try to dial it back a bit and might even decide to remove the feature.
-----

There is a good chance that I will be releasing another update quite soon, as Platyping went ahead and released another WorldBuilder update that includes some things I really wanted.
 
I guess if I were enough into this game I'd learn to read code.

But I have a question for you Magister.

Round 103. I see a Sheaim city with a Pyre Zombie in it.

According to the Pedia entry:

Pyre Zombies need Necromancy, Death and Fire Mana, and a mage guild. The Sheaim have no death node, and the palace provides chaos, dimensional, and fire mana.

Now you wouldn't know this, but by round 103 these guys had 3 cities. So in 103 rounds they:

1) Popped a sage, or researched Knowledge of the ether
2) Researched agriculture (they had 3 farms. For 3 cities)
3) Researched Necromancy

I believe they start with ancient chants.

So in 103 rounds they research agriculture, Mysticism, maybe Knowledge of the Ether, and Necromancy?

Now I suppose it is possible they got lucky with goody huts, but I never seem to do that, and they seem to do it pretty regularly.

I might add, that Pyre Zombies don't "explode" the way they did in base FFH. In that mod, if you attack a stack with them and kill one the damage affects the attacker and the stack the zombie is in.

Here it affects the attacker's stack.

Build 3 cities, a worker or two and a Pyre Zombie.

What exactly are you driving for in this mod? The Khazad are worse than they are for "cheating," but it is hard to figure out what's going on with them. Apparently they don't need food or something for their cities.

I dunno, getting sick of some of it, and especially Yggdrasil. I've pretty much reached the conclusion that any civ that gets that automatically wins, unless a human player intervenes.
 
Oh yeah, and I'm curious. Can some of these civs research religions without the appropriate techs?

Cause I'm pretty sure the Khazad can get Runes without Mysticism.
 
I guess if I were enough into this game I'd learn to read code.

But I have a question for you Magister.

Round 103. I see a Sheaim city with a Pyre Zombie in it.

According to the Pedia entry:

Pyre Zombies need Necromancy, Death and Fire Mana, and a mage guild. The Sheaim have no death node, and the palace provides chaos, dimensional, and fire mana.

Now you wouldn't know this, but by round 103 these guys had 3 cities. So in 103 rounds they:

1) Popped a sage, or researched Knowledge of the ether
2) Researched agriculture (they had 3 farms. For 3 cities)
3) Researched Necromancy

I believe they start with ancient chants.

So in 103 rounds they research agriculture, Mysticism, maybe Knowledge of the Ether, and Necromancy?

Now I suppose it is possible they got lucky with goody huts, but I never seem to do that, and they seem to do it pretty regularly.

I might add, that Pyre Zombies don't "explode" the way they did in base FFH. In that mod, if you attack a stack with them and kill one the damage affects the attacker and the stack the zombie is in.

Here it affects the attacker's stack.

Build 3 cities, a worker or two and a Pyre Zombie.

What exactly are you driving for in this mod? The Khazad are worse than they are for "cheating," but it is hard to figure out what's going on with them. Apparently they don't need food or something for their cities.

I dunno, getting sick of some of it, and especially Yggdrasil. I've pretty much reached the conclusion that any civ that gets that automatically wins, unless a human player intervenes.

If it is only one Pyre Zombie, then it could have been given to them by a certain random event rather than built the normal way.

If the Sheaim have the holy shrine of the Octopus Overlords, it would provide them with all the Death mana they need.


Are you sure that Pyre Zombie explosions work as you describe?

The only difference in the code is that the explosions in MagisterModmod cannot kill the damaged units but must leave them at least 1% of their health. (Technically there are also the inconsequential difference that I define certain things at the top rather than defining them again every time it loops through a surrounding tile.) It should effect the Pyre Zombie's tile and all adjacent tiles in either case.


The Khazad's Dwarven Vaults have a bigger effect in this modmod, but I don't think there is any reason why they should not need food.


I think I'll shift some of the extra yields from unique features so that they require more advanced techs rather than being granted at the start of the game.

Oh yeah, and I'm curious. Can some of these civs research religions without the appropriate techs?

Cause I'm pretty sure the Khazad can get Runes without Mysticism.

No civ should be able to research a religion-founding technology without knowing its immediate prerequisites.

(It does not matter if they know the prerequisites of the prerequisites. Th Hippus start with Animal Husbandry, so they can research Horseback Riding without needed to research Agriculture first like other civs would have to do.)

Some civilizations do start out with some free research towards specific techs. The Khazad do get free research towards Way of the Earthmother. This should not be enough to give them knowledge of the tech though, or to allow them to begin researching it any further without knowing its prerequisites.

The Ljosalfar get a bigger bonus towards Way of the Forests, but the prerequisites that of tech are a bit more expensive.


The Malakim can found The Empyrean at Way of the Wise, whereas every other civ must wait until Honor. If any civ has The Empyrean as its state religion without knowing Honor yet, then moving a unit onto the tile of the Mirror of Heaven will grant the Honor tech for free and also a free great prophet.

It is possible for any civ to rescue a disciple or pries fro a lair, and use it to spread and thus found its religion without requiring knowledge of the tech that usually founds it.
 
Sunbeam, you should also know that in the MNAI code that Magister's ModMod uses the AI receives significant bonuses to production and economy, even at Noble level (maybe below). If the game is frustrating, you might consider adjusting the values in this mod's CIV4AIHandicap XML file.
 
If it is only one Pyre Zombie, then it could have been given to them by a certain random event rather than built the normal way.

I don't play the Sheaim a lot, so no idea about the event.

If the Sheaim have the holy shrine of the Octopus Overlords, it would provide them with all the Death mana they need.

I was the one who founded the overlords, so I know they didn't have that.


Are you sure that Pyre Zombie explosions work as you describe?

The only difference in the code is that the explosions in MagisterModmod cannot kill the damaged units but must leave them at least 1% of their health. (Technically there are also the inconsequential difference that I define certain things at the top rather than defining them again every time it loops through a surrounding tile.) It should effect the Pyre Zombie's tile and all adjacent tiles in either case.

I'm pretty sure, I'll test it tonight.


The Khazad's Dwarven Vaults have a bigger effect in this modmod, but I don't think there is any reason why they should not need food.

I was being flippant. Sort of. Look I start at Ancient Era. Khazad should start with crafting, and have to research exploration and agriculture, at least agriculture. I'm pretty sure it wasn't huts because the first thing they do is build a warrior, and send one or both fighters to scout close to the city. Then they build a worker (anytime I've fired up worldbuilder on round 2 or so every ai city is building warriors).

Quite often I have gotten huts from around the Khazad in the early game, something impossible with the other civs. They don't seem to build scouts till round 30 or something. Unless they get one from a hut a warrior found maybe.

But I founded Overlords sometime around round 75 or so. Khandros Fir was just a couple rounds behind me on founding Runes.

I say he doesn't need food because how does he research ancient chants, mysticism and mining so quickly? I had Yggdrasil on this one so it was pretty quick for me.

I might add Varn founds the Empyrean before anyone does anything. He usually does it by round 60 if he is in the game. I guess he could research Mysticism, maybe pop a prophet for philosophy, then research Way of the Wise.

But when do they research the techs to make the city grow?

I'm kind of wondering if it is the map I use or something. Maybe I start in Ancient Era, and the AI civs all get agriculture as they would on lower difficulties. I do notice most of them have no idea how to build roads. I've actually traded exploration to ai civs past round 200.

No civ should be able to research a religion-founding technology without knowing its immediate prerequisites.

(It does not matter if they know the prerequisites of the prerequisites. Th Hippus start with Animal Husbandry, so they can research Horseback Riding without needed to research Agriculture first like other civs would have to do.)

Some civilizations do start out with some free research towards specific techs. The Khazad do get free research towards Way of the Earthmother. This should not be enough to give them knowledge of the tech though, or to allow them to begin researching it any further without knowing its prerequisites.

The Ljosalfar get a bigger bonus towards Way of the Forests, but the prerequisites that of tech are a bit more expensive.


The Malakim can found The Empyrean at Way of the Wise, whereas every other civ must wait until Honor. If any civ has The Empyrean as its state religion without knowing Honor yet, then moving a unit onto the tile of the Mirror of Heaven will grant the Honor tech for free and also a free great prophet.

It is possible for any civ to rescue a disciple or pries fro a lair, and use it to spread and thus found its religion without requiring knowledge of the tech that usually founds it.

Now see this gets me. Kandros Fir had two cities, had already founded Runes. Then he switches to God King? That was the message I saw at least. And it wasn't a thane he found in a lair, he had a Priest in Khazad.

I switch to God King and Pacifism as soon as I get Mysticism. When I play the Kuriotates, it usually takes 15 rounds to pop a prophet (I avoid building elder councils or anything to pollute the great person stream). Getting a prophet is the only way I've found to win the race to one of the popular religions.

Strangely though, I can almost always beat Falamar to Overlords, but often not Hannah.

It is harder to beat the Khazad to Runes though. Unless they are in one of their weird spots with no food resources. If they build somewhere away from the mountains where the city grows, it is very hard to beat them.

On the other hand, the Ljolsalfar have to get lucky with a hut to beat you if you want Leaves. No other civ, not even the Svarts seem to really go after it. They only seem to get it if they get hunting and have a priest or something pop.

It's pretty weak for the Kuriotates, because they can't exploit forests like the Svarts and Ljolsalfar can. Plus in the long fun you can park an Archamage in each city to run Abundance and Unyielding Order, so it really doesn't benefit you.

I've found that Runes is by far the strongest religion for them. Overlords is good early so that priest can nuke stuff.

Plus the map I use often gives them coastal starts, so it goes along with the prophet thing.
 
stoopid question, but if the "free science" is fixed, wouldn't it be possible that in quick the advance is enough to grant the tech immediatly ?
 
Varn is supposed to found The Empyrean most easily, as he is the canonical founder of the faith. In the lore he organized a religion devoted to Lugus long before he had the revelation which established the doctrines of the faith.

Hannah the Irin gets a tech bonus towards the Octopus Overlords, while Falamar does not. (Famalar's only advantage towards researching the tech is the fact that the Lanun start out with Fishing.) This is justified by the fact that Hannah is practically the messiah of the Overlords' faith, and considers it her mission to spread the religion to all the world. Famalar, on the other hand, is not at all religious. He is more familiar with the Overlords's religion than with any other, but he rejects it as a much of strange superstitions. He was chosen to be the champion of COndatis, the Archangel of Danalin, who hates the Overlords.


I'm thinking I may need to increase the cost of Mining and decrease the cost of Hunting.


@Calavente:

No. I play the game almost exclusively with the Quick game speed, so it is based on that game speed that I decided how much of a bonus to give the various players. None of them get even half of the research needed on Quick. On Marathon, the bonuses may well become almost negligible.

Edit: On the other hand, I suppose that the tech bonus I grant might be combined with a tech bonus given to AIs based on difficulty level.

I think I'll change those bonuses so that they are a fraction of the total tech cost, and so scale with the game speed.
 
Forgot to do it last night, but I can now confirm for you that if you attack a stack of pyre zombies, one dies and blows up, your stack, not theirs takes the damage from the explosion.

I'm pretty sure this is exactly the opposite of the base mod, though I have no idea what's been going on with the revisions he has been making.

Really if I know I am going to deal with them, I avoid it until I have a few mages with Life II.

If you don't believe me, put a couple pyre zombies and a wood golem (barbarians) on an empty tile and then give yourself some knights or something. Attack them. You stack will have damage, and theirs will be full health.
 
That's how they work in base FFH. Otherwise they would be a pretty crappy unit.

I'm pretty sure you are wrong. My memory is that if the Pyre Zombie died attacking a stack, the damage goes to the stack attacked. If you kill it in the stack it is in, the damage should go to that stack.

Tell me do you have a copy of it from waaay back.

Before you started doing your changes?
 
I'm pretty sure you are wrong.

And I'm 100% sure that I am right. The effect is done in python. Here's the code.

Code:
def postCombatExplode(pCaster, pOpponent):
	iX = pCaster.getX()
	iY = pCaster.getY()
	for iiX in range(iX-1, iX+2, 1):
		for iiY in range(iY-1, iY+2, 1):
			[COLOR="Red"]if not (iiX == iX and iiY == iY):[/COLOR]
				pPlot = CyMap().plot(iiX,iiY)
				if pPlot.isNone() == False:
					if (pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_FOREST') or pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_JUNGLE') or pPlot.getFeatureType() == gc.getInfoTypeForString('FEATURE_FOREST_NEW')):
						if CyGame().getSorenRandNum(100, "Flames Spread") < gc.getDefineINT('FLAMES_SPREAD_CHANCE'):
							bValid = True
							iImprovement = pPlot.getImprovementType()
							if iImprovement != -1 :
								if gc.getImprovementInfo(iImprovement).isPermanent() :
									bValid = False
							if bValid:
								pPlot.setImprovementType(gc.getInfoTypeForString('IMPROVEMENT_SMOKE'))
					for i in range(pPlot.getNumUnits()):
						pUnit = pPlot.getUnit(i)
						pUnit.doDamage(10, 100, pCaster, gc.getInfoTypeForString('DAMAGE_FIRE'), false)

The red part prevents it from affecting the plot the unit is on. It doesn't matter who was the attacker or defender.

You can still download Kael's last version from the main forum - http://forums.civfanatics.com/showthread.php?t=308020 (of course you'll need my XML fix so that Zombies explode instead of Sons of Asena - http://forums.civfanatics.com/showthread.php?t=419634)
 
What is that code supposed to mean to me?

You've got not comment one in the whole thing. No explanation of what variable is what. No context.

I take it we are looking at some sort of function that marches through the effects of an explosion. As another guess iX and iY are variables that use some kind of method or other function to get the X and Y coordinates of pCaster's current hex (whatever Python calls this stuff), and whatever it is you are doing here (Is this an object or a function? WTH does 'def' mean in Python? Define? A function? An object? This one of those languages that wants everything to be an object?).

That leads me to the question of what "iiX" and "iiY" are exactly. Dunno maybe every hex has an identifier? You aren't using a grid? Got me.

But then that leaves me with the question of whether this code is exactly the same as the 'base' code, untouched by you.

Now see I have no interest in learning Python. I gather from context this is the language Civ 4 used for scripting?

I'm pretty sure I remember attacking stacks with Pyre Zombies in the base mod, and not having it be suicide.

But you know something? I don't really care anymore. This game has been bugging me lately, and it is less and less fun to play.

Your AI improvements are actually part of that. Now I have annoying lizardmen that run back and forth from forested hill to forested hill for round after round. Not a threat exactly, but it keeps you from building till they actually attack a city or you can build units that can attack one and win.

Your improvements are also the reason I quit playing with Orthus turned on. He used to beeline for the closest city and give them his axe. Now he hangs around somewhere, for up to a hundred rounds, and pops up at a later time, after you've gotten bored of waiting for him, and moved on.

Kind of not getting your AI improvements. I understand not attacking if the odds say you are probably going to lose. But then if you wait long enough they do attack. Like they are bored or something, though that can't be the case. And then sometimes they attack when the odds are ridiculously against them.
 
If you "remember attacking stacks with Pyre Zombies in the base mod, and not having it be suicide" then you might be remembering playing the version of FfH2 where Kael accidentally switched the <PythonPostCombatLost> that should have belonged to Pyre Zombies to Sons of Asena instead.


The only difference between the MNAI and base FfH2 codes here is that MNAI uses less than while FfH2 uses less than or equal to in the line that determines the random odds of creating Smoke on a forested tile.


MagisterModmod has some other minor differences, but none with the effects you describe. It has its damage capped at 99% instead of 100%, so it is not fatal. It uses the form if not pPlot.isNone(): instead of the equivalent if pPlot.isNone() == False: just because I think that looks nicer. It defines various variables at the top rather than redefining them during each iteration of the loop, to make things slightly more efficient.

(I am thinking that I may in future versions swap the two loops and first conditional statement with a single loop, like this:
Code:
	for iDirection in range(DirectionTypes.NUM_DIRECTION_TYPES):
		pPlot = plotDirection(iX, iY, DirectionTypes(iDirection))
The effects should be equivalent, but it looks nicer and I think it would be very slightly more efficient.)


I believe that def is used to introduce the definition of a function. The units are all objects, as are the plots.

pCaster refers to the unit with this <PythonPostCombatLost> effect in its xml defined, i.e., the Pyre Zombie.

pOpponent refers to the unit that it was fighting in this particular combat, the one that killed the Pyre Zombie.

iX and iY are the coordinates of the plot where the Pyre Zombie is located.


iiX and iiY are the indices of loops used to cycle through nearby tiles. Any integer variables would do here, but iiX and iiY are the ones typically used in such cases for convenience sake.

For loops cycles through lists. The range function generates a list of integers starting with the first parameter, ending just before reaching the second parameter, in increments of the third parameter.

(That is what it does if given 3 parameters. If it only has only 2 arguments, then it returns a list starting with the first of those and ending just before the last with an increment of 1. If it is given a single argument, it returns a list of numbers starting at 0 and ending just before the number it is given.)

CyMap().plot(iiX,iiY) is a function that returns the plot object with the coordinates iiX and iiY.

if not (iiX == iX and iiY == iY): is a conditional statement used to make the rest of the code not run in cases where the coordinates of the plot that the CyMap().plot(iiX,iiY) function would generate are the same as the coordinates of where the Pyre Zombie is located.

pPlot.isNone() is a boolean function that returns true if the plot does not actually exist, as when its coordinates fall outside of the bounds of the map. This is important near the edges of flat maps.

pPlot.getFeatureType() is a function which returns the feature type of the plot object. If that is a Forest, Jungle, or New Forest, then it might generate the smoke improvement that could later lead to changing the feature to Flames.

CyGame().getSorenRandNum(100, "Flames Spread") is a pseudo-random number generator that generates which is 0 or more and less than 100. "Flames Spread" is a string used to seed it.

gc.getDefineINT('FLAMES_SPREAD_CHANCE') is an integer defined in the xml.

There is an if statements whose then runs when that integer is bigger than the random one.

Under that condition it finds the improvement on the tile, and if an improvement exists checks to see if it is a permanent improvement (like Unique Features such as the Yggdrasil). It will not change a plot with a permanent improvement, but otherwise will change the improvement to Smoke.

Completely separate from any consideration of whether it will create smoke on the tile, there is a for loop which goes through all of the units on the tile.

pPlot.getNumUnits() returns the number of units on the tile, so range(pPlot.getNumUnits()) creates a list of integers starting at 0 and stopping just shy of that number.

The pPlot.getUnit(i) function uses the index of that list to identify each of the specific units on that plot.

pUnit.doDamage(10, 99, pCaster, iFire, False) damages each of those units, with a fire type damage, counted as being dealt by pCaster (the Pyre Zombie) with a base amount of damage being 10% (which can be modified by factors like the unit's relative strength and the benefits of certain promotions), not being able to damage the unit more than 99% (so it cannot be completely lethal, like it is in base FfH2 or MNAI where this number is 100), and the boolean at the end says whether this damage may cause a war.
 
I concure with Tholal and Magister.
attacking pyre zombies was always an issue as when you killed it it exploded in your face.
the pyre zombies which explode always did damage to the surrounding tiles : not to the tiles it is one.

that's why you attacked pyre zombies with fire resistant units, and/or 2 move units... so that only the unit(s) that attacked got blasted and not the stack that did not attack yet.
Oh, and try reducing their health before killing the PZ... I was always of the impression that the damage was linked to their health before dying (but I may be wrong)

the only time when you could attack pyre zombies without having them kill you was when they did not explode at all.
 
Actually, I tried the plot direction method before, but it didn't do what it is supposed to do for me. It only loops through the vertical and horizontal ones but skip the diagonal ones.

Not sure if my civ dll is screwed as I have difficulties installing on this new com.
 
Using plotDirection seems to work fine for me. I just tested the pyre zombie change.

Are you sure you did not accidentally use plotCardinalDirection and/or range(CardinalDirectionTypes.NUM_CARDINALDIRECTION_TYPES) instead?

Of course, I have only tried it with the MNAI DLL, so I suppose there could be something wrong with the default BtS one.
 
Back
Top Bottom