[MOD] MagisterModmod

Is everyone else's Civlopedia working properly?
On mine, if I click on "Units", it shows only units up until Arquebus. When I click on any of those I don't get the specific unit info.
If I click on "Civilizations" and say go to Elohim and click on Monk, I don't get the Monk picture and info.

I had a similar problem myself in one game before merging in lfgr's latest update. I never discovered the cause, because the problem disappeared when I closed and reloaded the program and never happened again.

I do recall that I had before this point noticed some differences in the pedia python files in lfgr's version and mine. I think I started merging in his versions before having that bug, but then for some reason stopped. I think it was because the upgrade chart page was an even bigger mess with his code.
Edit: I guess lfgr found the answer to this one.

Ok, I need something to be explained to me. Why did a Granary spread the Empyrean into my city? As a fyi, I'm playing as the Khazad with Kandros Fir, advanced start.

EDIT 1: Even the Svartalfar have the Empyrean all over their cities, obviously by building Granaries all over.

EDIT 2: Unloading and reloading the mod fixed it. I have no idea what's going on.

I'm afraid I don't know what is going on here either. Are you sure it is Granary related? You didn't accidentally add the religion in worldbuilder? No one had an event trigger which gave the option to spread their state religion in their own and rival cities?

Hey Magister! First of all, I gotta say, I'm very impressed that this mod is still going strong for so long. After trying so many FFH2 modmods long ago, this ended up being my favorite by far, in part due to the lore authenticity, and in part due to the utterly ridiculous stuff you can do and reach in gameplay. I recently downloaded your updated versions, and I had a lot of fun despite the roughness on the edges (more on that later). This is going to be insanely long, so I apologize in advance.

First up, the 3 sessions I fired up to try out the mod; first 2 were with the version before the current, the third with the current version.
First session was with the Svartalfar, second with the Bannor, third with the Calabim (still going).

Spoiler First Session: Svartalfar :
The first session was me messing around with an elf civ, see how far you can go with being able to build more than just lumbermills and camps on forested tiles. The end result? Pure madness; the fellowship religion was a natural choice, and with the crazy food production you could achieve with farms + sanitation + ancient forests, your cities' population went through the roof, doubly so due to the generous health bonuses thanks to said forests. However, what I noticed is if you did Apprenticeship (or Arete if you got all your ancient forests and want a round with Kilmorph now) + all workshop-related techs, you could simply spam workshops like a madman to achieve downright sickening amounts of production without the drawback of being pop-limited.

Also, I went with Rivanna the Wraith Lord for that run, simply because the Organized trait was too good to pass up; Military Strategy is infinitely easier to reach than Arcane Lore, and this makes Organized hit much harder than Philosophical much earlier in the game. The Sinister trait was good stuff, it really helps recon units punch just a little bit harder, especially if you need to spam fawns in a pinch. I had to do that to beat down an octopus-worshiping Doviello at bay, whch also had a Saverous that was REALLY levelled up; it was nerve wracking, but it worked. I eventually sacked the Doviello and even managed to get their holy city, giving me 3 new sources of mana thanks to their Necronomicon.

The rest of the game was kinda uneventful, really; I passed everyone else in the game, maintained top position, and eventually got bored. So I fired up the Bannor.


Spoiler Second Session: Bannor :
The second session has me using the Bannor because I wanted to play a good civ for a change. Went with Sabathiel for the same reason I went with Rivanna, plus the fact he has Charismatic, another OP trait that trivializes unit training. This time, I beelined for the Order, and managed to rescue a Vicar from the Pyre of the Seraphic later on to found the Empyrean early. Before that, though, I spammed archers and killed the Illians early because they were a close competitor and they were evil. After the Illians, I decided to sack the Ljosalfar because I wanted to expand, which got Valin Phanuel at a high enough level to free Brigit.

Freeing Brigit was funny as hell. After I freed her, I had a super powerful unit that was perfect for... raiding unique features. Brigit could be a one-archangel army to put everyone else to heel, but what did I relegate her for? Looting her fallen god's little pyramid for free stuff. The audacity of her still unfallen archangel committing such casual disrespect towards her is not lost to me; I think I managed to get a jade torc, a timor mask, that Vicar I mentioned, and a Great Engineer. Good stuff. Valin, on the other hand, got a bunch of shades and great engineers by looting the Broken Sepulcher. At the very end, I just decided the Malakim should stop being baddies and attacking the Hippus, so I used a portal discovered by Brigit looting Bhall's little bonfire as a shortcut to attack the Malakim's unguarded behind. Sacked their Fellowship holy city, reduced them to a rump state, ended the game there.

By the way, Brigit turned from angel to demon at some point for some reason. What could cause such a thing?
.

The first way that comes to mind for an angel to turn into a demon is for it to somehow get the Demon Possessed promotion. Its python effect removes that promotion from non-living units, but first transforms Angels into Demons. (It also changes Life and Arawn's Death promotions to Undeath.)

At one point I had Unholy Taint turn all summons into Demons, but decided that was not right for a necromancer to summon a bunch of demonic Spectres and Wraiths that were invulnerable to Destroy Undead. I thought about having Unholy Taint pass on Unholy Taint, but with it allowing access to evil spell spheres in older versions or granting affinities with Demonic Pacts that seemed too much. I still did not want Profanes summoning a bunch of holy Einherjar angels instead of corrupted fallen angels (i.e., Demons).

Brigit is created in Python though, not a summon who would get any summon perks from its summoner's promotions. As Angels are non-living, she should also be immune from the lair exploration result that adds Possession

The only way I can think of for Brigit to become Demon Possessed is through reading the Infernal Grimoire. If you had your archangel seek such evil knowledge, I think it is appropriate that she would fall.

It is also possible for an Angel to become a Demon if you had a Pact with Statius at the time the unit was first created.

For more weird stuff that happened, Rivanna the Wraith Lord is both a leader of the Svartalfar, and a Commander under my employ, and you spawned as a great sage, who promptly became barbarian because I'm Calabim. Don't worry though, I captured you and you became Mikel Dylantyr for some reason. I need my Academy, you know.
MagisterCultuum does not turn barbarian because you are Calabim, but because his Children of the One religion makes his disloyal to anyone with any State Religion. You could have held on to this great sage and potentially even had him pass on Govanon's Ethics to your units if you had no state religion.(If you wait until after learning Theology to convert, you could make MagisterCultuum into a Profane, or a Luminary if you were not Calabim. That would change his religion and make him no longer rebel. If you then got an Infernal pact with Hyborem, your MagisterCultuum profane would have all of the abilities of an Archmage and could spread magical knowledge to anyone.)

It is kind of annoying that great persons change to different great persons when they are captured, but that is a vanilla BtS thing I don't know how to change.

With my sessions all showcased, I'll move on to my observations/suggestions/pipe dreams.

Spoiler :
Observations:
  1. Workshops are OP once set up right; their +5 :hammers: and +1 :commerce: stomp literally every other improvement out there even with the -1 :food: food malus (ancient forests + elves/kurios = gg wp), and if you also have the Financial trait with Arete? Well, where we're going, we won't need cottages. Or Farms. Maybe some Enclaves if you're Kurio, but if you're elven? Just turbocharge your production, what is Cernunnos gonna do, complain you're polluting his forests with industry? Without Ancient Forests, you'll need a few farms to make sure you're not in the negative food-wise, but a few Creation Affinity mages fix that problem VERY trivially, doubly so if they're Earth/Mind affinity for Greater Diligence/Inspiration.
  2. On the topic of Improvements, Mana Nodes don't give anything at all in terms of yield bonuses. I understand the bonus is the Mana you're collecting, but something to make them more than just one step above peaks in terms of yield usefulness would be nice. Also, why did you make Creation nodes buildable on raw mana? I thought you shouldn't be able to do such a thing, unless you changed something.
When I introduced Affinity I decided that it made much more sense for Creation to be a sphere with only affinity, without the ability to learn any spell sphere promotions with experience, rather than placing any limits on building Creation mana nodes. It still depends on chance, but in a less annoying way that does not push people so hard into trying to get the Dies Diei or Museum of Maponos every game.
Why are Thessa and Rivanna eligible to lead the Calabim? I'm asking for curiosity, really. I'd like to know of the lore behind this decision, if there's any.
If you play the scenario The Splintered Court, you will find that defeating either Thessa or Rivanna will lead to Alexis asking the favor of turning them over to her. If you agree, then they will appear as Calabim leaders in the Mulcarn Reborn scenario. (Volanna and Amelanchier can similarly be given to Baron Duin Halfmorn to return as Doviello werewolves.) Canonically, Thessa is an archmage who in her youth acquired forbidden knowledge from a grimoire of necromancy which had been stolen from the Calabim. On her wedding night she killed her husband in a ritual where she absorbed his spirit in order to make herself strong enough to purge the forest of the corruption that was destroying it. Her actions sound a lot like what a vampire does when it feeds. She was practically a vampire already, even if she learned from Calabim books rather than being turned by a vampire Sire the traditional way. Alexis would not want this knowledge spreading, but would surely recognize Thessa as the sort of talent that could rise high in her empire and should be given the dark gift in such a way that would bind her to her service. I often like to play Thessa as a reluctant vampire, who resists her desire to feast because she does not want to be evil yet at times must feed to serve a higher purpose. She is True Neutral and embodies the ethos of an Archmage as described by Malchavic. She is not needlessly cruel or malicious, but has the strength of will to pursue her goals and make herself commit any act, no matter how heinous, that she believes is necessary to achieve a worthy end. All we know about Rivanna canonically is that she often plots to depose Faeryl and is the one subordinate that the Winter Queen fears yet finds to useful to have assassinated. (If the Svartalfar were The North and Faeryl was Ned or Robb Stark, then Rivanna would be Roose Bolton.) I usually assume she is an archmage with affinity for Shadow and Death, or maybe even a Lich that maintains a convincing illusion of life. Given that her title is "Wraith Lord," not "Wraith Lady," I am not at all sure that she is female but may choose to present her gender differently at different times to different people.
  1. Svartalfar Archmages look bad. It's just a still model t-posing (probably to assert dominance over its more animated brethren), whereas illusionists are normal. Can you fix that, please? It makes the mod look unpolished. Even a haphazard model swap is fine, really. Same goes with Gosea, and pretty sure with some other units I'm not aware of.
  2. Speaking of unpolished, the mod in general feels unpolished all around. The Force mana writing tidbits have Kael's and your explanations thrown there haphazardly, the Affinity promotions are cluttered with all those explanation wall of text dumps in their effect list, many links don't go where they should (the abundance spell in the civilopedia doesn't get you to the building, it keeps you stuck there until you go manually), you have Longbowmen with 2-3 first strikes on their own with 3 Drill promotions on top, the unit icons looking enormous on the unit upgrades section, etc. etc. You gotta polish that stuff, man. Adding tons of stuff is fine and all, but polish is the other half of the building process, and equally essential. Would you mind if I tried my hand in doing some polish work? It's still up to you to decide on what to keep and what to discard, but I'd like to help around and make it less rough around the edges.
  3. IIRC unlike other religions, the White Hand didn't have an "Era" assigned to it, and always felt a little bit unpolished compared to the other religions. Ashes of Erebus did it some justice on that, did you fix that? Never had much of a chance to play the Illians recently.
  1. I'm not really familiar with Ashes of Erebus, or what is involved in making a new Era. I guess I can look into it.
Suggestions (small scale):
  1. While I understand most Archmages are insanely old due to dedicating their life in studying the arcane, some Archmage models don't/shouldn't look like it (Calabim, Amurite, Elven, Body/Life affinity mages, and probably some others). Instead of being a measly 1 strength denoting their old age, they could be 4 to represent they're not that decrepit (Calabim Archmages being Vampiric, Amurite Archmages being naturals and allowing them to reach that stage more easily than the rest, Elven Archmages just having higher lifespans, Body/Life Affinity Archmages being young and spry due to their sphere connection, etc). Of course, this depends on the civ, race, and model used, and shouldn't be that common.
  1. Reducing the strength all the way to 1 may have been too much, but I don't like the idea of them being any stronger physically than Mages/Wizards in their prime when deprived of enough mana for which they have affinity. Strength 2 or 3 may be better. Body 3 already can be used to increase their strength, and Body affinity randomly grants Strong, but canonically those who use Body magic actually end to die young as it puts too much strain on their bodies. It is like using high doses of anabolis steroids for years.
    [*]For some reason, I can stack Inspiration and Greater Inspiration together, getting the benefits of both, and I'm pretty sure this shouldn't be a thing. I also have the sneaking suspicion I can do the same with Diligence and Hope. Instead of effect buildings like Inspiration, Diligence, and Hope having only one building, why not split the effects? Like, have the normal effect buildings, and any additional effects are only added to the Greater version of the building. Then, you have the say, Greater Inspiration spell, and this puts down 2 "buildings": the normal inspiration, and its Greater cousin.
    [*]While we're on the "Greater xyz" topic, why not try to differentiate the effects between each Greater xyz "building"? For example, Diligence gives +10% bonus to :food::hammers::commerce:, while Inspiration gives +10% bonus to :gold::science::culture:. This would make each effect stand out more compared to its peers. Also, this is more for UI sorting, but instead of having the "(Greater)" text as a prefix, it would be better as a suffix. It'd make sorting much more intuitive, and the lookup of things much less painful.
The dll/xml is only written to allow a spell to create one building. I could add more in python, but normal spell buildings have to be maintained by a unit in the city capable of casting that spell. If I add a python effect I also have to add a python prereq, and would have to double the process of checking for valid casters, which is slower in python than C++. If I add a python prereq to the normal spell building preventing it from being cast in a city with the greater version, that would also apply to the spell maintain check and would cause the building to be removed each turn so long as the greater version of the building is there. If lfgr gets around to adding an xml tag to make the ability to cast one spell block another, then I might decide to make affinity promotions stack on top of normal spell spheres instead of replace them. Maybe then I'd make the greater versions of the spells only add the extra benefits on top of the base version, maybe even requiring the base version in the city as an xml prereq to cast. As it is that method would require way too many python prereqs for everything though.
  1. Can you make the Necronomicon readable like the Infernal Grimoire? That'd be pretty cool. Gaining power at the expense of madness, with Cultists/Speakers of the Tide having less of a risk would be pretty thematical for the Octopus Overlords.
I suppose I could make it a readable Grimoire, but don't think I will. It seems rather unbalanced for only one religion's holy city to have such an extra ability.
  1. While we're on the topic of Cultists, it'd be a pretty neat touch to have them yell quotes from Blood's cultists if possible (example). Again, it's a thematic touch that'd add to the experience.
I don't think I've ever dealt with any in game audio. I usually play with the sound off, listening to a podcast, audiobook, or YouTube video at the same time. It would take a bit of effort to figure out how to add audio files, it would make the download larger, there could be come copyright issues, and I just don't personally care very much.
Suggestions (large scale):
  1. To make things spicier, why not add a second version of affinity that's even more powerful? This could be used to represent Kael's idea of having freakishly powerful mages every once in a lifetime, with the tradeoff that mages spawned with this sort of "super" affinity can only have that, and no other affinity unless they want to try their hand becoming Archmages. Of course, I understand this might be unbalancing and could take a LOT of work, so feel free to discard it if you think it's not fitting, or mutate it to something more palatable.
There are already a lot of promotions in the game, way more than in the base game, which have to be cycled through many times per turn for every unit or spell prereq check. I don't feel like adding 21+ more just now without a very good reason. The once in a generation casters would all seem to be heroes anyway, which can have affinity in their unit defines without needing special promotions for that. I have considered making the 3rd level spell sphere promotions grant affinity (in the extra strength sense, not granting extra spells) which could boost Archmages in spheres for which they are not innately gifted.
  1. Instead of just having one spell for each mana sphere promotion, why not have two? Some mana spheres already have 2 spells tied to them, and this would allow for unconventional and creative spells. For example, Air spells could "lighten" a unit, progressively removing the heavy promotion and adding the light promotion to them, with Earth spells doing the inverse. Death and Undeath could be made into one promotion, with the use of Undeath spells automatically damning the unit to an afterlife in hell. Dimensional could set up "voodoo doll" effects (think the Destiny Bond move in Pokemon), Enchantment could boost a city's best attribute, Law being able to purge or neuter mutations, Mind could tap into its untainted foresight power for research or first strikes, etc. Combining two spheres for compound spells could also be a thing, an example being Body+Chaos allowing for "controlled" mutations (however much they can be controlled because of the Chaos sphere lol).
  1. At one point I intended to add a lot more spells, expecially cross sphere spells, but there are only so many unique flavorful and easily coded ideas. If you have have suggestions that work with existing game mechanics, not requiring DLL changes or insanely ineffiecient python, then I am willing to consider them but am making no promises.
    [*]I wish Brigit could go to Bhall's vault and nab the sphere of Fire to return it to its pure, untainted form via an expensive ritual. On top of being crazy epic, it could also go a lot of in-game effects related to Agares's manipulations amounting to nothing because a plucky little mortal civ undid all his hard work just like that. Plus, the idea of him sinking to new lows of despair, screaming in never seen before anguish on his pillow because his whispers amounted to nothing is just hilarious to me.
    What sort of in game effects are you thinking of? Making Brigit an Avatar, with complete healing like Auric Ascended and the ability to dominate every user of Fire magic? Removing access to Fire mana from all your enemies? Providing a Heart of Fire (the Gem of Creation still found in Bhall's broken vault) building that provides something like +100 Fire mana? Just a flavorful text popup/image? I may consider it, but doubt the game mechanics would make it easy enough to impliment an epic enough effect. At once point I did include a Rise of Laroth ritual, but ended up cutting it as I just could not think of a way to handle it in the game was was epic enough. I think this is a similar situation.
    [*]It'd be nice to have adventurers decoupled from the Great Person mechanic, and the Ardor World Spell being changed to reset the Adventurer counter. I liked how Rise from Erebus decoupled adventurers from other Great People, though it could imbalance the Grigori. Then again, the mod is already Camulos's playing field with how insane it is mechanically, what's a mechanic more?
    I don't intend to do this.
Pipe Dreams:
  1. I really wish Espionage, Cults, and Corporation-style Guilds were a thing. This requires a ton of DLL work to implement, sadly, but what I liked about the Orbis modmod is it splitting religions into proper religions and cults (putting the council of Esus into cult status), using Beyond the Sword's Espionage and Corporation Mechanics, and its more comprehensive civic system. The civic style can be ported easily (I can probably do it pretty fast), but the other stuff? I'd kill for all that.
  2. Another DLL-intensive mechanic I'd like would be the gradual terrain/feature change mechanic from Ashes of Erebus. Seeing Grassland gradually change to Tundra and then to Snow as the Illians makes the effort look more organic than that sudden change that occurs currently. This would also benefit Fellowship civs, with their forests turning Ancient not by chance but gradually and deliberately, and the Hell Terrain mechanic showing a corruption that seeps into Erebus slowly and menacingly instead of just "happening". Better load up those Life mages...
Any DLL stuff is up to lfgr, unless Tholal comes back.

I am not compleetly opposed to adding Cults that canonically exist, like the Emrys, Foxmen, Occis, and Stewards of Inequity, but I'd have to have good effects for them all worked out first. I don't plan to demote the Council of Esus to a cult/corporation.

  1. Observation: Too many civilizations have the same nationality voice lines, with Arabic being used a lot. It'd be nice if each civ had its own nationality voice-wise to ensure they're more distinct from each other.
  2. Suggestion: Hemah being able to dream and cause random effects (like Wonder, in a way) would be a pretty cool thing to implement, and make him more distinct than how he currently is. Right now, he's just an archmage with water/mind affinities, a strength of 7, and a damage randomization effect. Pretty sure it'd take a lot of time to implement, though.
As I said, I always have the audio off and consider it a very low priority. I would not mind reassigning the voices for different units or civs if someone else does most of the work of deciding what fits best together and all I have to do is some minor xml tweaks, but I don't intend to go finding new audiofiles to include in every download.


If it was not for the existence of Gaelan, I think I would have long ago tried changing Hemah to be a Mage (rather than archmage) level caster with the ability to cast Wonder or something similar. The pedia never says "Some say Hemah isn't a mage (not Archmage), he only dreamt he was once and he hasn't forgotten the dream.

I'm a bit reluctant to add a new promotion just for one unit's PyPerTurn effect. (I would much prefer it is units could have <PyPerTurn> effects and promotions could grant <PythonPostCombatWon> and <PythonPostCombatLost> effects.) I guess I could make a random event that requires the unit and recurs frequently, but it would be a lot of work and I imagine it could easily get to be more annoying than fun.

p.s. Using lists, especially numbered lists, makes posts very hard to quote when trying to address things point by point as the forum keep trying to reformat and renumber everything.
 
I'm afraid I don't know what is going on here either. Are you sure it is Granary related? You didn't accidentally add the religion in worldbuilder? No one had an event trigger which gave the option to spread their state religion in their own and rival cities?

None of that were a thing, I'm afraid. I do remember starting and aborting lots of game sessions, but I have no idea whatsoever what would trigger this effect. Personally, I'll chalk it up to a one in a million occurrence and think nothing of it until it happens again. If it happens again and I manage to reproduce it, I'll notify you right away.

The first way that comes to mind for an angel to turn into a demon is for it to somehow get the Demon Possessed promotion. Its python effect removes that promotion from non-living units, but first transforms Angels into Demons. (It also changes Life and Arawn's Death promotions to Undeath.)

At one point I had Unholy Taint turn all summons into Demons, but decided that was not right for a necromancer to summon a bunch of demonic Spectres and Wraiths that were invulnerable to Destroy Undead. I thought about having Unholy Taint pass on Unholy Taint, but with it allowing access to evil spell spheres in older versions or granting affinities with Demonic Pacts that seemed too much. I still did not want Profanes summoning a bunch of holy Einherjar angels instead of corrupted fallen angels (i.e., Demons).

Brigit is created in Python though, not a summon who would get any summon perks from its summoner's promotions. As Angels are non-living, she should also be immune from the lair exploration result that adds Possession

The only way I can think of for Brigit to become Demon Possessed is through reading the Infernal Grimoire. If you had your archangel seek such evil knowledge, I think it is appropriate that she would fall.

It is also possible for an Angel to become a Demon if you had a Pact with Statius at the time the unit was first created.

I didn't build the Infernal Grimoire, let alone use it, nor did I make any pact with Statius. I think I'll need to "replicate" this event and tell you how it exactly happened if I manage to reproduce it.

MagisterCultuum does not turn barbarian because you are Calabim, but because his Children of the One religion makes his disloyal to anyone with any State Religion. You could have held on to this great sage and potentially even had him pass on Govanon's Ethics to your units if you had no state religion.(If you wait until after learning Theology to convert, you could make MagisterCultuum into a Profane, or a Luminary if you were not Calabim. That would change his religion and make him no longer rebel. If you then got an Infernal pact with Hyborem, your MagisterCultuum profane would have all of the abilities of an Archmage and could spread magical knowledge to anyone.)

It is kind of annoying that great persons change to different great persons when they are captured, but that is a vanilla BtS thing I don't know how to change.

Oh, my bad. Thanks for clarifying that.

If you play the scenario The Splintered Court, you will find that defeating either Thessa or Rivanna will lead to Alexis asking the favor of turning them over to her. If you agree, then they will appear as Calabim leaders in the Mulcarn Reborn scenario. (Volanna and Amelanchier can similarly be given to Baron Duin Halfmorn to return as Doviello werewolves.) Canonically, Thessa is an archmage who in her youth acquired forbidden knowledge from a grimoire of necromancy which had been stolen from the Calabim. On her wedding night she killed her husband in a ritual where she absorbed his spirit in order to make herself strong enough to purge the forest of the corruption that was destroying it. Her actions sound a lot like what a vampire does when it feeds. She was practically a vampire already, even if she learned from Calabim books rather than being turned by a vampire Sire the traditional way. Alexis would not want this knowledge spreading, but would surely recognize Thessa as the sort of talent that could rise high in her empire and should be given the dark gift in such a way that would bind her to her service. I often like to play Thessa as a reluctant vampire, who resists her desire to feast because she does not want to be evil yet at times must feed to serve a higher purpose. She is True Neutral and embodies the ethos of an Archmage as described by Malchavic. She is not needlessly cruel or malicious, but has the strength of will to pursue her goals and make herself commit any act, no matter how heinous, that she believes is necessary to achieve a worthy end. All we know about Rivanna canonically is that she often plots to depose Faeryl and is the one subordinate that the Winter Queen fears yet finds to useful to have assassinated. (If the Svartalfar were The North and Faeryl was Ned or Robb Stark, then Rivanna would be Roose Bolton.) I usually assume she is an archmage with affinity for Shadow and Death, or maybe even a Lich that maintains a convincing illusion of life. Given that her title is "Wraith Lord," not "Wraith Lady," I am not at all sure that she is female but may choose to present her gender differently at different times to different people.

Makes sense, thanks for the rundown.

I'm not really familiar with Ashes of Erebus, or what is involved in making a new Era. I guess I can look into it.

If you want me to, I can try messing around with my copy of MagisterModMod and do it myself. IIRC, I managed to do it very seamlessly years ago by doing some copying around and some rough play testing just to make sure nothing's broken, so it should be easy enough.

Reducing the strength all the way to 1 may have been too much, but I don't like the idea of them being any stronger physically than Mages/Wizards in their prime when deprived of enough mana for which they have affinity. Strength 2 or 3 may be better. Body 3 already can be used to increase their strength, and Body affinity randomly grants Strong, but canonically those who use Body magic actually end to die young as it puts too much strain on their bodies. It is like using high doses of anabolis steroids for years.

Yeah, base strength 3 for eligible archmages sounds good. Strength 2 is fine too if you feel 3 tips the scales too much and wanna make it more universal.

The dll/xml is only written to allow a spell to create one building. I could add more in python, but normal spell buildings have to be maintained by a unit in the city capable of casting that spell. If I add a python effect I also have to add a python prereq, and would have to double the process of checking for valid casters, which is slower in python than C++. If I add a python prereq to the normal spell building preventing it from being cast in a city with the greater version, that would also apply to the spell maintain check and would cause the building to be removed each turn so long as the greater version of the building is there. If lfgr gets around to adding an xml tag to make the ability to cast one spell block another, then I might decide to make affinity promotions stack on top of normal spell spheres instead of replace them. Maybe then I'd make the greater versions of the spells only add the extra benefits on top of the base version, maybe even requiring the base version in the city as an xml prereq to cast. As it is that method would require way too many python prereqs for everything though.

Oof, guess we'll have to live with building stacking until such a thing can get fixed. I assumed multiple buildings can be thrown down at once, but since it's not possible...

I suppose I could make it a readable Grimoire, but don't think I will. It seems rather unbalanced for only one religion's holy city to have such an extra ability.

Maybe other shrines can have their own abilities to balance it out? This is more of a concept to sit upon atm than sth that can be applied immediately. If I can think of something for every other shrine, I'll pitch the idea to you again.

I don't think I've ever dealt with any in game audio. I usually play with the sound off, listening to a podcast, audiobook, or YouTube video at the same time. It would take a bit of effort to figure out how to add audio files, it would make the download larger, there could be come copyright issues, and I just don't personally care very much.

Another thing I'll do for my copy, then. If others are ok with it and no copyright issues pop up, I'll share it too.

There are already a lot of promotions in the game, way more than in the base game, which have to be cycled through many times per turn for every unit or spell prereq check. I don't feel like adding 21+ more just now without a very good reason. The once in a generation casters would all seem to be heroes anyway, which can have affinity in their unit defines without needing special promotions for that. I have considered making the 3rd level spell sphere promotions grant affinity (in the extra strength sense, not granting extra spells) which could boost Archmages in spheres for which they are not innately gifted.

Huh, this does make sense. I rest my case on this.

Gaining strength affinity with the 3rd level sphere is a neat idea though.

At one point I intended to add a lot more spells, expecially cross sphere spells, but there are only so many unique flavorful and easily coded ideas. If you have have suggestions that work with existing game mechanics, not requiring DLL changes or insanely ineffiecient python, then I am willing to consider them but am making no promises.

As I mentioned, have an Air sphere spell that takes a unit and first removes the Heavy promotion if it exists, and if it does, you can cast it again to bestow the Light promotion. You can also have an Earth analogue that does the opposite (Light -> normal -> Heavy).

Fire can have a derivative of Herald's Call; turbocharge a unit's power with the risk of them spontaneously dying or burning up (getting the Weak/Enervated promotion after its effect ends) because they can't handle the power. It plays with Fire's theme of great but temporary transformations that can leave the user weaker (or dead) afterwards.

Enchantment can take a city, compare every attribute (production, gold, research, culture, great person production, experience bestowed to units), and boost the best of them by a certain percentage. Again, it falls in line with Enchantment improving an object's quality.

In all honesty though, instead of burdening you with requests, I'll try my hand in making spells myself and tossing them at you for you to accept to discard. Sound good to you?

What sort of in game effects are you thinking of? Making Brigit an Avatar, with complete healing like Auric Ascended and the ability to dominate every user of Fire magic? Removing access to Fire mana from all your enemies? Providing a Heart of Fire (the Gem of Creation still found in Bhall's broken vault) building that provides something like +100 Fire mana? Just a flavorful text popup/image? I may consider it, but doubt the game mechanics would make it easy enough to impliment an epic enough effect. At once point I did include a Rise of Laroth ritual, but ended up cutting it as I just could not think of a way to handle it in the game was was epic enough. I think this is a similar situation.

A singular effect won't do for an event as big as Brigit's Ascension, so I'll have to make a list of effects instead:

1. Fire 3 and anything fire-related won't damn units to an afterlife in hell anymore. Also, if you weren't Good-aligned before for some reason, you are now.
2. The purification of the Fire sphere should bar it from the Infernals and any demons, and bolster the forces of Good in some big extent, with demons now receiving a BIG malus to fire damage, as the sphere Agares worked so hard to corrupt is now pure again and arms the righteous as it did before Bhall's fall. For this great deed, you can get a great relations bonus with Order/Empyrean civs and the Mercurians, and a severe malus with Ashen Veil civs and the Infernals.
3. Brigit taking Bhall's place should affect the Clan of Embers in a big way if they're in play. They could be purified of their orcish nature, they could start on a path to redemption, or they could stay corrupt and suffer the consequences. I can't give any pinpoint specifics, but since they're so tied to the Fire sphere, it should affect them pretty severely. This also goes for the orc Barbarians littering the map.
4. Brigit being an Avatar on Erebus would violate the Compact pretty bad, and while I'd like it to be a choice, I don't want it to be without consequences. The Godslayer needs to be given to the strongest rival civ if the choice is possible and Brigit stays on Erebus. Or if Auric Ascended is on the map, she could stay on Erebus to incinerate him for his violation of the Compact, and have a choice to return to her Vault or stay.

That's as much as I can think of, really. There might be more that can be done, but it's up to the rest to suggest stuff.

As for Laroth? That ritual could turn the Sidar Evil as they become his thralls, you could get a Laroth Ascended unit that bursts into Erebus from Bradeline's Well (to Tebryn's surprise, I can imagine), or even corrupt the death sphere so much, only undeath spells can be used at that point. I'm just spitballing though.

Unrelated, but I wonder if an evil civ can have Odio claim the Fire or Ice spheres, or instead of claiming the fire sphere, have Brigit claim the Ice sphere with the motivation of coming to the good old days of righteousness. This would take a massive undertaking, though, and some of the ideas might not fit, so it's ultimately up to you.

Any DLL stuff is up to lfgr, unless Tholal comes back.

I am not compleetly opposed to adding Cults that canonically exist, like the Emrys, Foxmen, Occis, and Stewards of Inequity, but I'd have to have good effects for them all worked out first. I don't plan to demote the Council of Esus to a cult/corporation.

Normally, I'd have the Council of Esus be its own thing sitting on top of other religions to represent how it likes to mislead anything and everything, but that'd be a pretty big undertaking with some DLL work required. That's the limitation of the Civ4 framework, sadly.

As I said, I always have the audio off and consider it a very low priority. I would not mind reassigning the voices for different units or civs if someone else does most of the work of deciding what fits best together and all I have to do is some minor xml tweaks, but I don't intend to go finding new audiofiles to include in every download.

I'll see what I can do, then. You can focus on the stuff you planned so you don't get overwhelmed by suggestions.

If it was not for the existence of Gaelan, I think I would have long ago tried changing Hemah to be a Mage (rather than archmage) level caster with the ability to cast Wonder or something similar. The pedia never says "Some say Hemah isn't a mage (not Archmage), he only dreamt he was once and he hasn't forgotten the dream.

I'm a bit reluctant to add a new promotion just for one unit's PyPerTurn effect. (I would much prefer it is units could have <PyPerTurn> effects and promotions could grant <PythonPostCombatWon> and <PythonPostCombatLost> effects.) I guess I could make a random event that requires the unit and recurs frequently, but it would be a lot of work and I imagine it could easily get to be more annoying than fun.

Yeah, an automatic effect can get very annoying, though one idea is to turn it off for slightly weaker strength/spell strength. Still, if it's not fun, it shouldn't be implemented, so I understand your reluctance.

p.s. Using lists, especially numbered lists, makes posts very hard to quote when trying to address things point by point as the forum keep trying to reformat and renumber everything.

Will keep that in mind. I like formatting stuff to keep things legible, but since lists cause issues I'll refrain from using them from now on.
 
Oh, I actually forgot a crucial thing: the Orbis mod also has the White Hand have its own era like the rest of the religions. It also has a unique sound for when it's founded and it spreads to a city. Orbis has quite a lot of things you can salvage from, if you're interested in that.

I feel like an idiot for forgetting all that.
 
Welp, another weird thing happened to me. When I booted up your modmod and went to the civilopedia, as I was combing the Traits screen (the Financial trait is OP how it is rn, I suggest it give that extra :commerce: at 3 :commerce: instead of the 2 it is currently), I noticed Hafgan the Purger having the Pact with Sallos trait onto him. I closed the game, reopened it, and it still was there. Had to repeat the reboot a third time before it returned to normal.

I currently erased the Beyond the Sword folder in my documents to see if that fixes anything, but something's definitely up. I don't know if it's just me having a case of Paranormal Activity or there's something more substantial (sometimes the game refuses to start at the initialization stage, I should add), so has anyone here noticed strange stuff like Granaries spreading the Empyrean, or Hafgan suddenly getting the Pact with Sallos trait?
 

Attachments

  • Civ4BeyondSword_2019_07_05_01_16_12_799.png
    Civ4BeyondSword_2019_07_05_01_16_12_799.png
    1.3 MB · Views: 78
I have had a couple games where a minor leader randomly got an Pact trait before, but never found out why. I never had it stick around after restarting the game before though. I've also been annoyed by the game occasionally closing itself during initialization. I wish I knew the cause, and hope it is fixed with lfgr's latest dll. I have merged in mnai-2.8-beta2u and will be uploading another minor update soon.
 
I went ahead and released a minor update tonight, incorporating lfgr's minor update.

Unfortunately I forgot to test any Advanced Start games before releasing, and did not realize that when eliminating unnecessary tags in CIV4UnitInfos.xml I accidentally removed all of the <iAdvancedStartCost> tags and thus prevented any units from being eligible for purchase in advanced start games. I considered re-uploading with that fix tonight, but since I suspect lfgr may release a new version soon I think this fix can probably wait until I have more fixes to add to it.


edit: I just discovered and fixed 3 minor python errors. One was in the Ignore Changeling event when the unit becomes a barbarian but has no free tile to occupy. One in he help string for Vitalize (iNewForest was not defined, or rather defined in a section I commented out thinking it was unnecessary). One was in the on move call for Hallowed Ground, where I initialize a Tomb Warden for pPlotPlayer instead of pPlayer.


I'm thinking of possibly removing Death 1 and Undeath 1 from the spells randomly granted to Adepts, but keeping Death affinity for Mages. Kael did say that "No one is born with death affinity. Instead it is found in those that suffer some traumatic event early in life." I'm not sure I want too many Adepts summoning Rebellious Skeletons early in the game when cities are not well defended. Adepts with Death mana could still purchase it, just not get it at random. Hallowing a Grave can also be very powerful in the early game if used to turn City Ruins into a Graveyard that is immediately robbed and produces technologies.
 
Last edited:
I'm thinking of possibly removing Death 1 and Undeath 1 from the spells randomly granted to Adepts, but keeping Death affinity for Mages. Kael did say that "No one is born with death affinity. Instead it is found in those that suffer some traumatic event early in life." I'm not sure I want too many Adepts summoning Rebellious Skeletons early in the game when cities are not well defended. Adepts with Death mana could still purchase it, just not get it at random. Hallowing a Grave can also be very powerful in the early game if used to turn City Ruins into a Graveyard that is immediately robbed and produces technologies.

Go for it. If it's feasible, you could randomly grant normal Death promotions (or even affinity?) to any arcane unit that survived a battle at critical condition (20% or below health seems like a good reference point), going along with Kael's info regarding Death affinity. The closer to death the unit, the more the chance of getting an increasingly powerful bonus. As you don't see arcane units thrown to the front lines like other units, I don't see it as a common occurrence, but I could see daring enough players would be pretty keen on throwing a mage in a battle from time to time to see if they luck out on the death promotion lottery.

Speaking of Death-related stuff, how is Death affinity/promotions applied at the moment? Is Death affinity and promotions preferred to their Undeath equivalent, or just random? If it's the latter, outside of specific cases (demons, unholy taint units, vampires, and the like), I'd greatly prefer it if the affinity promotion given was Death at first, with the choice to irreversibly turn it to Undeath if one so wishes. Or idk, have it dependent on the unit's alignment? I like to have a degree of control when it comes to death/undeath affinity-wise, as it feels a bit outside my control right now. Not that affinity is controllable, of course, but choosing how to use your gifts is more of a choice than choosing which ones you are burdened with.

By the way, quick side note: if you luck out and have an explorable unique feature like the Broken Sepulcher, the Palus, or Pyre of the Seraphic very near your starting city, and are willing to roll the dice exploring it a few times, you can easily go waaaaaay overboard with the stuff you can loot and people you can rescue. Playing as Alexis of the Calabim, I managed to earn tens of great people, commanders, and shades from the Broken Sepulcher, tons of items (I managed to get 2 of Kanna's rings and Deasil Charms, not to mention the uncountable Jade Torcs I collected), and when a lair defender popped up, I could easily kill them for free xp. With Philosophical, Pacifist, and a metric boatload of settled great people, I was practically mass producing them like some sort of factory. Dungeons have nothing on explorable unique features tbqh
 
Last edited:
A little off topic, but has anyone else felt that Malakim are a bit slow to build up compared to others?
When we start off with mostly deserts around us and not forests we lose a production advantage that others have.
Since they typically have flood plains nearby too, a cool building for them to have might be one that grants +1 production on desert & flood plains tiles or at least flood plains, if there is a concern that it would result in desert hills being too productive.
 
A little off topic, but has anyone else felt that Malakim are a bit slow to build up compared to others?
When we start off with mostly deserts around us and not forests we lose a production advantage that others have.
Since they typically have flood plains nearby too, a cool building for them to have might be one that grants +1 production on desert & flood plains tiles or at least flood plains, if there is a concern that it would result in desert hills being too productive.

There's no need for such measures, you can solve the :hammers: problem by building Workshops. They can be plopped down to any tile with at least 1 :food:, and with flood plains being 3 :food:? You can do Aristoagrarianism paired with Apprenticeship or Arete, and enjoy 2 :food: 2 :hammers: 3 :commerce: workshop tiles (4 :commerce: with Arete, with +1 :hammers: on mines on top!!! Kilmorph is just too good) and up to 5 :food: 4 :commerce: farm tiles. Smelting gets workshops to 3 :hammers:, and guilds boosts them to a scary 5 :hammers:, and with the research benefits you'll have for being Malakim (especially if you play as Kane instead of Varn!), you'll reach your full potential in no time. Just beeline towards Construction first, and make sure you stock up on health bonuses to counteract the flood plains :yuck:.
 
Last edited:
Go for it. If it's feasible, you could randomly grant normal Death promotions (or even affinity?) to any arcane unit that survived a battle at critical condition (20% or below health seems like a good reference point), going along with Kael's info regarding Death affinity. The closer to death the unit, the more the chance of getting an increasingly powerful bonus. As you don't see arcane units thrown to the front lines like other units, I don't see it as a common occurrence, but I could see daring enough players would be pretty keen on throwing a mage in a battle from time to time to see if they luck out on the death promotion lottery.

Speaking of Death-related stuff, how is Death affinity/promotions applied at the moment? Is Death affinity and promotions preferred to their Undeath equivalent, or just random? If it's the latter, outside of specific cases (demons, unholy taint units, vampires, and the like), I'd greatly prefer it if the affinity promotion given was Death at first, with the choice to irreversibly turn it to Undeath if one so wishes. Or idk, have it dependent on the unit's alignment? I like to have a degree of control when it comes to death/undeath affinity-wise, as it feels a bit outside my control right now. Not that affinity is controllable, of course, but choosing how to use your gifts is more of a choice than choosing which ones you are burdened with.

By the way, quick side note: if you luck out and have an explorable unique feature like the Broken Sepulcher, the Palus, or Pyre of the Seraphic very near your starting city, and are willing to roll the dice exploring it a few times, you can easily go waaaaaay overboard with the stuff you can loot and people you can rescue. Playing as Alexis of the Calabim, I managed to earn tens of great people, commanders, and shades from the Broken Sepulcher, tons of items (I managed to get 2 of Kanna's rings and Deasil Charms, not to mention the uncountable Jade Torcs I collected), and when a lair defender popped up, I could easily kill them for free xp. With Philosophical, Pacifist, and a metric boatload of settled great people, I was practically mass producing them like some sort of factory. Dungeons have nothing on explorable unique features tbqh

Here is the affinity code:
Spoiler :

in CvEventManager.py:
Code:
   def onUnitPromoted(self, argsList):
       'Unit Promoted'
       pUnit, iPromotion = argsList
       iPlayer = pUnit.getOwner()
       player = PyPlayer(iPlayer)
       pPlayer = gc.getPlayer(iPlayer)
       iTeam = pPlayer.getTeam()
       eTeam = gc.getTeam(iTeam)
       iCiv = pPlayer.getCivilizationType()
       pPlot = pUnit.plot()
       pArea = pUnit.area()

       iUnit = pUnit.getUnitType()
       infoUnit = gc.getUnitInfo(iUnit)
       infoProm = gc.getPromotionInfo(iPromotion)


       iChanneling1 = gc.getInfoTypeForString('PROMOTION_CHANNELING1')
       iChanneling2 = gc.getInfoTypeForString('PROMOTION_CHANNELING2')
       iChanneling3 = gc.getInfoTypeForString('PROMOTION_CHANNELING3')
       iUnholyTaint = gc.getInfoTypeForString('PROMOTION_UNHOLY_TAINT')

       if iPromotion in [gc.getInfoTypeForString('PROMOTION_ILLUSION'), gc.getInfoTypeForString('PROMOTION_DARK_REFLECTION')]:
           if pUnit.isAvatarOfCivLeader():
               pUnit.setAvatarOfCivLeader(False)
           cf.makeMortal(pUnit)
           pUnit.setDuration(1)


       elif iPromotion == gc.getInfoTypeForString('PROMOTION_CHANGELING'):
           if not -1 < pUnit.getScenarioCounter() < gc.getNumUnitInfos():
               pUnit.setScenarioCounter(pUnit.getUnitType())


       elif iPromotion == iChanneling1:
           if pUnit.getRace() != gc.getInfoTypeForString('PROMOTION_PUPPET'):
   ##           if iUnitCombat == gc.getInfoTypeForString('UNITCOMBAT_ADEPT'):
               listWeightedAffinities = []
               listAffinities = [   gc.getInfoTypeForString('PROMOTION_AIR1'),
                                   gc.getInfoTypeForString('PROMOTION_BODY1'),
                                   gc.getInfoTypeForString('PROMOTION_CHAOS1'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_CREATION'),
                                   gc.getInfoTypeForString('PROMOTION_DEATH1'),
                                   gc.getInfoTypeForString('PROMOTION_DEATH_ARAWN1'),
                                   gc.getInfoTypeForString('PROMOTION_DIMENSIONAL1'),
                                   gc.getInfoTypeForString('PROMOTION_EARTH1'),
                                   gc.getInfoTypeForString('PROMOTION_ENCHANTMENT1'),
                                   gc.getInfoTypeForString('PROMOTION_ENTROPY1'),
                                   gc.getInfoTypeForString('PROMOTION_FIRE1'),
                                   gc.getInfoTypeForString('PROMOTION_FORCE1'),
                                   gc.getInfoTypeForString('PROMOTION_ICE1'),
                                   gc.getInfoTypeForString('PROMOTION_LAW1'),
                                   gc.getInfoTypeForString('PROMOTION_LIFE1'),
                                   gc.getInfoTypeForString('PROMOTION_METAMAGIC1'),
                                   gc.getInfoTypeForString('PROMOTION_MIND1'),
                                   gc.getInfoTypeForString('PROMOTION_NATURE1'),
                                   gc.getInfoTypeForString('PROMOTION_SHADOW1'),
                                   gc.getInfoTypeForString('PROMOTION_SPIRIT1'),
                                   gc.getInfoTypeForString('PROMOTION_SUN1'),
                                   gc.getInfoTypeForString('PROMOTION_WATER1')
                                   ]
               if pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_OVERCOUNCIL')):
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DEATH_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_DEATH1') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_DEATH1'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_ENTROPY_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_ENTROPY1') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_ENTROPY1'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SHADOW_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_SHADOW1') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_SHADOW1'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DIMENSIONAL_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_DIMENSIONAL1') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_DIMENSIONAL1'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_CHAOS_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_ENTROPY1') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_ENTROPY1'))
               elif pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_UNDERCOUNCIL')):
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SUN_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_SUN1') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_SUN1'))
               lAlignment = [pPlayer.getAlignment(), cf.getUnitAlignment(pUnit, False)]
               if gc.getInfoTypeForString('ALIGNMENT_EVIL') in lAlignment:
                   if gc.getInfoTypeForString('PROMOTION_DEATH_ARAWN1') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_DEATH_ARAWN1'))
               elif gc.getInfoTypeForString('ALIGNMENT_GOOD') in lAlignment:
                   if gc.getInfoTypeForString('PROMOTION_DEATH1') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_DEATH1'))
               if iCiv == gc.getInfoTypeForString('CIVILIZATION_SIDAR') or pUnit.getRace() == gc.getInfoTypeForString('PROMOTION_GREY'):
                   if gc.getInfoTypeForString('PROMOTION_DEATH_ARAWN1') in listAffinities:
                       listAffinities.append(gc.getInfoTypeForString('PROMOTION_DEATH_ARAWN1'))
                   if gc.getInfoTypeForString('PROMOTION_DEATH1') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_DEATH1'))
               if pUnit.isHasPromotion(iUnholyTaint) or pUnit.getRace() in [gc.getInfoTypeForString('PROMOTION_UNDEAD'),gc.getInfoTypeForString('PROMOTION_DEMON')]:
                   if gc.getInfoTypeForString('PROMOTION_LIFE1') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_LIFE1'))
                   if gc.getInfoTypeForString('PROMOTION_DEATH_ARAWN1') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_DEATH_ARAWN1'))
               if pUnit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_VAMPIRE')):
                   if gc.getInfoTypeForString('PROMOTION_SUN1') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_SUN1'))

               iNumSpheres = 1
               if CyGame().getSorenRandNum(5, "Petrarch? "+ str(pUnit.getName())) < 1:
                   iNumSpheres = 2
               for iAffinity in listAffinities:
                   if pUnit.isHasPromotion(iAffinity):
                       iNumSpheres -= 1
                       if iNumSpheres < 1:
                           break
                   else:
                       infoAffinity = gc.getPromotionInfo(iAffinity)
                       iMana = infoAffinity.getBonusPrereq()
                       for i in range(cf.getNumBonusEffective(iPlayer, iMana, pUnit)):
                           listWeightedAffinities.append(iAffinity)

               for i in range(iNumSpheres):
                   if len(listWeightedAffinities) > 0:
                       iAffinity = listWeightedAffinities.pop(CyGame().getSorenRandNum(len(listWeightedAffinities), "Affinity-Channeling1 " + str(pUnit.getName())))
                       pUnit.setHasPromotion(iAffinity, True)
                       self.onUnitPromoted([pUnit, iAffinity])


       elif iPromotion == iChanneling2:
           if pUnit.getUnitCombatType() == gc.getInfoTypeForString('UNITCOMBAT_ADEPT') or (pUnit.isHasPromotion(iUnholyTaint) and pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_HYBOREM'))):
               listWeightedAffinities = []
               listAffinities = [   gc.getInfoTypeForString('PROMOTION_AFFINITY_AIR'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_BODY'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_CHAOS'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_CREATION'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH_ARAWN'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_DIMENSIONAL'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_EARTH'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_ENCHANTMENT'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_ENTROPY'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_FIRE'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_FORCE'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_ICE'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_LAW'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_LIFE'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_METAMAGIC'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_MIND'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_NATURE'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_SHADOW'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_SPIRIT'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_SUN'),
                                   gc.getInfoTypeForString('PROMOTION_AFFINITY_WATER')
                                   ]

               if pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_OVERCOUNCIL')):
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DEATH_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_ENTROPY_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_AFFINITY_ENTROPY') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_ENTROPY'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SHADOW_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_AFFINITY_SHADOW') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_SHADOW'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DIMENSIONAL_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_AFFINITY_DIMENSIONAL') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_DIMENSIONAL'))
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_CHAOS_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_AFFINITY_ENTROPY') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_ENTROPY'))
               elif pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_UNDERCOUNCIL')):
                   if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SUN_MANA')):
                       if gc.getInfoTypeForString('PROMOTION_AFFINITY_SUN') in listAffinities:
                           listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_SUN'))
               lAlignment = [pPlayer.getAlignment(), cf.getUnitAlignment(pUnit, False)]
               if gc.getInfoTypeForString('ALIGNMENT_EVIL') in lAlignment:
                   if gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH_ARAWN') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH_ARAWN'))
               elif gc.getInfoTypeForString('ALIGNMENT_GOOD') in lAlignment:
                   if gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH'))
               if iCiv == gc.getInfoTypeForString('CIVILIZATION_SIDAR') or pUnit.getRace() == gc.getInfoTypeForString('PROMOTION_GREY'):
                   if gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH_ARAWN') in listAffinities:
                       listAffinities.append(gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH_ARAWN'))
                   if gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH'))
               if pUnit.isHasPromotion(iUnholyTaint) or pUnit.getRace() in [gc.getInfoTypeForString('PROMOTION_UNDEAD'),gc.getInfoTypeForString('PROMOTION_DEMON')]:
                   if gc.getInfoTypeForString('PROMOTION_AFFINITY_LIFE') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_LIFE'))
                   if gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH_ARAWN') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_DEATH_ARAWN'))
               if pUnit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_VAMPIRE')):
                   if gc.getInfoTypeForString('PROMOTION_AFFINITY_SUN') in listAffinities:
                       listAffinities.remove(gc.getInfoTypeForString('PROMOTION_AFFINITY_SUN'))

               iNumSpheres = 1
               if CyGame().getSorenRandNum(5, "Petrarch? "+ str(pUnit.getName())) < 1:
                   iNumSpheres = 2
               for iAffinity in listAffinities:
                   if pUnit.isHasPromotion(iAffinity):
                       iNumSpheres -= 1
                       if iNumSpheres < 1:
                           break
                   else:
                       infoAffinity = gc.getPromotionInfo(iAffinity)
                       iMana = infoAffinity.getBonusPrereq()
                       for i in range(cf.getNumBonusEffective(iPlayer, iMana, pUnit)):
                           listWeightedAffinities.append(iAffinity)

               for i in range(iNumSpheres):
                   if len(listWeightedAffinities) > 0:
                       iAffinity = listWeightedAffinities.pop(CyGame().getSorenRandNum(len(listWeightedAffinities), "Affinity-Channeling2 "+ str(pUnit.getName())))
                       pUnit.setHasPromotion(iAffinity, True)
                       self.onUnitPromoted([pUnit, iAffinity])
In CustomFunctions.py
Code:
   def getUnitAlignment(self, pUnit, bCheckPromotions = True):
       if pUnit.getRace() == gc.getInfoTypeForString('PROMOTION_ANGEL'):
           return gc.getInfoTypeForString('ALIGNMENT_GOOD')
       elif pUnit.getRace() == [gc.getInfoTypeForString('PROMOTION_DEMON'), gc.getInfoTypeForString('PROMOTION_UNDEAD')]:
           return gc.getInfoTypeForString('ALIGNMENT_EVIL')
       iReligion = pUnit.getReligion()
       iAlignment = gc.getInfoTypeForString('ALIGNMENT_NEUTRAL')
       if iReligion == gc.getInfoTypeForString('RELIGION_CHILDREN_OF_THE_ONE'):
           return -1
       elif iReligion in [   gc.getInfoTypeForString('RELIGION_THE_ASHEN_VEIL'),
                           gc.getInfoTypeForString('RELIGION_COUNCIL_OF_ESUS'),
                           gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS'),
                           gc.getInfoTypeForString('RELIGION_WHITE_HAND')]:
           iAlignment = gc.getInfoTypeForString('ALIGNMENT_EVIL')
       elif iReligion in [   gc.getInfoTypeForString('RELIGION_THE_ORDER'),
                           gc.getInfoTypeForString('RELIGION_THE_EMPYREAN'),
                           gc.getInfoTypeForString('RELIGION_RUNES_OF_KILMORPH')]:
           iAlignment = gc.getInfoTypeForString('ALIGNMENT_GOOD')
       elif iReligion == gc.getInfoTypeForString('RELIGION_CULT_OF_THE_DRAGON'):
           if pUnit.getCivilizationType() == gc.getInfoTypeForString('CIVILIZATION_KURIOTATES'):
               iAlignment = gc.getInfoTypeForString('ALIGNMENT_GOOD')
           elif pUnit.getCivilizationType() == gc.getInfoTypeForString('CIVILIZATION_SHEAIM'):
               iAlignment = gc.getInfoTypeForString('ALIGNMENT_EVIL')
           else:
               eTeam = gc.getTeam(pUnit.getTeam())
               if eTeam.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_EURABATRES')):
                   iAlignment = gc.getInfoTypeForString('ALIGNMENT_GOOD')
               elif eTeam.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_DRIFA')):
                   iAlignment = gc.getInfoTypeForString('ALIGNMENT_EVIL')
               elif eTeam.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_ACHERON')):
                   iAlignment = gc.getInfoTypeForString('ALIGNMENT_EVIL')
               elif not eTeam.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_THALATTH')):
                   iAlignment = -1

       if bCheckPromotions:

           lEvilProms = [
                           'PROMOTION_UNHOLY_TAINT',
                           'PROMOTION_VAMPIRE',
                           'PROMOTION_DEMON_POSSESSED',

                           'PROMOTION_INFERNAL_GRIMOIRE',
                           'PROMOTION_KANNAS_RING',

                           'PROMOTION_AFFINITY_DEATH',
                           'PROMOTION_DEATH1',
                           'PROMOTION_DEATH2',
                           'PROMOTION_DEATH3',

                           'PROMOTION_CHAOS2',
                           'PROMOTION_ENTROPY2',

                           'PROMOTION_BODY3',
                           'PROMOTION_CHAOS3',
                           'PROMOTION_DIMENSIONAL3',
                           'PROMOTION_FIRE3',
                           'PROMOTION_ICE3',
                           'PROMOTION_ENTROPY3',
                           'PROMOTION_MIND3',
                           'PROMOTION_SHADOW3'
                   ]
           for sProm in lEvilProms:
               if pUnit.isHasPromotion(gc.getInfoTypeForString(sProm)):
                   return gc.getInfoTypeForString('ALIGNMENT_EVIL')

       return iAlignment

Code:
   def getNumBonusEffective(self, iPlayer, iBonus, unit=-1):
       return gc.getPlayer(iPlayer).getNumAvailableBonuses(iBonus) + self.getNumSupplimentalMana(iPlayer, iBonus, unit)


   def getNumSupplimentalMana(self, iPlayer, iBonus, unit=-1):
       iNum = 0
       if gc.getBonusInfo(iBonus).isMana():
           if PyHelpers.PyGame().doesBuildingExist(gc.getInfoTypeForString('BUILDING_CRUCIBLE')):
               return 0
           iNum += self.getNumSupplimentalManaPlayer(iPlayer, iBonus)
           if unit != -1:
               iNum += self.getNumSupplimentalManaUnit(iBonus, unit)
       return iNum


   def getNumSupplimentalManaUnit(self, iBonus, unit):
       iNum = 0

       if gc.getUnitInfo(unit.getUnitType()).getPrereqAndBonus() == iBonus:
           iNum += 1

       pPlot = unit.plot()
       pArea = unit.area()
       iTeam = unit.getTeam()
       if iBonus == pPlot.getBonusType(iTeam):
           iNum += 5

       if unit.isHasPromotion(gc.getInfoTypeForString('PROMOTION_ADVENTURER')):
           if iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
               iNum += 1

       iRace = unit.getRace()
       if iRace != -1:
           if iRace == gc.getInfoTypeForString('PROMOTION_ELF'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum += 1
           elif iRace == gc.getInfoTypeForString('PROMOTION_DWARF'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum -= 1
           elif iRace == gc.getInfoTypeForString('PROMOTION_UNDEAD'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum -= 1
           elif iRace == gc.getInfoTypeForString('PROMOTION_DEMON'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ENCHANTMENT'):
                   iNum -= 1
           elif iRace == gc.getInfoTypeForString('PROMOTION_ANGEL'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum -= 1



       iRel = unit.getReligion()
       if iRel != -1:
           if iRel == gc.getInfoTypeForString('RELIGION_THE_ORDER'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_THE_EMPYREAN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_RUNES_OF_KILMORPH'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_FELLOWSHIP_OF_LEAVES'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_WATER'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_COUNCIL_OF_ESUS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_THE_ASHEN_VEIL'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_CULT_OF_THE_DRAGON'):
               pPlayer = gc.getPlayer(unit.getOwner())
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   if CyGame().getUnitCreatedCount(gc.getInfoTypeForString('UNIT_EURABATRES')):
                       iNum += 1
                       if pPlayer.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_EURABATRES')):
                           iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   if CyGame().getUnitCreatedCount(gc.getInfoTypeForString('UNIT_ABASHI')):
                       iNum += 1
                       if pPlayer.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_ABASHI')):
                           iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   if CyGame().getUnitCreatedCount(gc.getInfoTypeForString('UNIT_ACHERON')):
                       iNum += 1
                       if pPlayer.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_ACHERON')):
                           iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   if CyGame().getUnitCreatedCount(gc.getInfoTypeForString('UNIT_DRIFA')):
                       iNum += 1
                       if pPlayer.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_DRIFA')):
                           iNum += 2
               elif iBonus in [gc.getInfoTypeForString('BONUS_MANA_WATER'), gc.getInfoTypeForString('BONUS_MANA_MIND')]:
                   if CyGame().getUnitCreatedCount(gc.getInfoTypeForString('UNIT_THALATTH')):
                       iNum += 1
                       if pPlayer.getUnitClassCount(gc.getInfoTypeForString('UNITCLASS_THALATTH')):
                           iNum += 2
           elif iRel == gc.getInfoTypeForString('RELIGION_WHITE_HAND'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum -= 2

           elif iRel == gc.getInfoTypeForString('RELIGION_CHILDREN_OF_THE_ONE'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FORCE'):
                   iNum += 3
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum += 1


       return iNum

   def getNumSupplimentalManaPlayer(self, iPlayer, iBonus):
       iNum = 0
       pPlayer = gc.getPlayer(iPlayer)
       if gc.getBonusInfo(iBonus).isMana():

           if PyHelpers.PyGame().doesBuildingExist(gc.getInfoTypeForString('BUILDING_CRUCIBLE')):
               return 0

           if pPlayer.isBarbarian():
               return CyMap().getNumBonuses(iBonus)

           if pPlayer.isFullMember(gc.getInfoTypeForString('DIPLOVOTE_OVERCOUNCIL')):
               if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DEATH_MANA')):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                       return -pPlayer.getNumAvailableBonuses(iBonus)
               if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_DIMENSIONAL_MANA')):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                       return -pPlayer.getNumAvailableBonuses(iBonus)
               if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_ENTROPY_MANA')):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                       return -pPlayer.getNumAvailableBonuses(iBonus)
               if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_CHAOS_MANA')):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                       return -pPlayer.getNumAvailableBonuses(iBonus)
               if CyGame().isVotePassed(gc.getInfoTypeForString('VOTE_NO_SHADOW_MANA')):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                       return -pPlayer.getNumAvailableBonuses(iBonus)



           iLeader = pPlayer.getLeaderType()
           if iLeader == gc.getInfoTypeForString('LEADER_ALEXIS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum -= 2
           elif iLeader == gc.getInfoTypeForString('LEADER_AMELANCHIER'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_ANAGANTIOS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_ARENDEL'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_ARTURUS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_AURIC'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_METAMAGIC'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_AVERAX'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_BASIUM'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum += 3
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FORCE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_BEERI'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENCHANTMENT'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_BRAEDEN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_WATER'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_CAPRIA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_CARDITH'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_CASSIEL'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FORCE'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_CHARADON'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_DAIN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_METAMAGIC'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_DECIUS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_DUIN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_DUMANNIOS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_EINION'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_METAMAGIC'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_ETHNE'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_LIFE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_FAERYL'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_FALAMAR'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_WATER'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_FLAUROS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_FURIA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_GARRIM'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENCHANTMENT'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_GOSEA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_HANNAH'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_WATER'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_HAFGAN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_HYBOREM'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 3
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_JONAS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_JUDECCA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_KANE'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_KANDROS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_KEELYN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_KOUN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_LETHE'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum -= 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum -= 1
           elif iLeader == gc.getInfoTypeForString('LEADER_MALCHAVIC'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FORCE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_MAHALA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENCHANTMENT'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_MAHON'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_MELISANDRE'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_MERESIN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_OS-GABELLA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 3
           elif iLeader == gc.getInfoTypeForString('LEADER_OSTANES'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_OUZZA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_PERPENTACH'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_METAMAGIC'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_RHOANNA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_RIUROS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_RIVANNA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_SABATHIEL'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FORCE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_SALLOS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_SANDALPHON'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 2
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_SHEELBA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_SHEKINAH'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_METAMAGIC'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_STATIUS'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_TASUNKE'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_TEBRYN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ENCHANTMENT'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_TETHIRA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_THESSA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 2
           elif iLeader == gc.getInfoTypeForString('LEADER_THESSALONICA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FORCE'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_TYA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_ULDANOR'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_VALLEDIA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_METAMAGIC'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 1
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum -= 1
           elif iLeader == gc.getInfoTypeForString('LEADER_VARN'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                   iNum += 2
               elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum -= 2
           elif iLeader == gc.getInfoTypeForString('LEADER_VOLANNA'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1
           elif iLeader == gc.getInfoTypeForString('LEADER_WEEVIL'):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1


           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_FALLOW')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                   return -pPlayer.getNumAvailableBonuses(iBonus)
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_HYBOREM')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 1
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_JUDECCA')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 1
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_LETHE')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SPIRIT'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                   iNum += 1
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_MERESIN')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DEATH'):
                   iNum += 1
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_OUZZA')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                   iNum += 1
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_STATIUS')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_DIMENSIONAL'):
                   iNum += 1
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_SALLOS')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_BODY'):
                   iNum += 1
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_MIND'):
                   iNum += 1
           if pPlayer.hasTrait(gc.getInfoTypeForString('TRAIT_PACT_WITH_WINTER')):
               if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                   iNum += 1

           iStateRel = pPlayer.getStateReligion()
           if iStateRel != -1:
               if iStateRel == gc.getInfoTypeForString('RELIGION_THE_ORDER'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_LAW'):
                       iNum += 1
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CHAOS'):
                       iNum -= 2

               elif iStateRel == gc.getInfoTypeForString('RELIGION_THE_EMPYREAN'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                       iNum += 2
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                       iNum -= 1

               elif iStateRel == gc.getInfoTypeForString('RELIGION_RUNES_OF_KILMORPH'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_EARTH'):
                       iNum += 1
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_AIR'):
                       iNum -= 2

               elif iStateRel == gc.getInfoTypeForString('RELIGION_FELLOWSHIP_OF_LEAVES'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                       iNum += 1
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                       iNum -= 2

               elif iStateRel == gc.getInfoTypeForString('RELIGION_OCTOPUS_OVERLORDS'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_WATER'):
                       iNum += 1
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_FIRE'):
                       iNum -= 2

               elif iStateRel == gc.getInfoTypeForString('RELIGION_COUNCIL_OF_ESUS'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_SHADOW'):
                       iNum += 1
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_SUN'):
                       iNum -= 2

               elif iStateRel == gc.getInfoTypeForString('RELIGION_THE_ASHEN_VEIL'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_ENTROPY'):
                       iNum += 1
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_CREATION'):
                       iNum -= 2

               elif iStateRel == gc.getInfoTypeForString('RELIGION_WHITE_HAND'):
                   if iBonus == gc.getInfoTypeForString('BONUS_MANA_ICE'):
                       iNum += 1
                   elif iBonus == gc.getInfoTypeForString('BONUS_MANA_NATURE'):
                       iNum -= 2

       return iNum



Each spell type is added to a list.

A spell is removed from the list if the player belongs to a council that has banned the associated mana type.

Undeath is removed from units belonging to Good civs or which themselves are considered good. Arawn's moral Death is removed from the list if the unit or its owner are evil. Neutral units of neutral players can still get either.

Angels are always good, demons and undead are always evil. Units of evil religions are evil. Units of good religions are good (unless they have promotions that make them evil, but for some reason I have it set up to ignore those promotions in this instance).

Arawn's Death agic is added back and Undeath is removed for the Sidar or Grey race units regardless of alignment or council votes.

A new list is populated in which each item in the previous list appears once for every source of effective mana. That includes real mana sources and modifiers for leader type, state religion type, unit religion type, and a bonus present on the unit's tile.

The game then randomly choses a promotion from the list to grant the unit. Occasionally it randomly chooses to apply a second promotion too.

Unholy Taint will change Death to Undeath. Druidic will change Undeath back to Death, if the unit is not evil. Acquiring any Undeath promotion will change any Death promotion to the equivalent Undeath, but Undeath and Death promotions block each other in xml so you cannot purchase it ith xp and must get the promotion in python somehow (such as throuh the Infernal Grimoire or upon upgrading and having new affinities applied) for this to matter.
 
It is kind of annoying that great persons change to different great persons when they are captured, but that is a vanilla BtS thing I don't know how to change.
This sounds like something that should be fixed in MNAI.

If you want me to, I can try messing around with my copy of MagisterModMod and do it myself. IIRC, I managed to do it very seamlessly years ago by doing some copying around and some rough play testing just to make sure nothing's broken, so it should be easy enough.
Adding a new Era shouldn't be hard by copying another era entry and modifying it. However, the latest MNAI-U does the Religion-Era thing a bit different then vanilla FfH: in your religion, you want the <PseudoEra> tag to point to your new era. The era itself should have <bRealEra>0</bRealEra>, like the other religion-eras. The python code to switch eras on religion change is gone.
 
That sounds like a great strategy for Runes of Kilmorph, but what about for Empyrean?
I thought that was the one Malakim usually went for? Not that they have to, but if we researched to get Honor and Rathas as fast as possible, building unit for defense or early attacks is challenging, unless I missed something. We could still do "Aristoagrarianism paired with Apprenticeship" and build workshops just like you pointed out, just no Arete. Guilds would be too late for an early rush. I do usually play Varn. I'll try Kane next time.
 
Adding an era is not itself hard, but adding the art etc associated with an era can get complicated. Improvements like farms will have no graphics at all unless you make all the proper adjustments to C:\Program Files (x86)\Firaxis Games\Sid Meier's Civilization 4\Beyond the Sword\Mods\Magister Modmod for FfH2\Assets\XML\Buildings\CIV4PlotLSystem.xml, which is probably the easiest xml file to mess up.

I just tried to download Orbis just to get a look at what sort of art they used for the White Hand, but the download link seems to be broken. I'd rather be able to see screenshots of how things look in their Hand Era before trying to see if I can find the full download somewhere else.
 
@plasmacannon: If you go with Empyrean instead of Runes, you'll simply have 3 :hammers: Desert Hill Mines, and Workshops won't be as :commerce:-yielding, though it won't matter much. Just when you settle cities in the desert, keep an eye out for hill and flood plains tiles, and in general keep Agriculture, Mining, Education + Construction, Code of Laws, Sanitation, Smithing, Medicine, and Guilds at high priority, in that order preferably. Maybe Blasting Powder too, if you have lots of Mines, but that's pretty late game tech, even compared to guilds.

@MagisterCultuum: Thanks for the rundown. Can the Overcouncil resolution be changed to merely ban the practice of undeath? I feel it'll be a hassle to do such a thing, but it'd be good to know.

Also, here's where you can download Orbis.

EDIT: As a quick note, I dug into the PlotLSystem of Orbis, and I couldn't find any unique artwork for the Hand religion. A shame, really.
 
Last edited:
Thematically it makes sense for the Overcouncil to ban Death mana. It is canon that most people do not understand the difference between good and evil forms of death magic, so moral practitioners are often prosecuted for the crimes of necromancers. I have the Overcouncil resolution changing Undeath promotion to Arawn death promotions, but also negating sources of the mana so only the Sidar or leaders like Thessa who have supplimental death mana would ever be granted such affinities.


I too looked through Orbis and did not find any special Hand artwork. I really don't see that the Hand era does anything but change some songs. I am not terribly impressed with their song choices and including the files they use would just about double the download size. I made an era using select songs already in the game, a mix of those from other religions' eras that seemed most appropriate.

Orbis uses the same mana node artwork for the Hand as the Order, Empyrean, and Medieval era. I never really liked that artwork. In terms of node artwork I'd say that Fellowship of the Leaves > Octopus Overlords > Ashen Veil > Ancient > Runes of Kilmorph > Order/Empyrean/Council of Esus/Medieval era.

I'm thinking of using the Overlords node art for the Council of Esus too.

Of the node art in the game the Ancient version is still the most fitting for the Hand. I just tried to make Hand mana nodes look like a scaled down Letum Frigus instead, but that is causing the game to crash. Trying to use Bradeline's Well (which might fit the Council of Esus better) does the same. I would guess that those models' .nif files are not compatible with the KFM:Art/Structures/Improvements/node/mine.kfm file the nodes all use. Not including a KFM also causes crashes.




---

I'm thinking of giving priests a small chance of being gifted affinity in their religion's primary mana type. Does 1% per effective mana supply in that mana type sound appropriate? That would mean if you control 100 source of Nature mana all your Priests of the Leaves are certain to be able to cast Bloom Greater, but in most games those who were gifted by their god would be muhc more rare than that.
 
Last edited:
Admittedly, Orbis is one of the much older modmods for FFH2 out there. It's not updated since idk, 2010? 2011? Of all the modmods out there, afaik Ashes of Erebus (a continuation of Rise From Erebus) and your modmod are the only ones updated to a regular basis. You could see what Ashes does as a reference, but you're also free to ignore it; apparently even it doesn't have any White Hand improvement art.

I'm thinking of giving priests a small chance of being gifted affinity in their religion's primary mana type. Does 1% per effective mana supply in that mana type sound appropriate? That would mean if you control 100 source of Nature mana all your Priests of the Leaves are certain to be able to cast Bloom Greater, but in most games those who were gifted by their god would be muhc more rare than that.

Go for it. Some would say it'd make priests overlap slightly with mages, but IMO they can easily be differentiated with Divine + Affinity giving a slightly different set of toys to play with than Channeling + Affinity.
 
Last edited:
Sounds fine, would make priests a bit more viable to spend hammers on relative to churning out Adepts, and 1% is unlikely to get too snowbally until the game's already won.
 
I'd also think it's ok.
Maybe more than 1 % ?
usually you won't get more than 3-4 mana nodes of a type until end game when you start having str affinity summons /units
I'd say that 1 priest out of 10 would be a reasonnable affinity win. so 2-3% per mana of the primary type ?

other random ideas based on your initial input:
Maybe make it that the Malakim U-spell gives a +10%chances of affinity just during spell creation ?
Maybe spiritual could boost affinity appearance for priests ?(+5%)


BTW : I'm really bummed that PoL cannot cast bloom anymore, and that Bloom (nature2) needs now 3 turns.
 
I currently have it coded so that any Disciple units with a religion prereq can get affinity in their religion's patron sphere, based on the effective supply of that mana.

The base rate for Priests is 1% per effective mana supply. For basic Disciples it is only 0.2% per effective mana supply. For High Priests it is 5% per effective mana supply, and those who get affinity also get Channeling 3 so they can use Archmage level spells.

Note that effective supply takes into account the leader specific bonuses, the owner's state religion, unit's religion, and unit's race.

I also made it so that the Zeal promotion (from the Spiritual trait) and the Eremite promotion (from the Malakim Desert Shrine) double the chance of getting disciple religious affinity.

If you are playing as the Ljosalfar with Fellowship of the Leaves as your state religion and you train a Priest of the Leaves, your effective Nature mana supply equals your real nature mana supply +1 for your state religion, +1 for the unit's religion, +1 for the Elven race. Arendel and Thessa also get a bonus of +2, and Amelancheir of +1 Nature mana.

Arendel Phaedra also has the Spiritual trait, so her priests get Zeal and double their chance of having affinity. With only the Nature mana from the Ljosalfar Palace, Arendel Phaedra's Priests of the Leaves would get Nature Affinity 12% of the time and her High Priests of the Leaves would get affinity 60% of the time.


Monks may gain Spirit Affinity at the same rate as Priests would get affinity for their god's sphere.

Counselors now start with Spirit 1, 2, & 3 instead of the Spirit Affinity promotion, but the unit itself still has as much affinity for Spirit and there is a 10% chance per effective source of Spirit mana of being granted the Spirit Affinity and Channeling 3 promotions.

Bhall-Orcs no longer require the Eternal Flame in order to build. They no longer start with the Fire Affinity promotion, but have 1 Fire affinity in their unit defines and start with Fire 1 & 2. They may gain the Fire Affinity promotion at the same rate as Monks or Priests would get affinity for their god's sphere. Being trained in a city with the Eternal Flame makes getting affinity 10x as likely.


The Bloom 3 and Bloom 3 Greater spells (the ones that make Forests into Ancient Forests) now both require the unit to have the Fellowship of the Leaves religion, but there is no State Religion prereq.

I just reduced the delay for Bloom (the basic version that only makes New Forests) back down to 2 turns. Bloom 2 (turning New Forests to Forests) takes 3 turns and Bloom 4 (turning Forests to Ancient Forests) takes 4 turns.

---

I just changed the Kidnap spell from being a Svartalfar Recon ability to being a Council of Esus priest spell, requiring Divine and Council of Esus as both unit and state religion. I made it cause a diplomatic penalty, but not cause a declaration of war.

The Embezzle ability can be used by Agents of Esus without any state religion. It no longer has any building prereqs, but the amount of gold it can steal is increased by Aphotic Throne, Gambling Rings, and Smuggler's Ports in the city.

The Svartalfar's Unseelie Shadows now have Divine instead of Evangelist. They can use all of the Agent of Esus abilities. The Svartalfar have to actually convert to Esus and level up their Agents of Esus to get a disciple with Evangelist in order to use the Initiate into Esus ability.
 
Last edited:
interesting.
does the Zeal promotion having an effect on getting affinity to the mana mean that you have a specific code checking on _unit_creation the existence or absence of Zeal & Emerite before applying the affinity odds ?
 
Top Bottom