diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff8674a --- /dev/null +++ b/.gitignore @@ -0,0 +1,144 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ +output/*.dm +log.txt +magicgen/ +magicgen.zip + +# pycharm things +.idea/ +outputs/ + +# Nuitka leftovers +*.exe +*.dll + +blessgen*.zip +*.dbm \ No newline at end of file diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..22d660a --- /dev/null +++ b/Pipfile @@ -0,0 +1,11 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] + +[dev-packages] + +[requires] +python_version = "3.8" diff --git a/blesseffect.py b/blesseffect.py new file mode 100644 index 0000000..f50f448 --- /dev/null +++ b/blesseffect.py @@ -0,0 +1,112 @@ +import re +import utils + +EFFECTS_REQURING_MONTAG_DUMMIES = [564, 164] + +class BlessEffect(object): + def __init__(self): + self.id = None + self.name = None + self.effects = {} + self.scales = {} + self.effect10buffs = 0 + self.multipick = 0 + self.alwaysactive = 0 + self.path1 = 0 + self.path2 = -1 + self.path1level = 0 + self.path2level = 0 + self.descr = "" + def processstring(self, string): + out = string + while 1: + m = re.search("\\[EFFECT(\\d*)\\]", out) + if m is not None: + effectID = int(m.group(1)) + effectMag = str(self.effects.get(effectID, "???")) + out = re.sub("\\[EFFECT\\d*\\]", effectMag, out, count=1) + continue + + m = re.search("\\[EFFECTTIMES25_(\\d*)\\]", out) + if m is not None: + effectID = int(m.group(1)) + if effectID in self.effects: + effectMag = str(self.effects.get(effectID)*25) + else: + effectMag = "???" + out = re.sub("\\[EFFECTTIMES25_\\d*\\]", effectMag, out, count=1) + continue + + m = re.search("\\[EFFECTDIV10_(\\d*)\\]", out) + if m is not None: + effectID = int(m.group(1)) + if effectID in self.effects: + effectMag = str(round(self.effects.get(effectID) / 10, 1)) + else: + effectMag = "???" + out = re.sub("\\[EFFECTDIV10_\\d*\\]", effectMag, out, count=1) + continue + + break + return out + def _prepareMonsterDummy(self, effectMag): + + s = """ +#newmonster {} +#copystats 284 +#copyspr 284 +#firstshape {} +#secondshape {} +#regeneration -999 +#landdamage 100 +#uwdamage 100 +#drawsize -99 +#woundfend 99 +#hp 1 +#amphibian +#mr 15 +#itemslots 262143 +#name "{}" +#descr "This unit has no purpose except to spawn in a unit of montag {}." +#end + +""" + s = s.format(utils.START_UNIT_ID, effectMag, effectMag, f"Dummy Montag {effectMag}", effectMag) + utils.START_UNIT_ID += 1 + return s + def output(self): + if len(self.name) < 31 and self.multipick: + self.name += "*" + out = f"#selectbless {utils.START_BLESS_ID}\n" + out += f"#clear\n" + if self.name is None: + self.name = f"Unnamed Bless {utils.START_BLESS_ID}" + out += f'#name "{self.processstring(self.name)}"' + "\n" + out += f'--#descr "{self.processstring(self.descr)}' + if self.alwaysactive: + out += " This effect does not require sacred units to be blessed." + out += '"' + out += "\n" + utils.START_BLESS_ID += 1 + out += f"#path1 {self.path1}\n" + out += f"#path2 {self.path2}\n" + out += f"#path1level {self.path1level}\n" + out += f"#path2level {self.path2level}\n" + if self.effect10buffs > 0: + out += f"#effect10buffs {self.effect10buffs}\n" + if self.multipick: + out += "#multipick\n" + if self.alwaysactive: + out += "#alwaysactive\n" + for effect, effectMag in self.effects.items(): + # This would work, if .dm commands were also valid in .dbm files + # potentially useful, but needs converting to write an accompanying .dm file + #if effect in EFFECTS_REQURING_MONTAG_DUMMIES and effectMag < 0: + # out = self._prepareMonsterDummy(effectMag) + out + # effectMag = utils.START_UNIT_ID - 1 + out += f"#addeffect {effect} {effectMag} -- {utils.EFFECT_IDS_TO_LABELS.get(effect, 'Unknown Effect')}\n" + for scale, scaleMag in self.scales.items(): + if scaleMag != 0: + out += f"#reqscale {scale} {int(scaleMag)}\n" + out += "#end\n\n" + return out \ No newline at end of file diff --git a/blessgen.py b/blessgen.py new file mode 100644 index 0000000..f3175bf --- /dev/null +++ b/blessgen.py @@ -0,0 +1,160 @@ +import utils +import fileparser +import random +import copy +import sys +import os +import traceback +from blessgenerationsettings import BlessGenerationSettings + +ver = "1.0.0" + +def _parseDataFiles(): + if len(utils.blesseffects) < 0: + return + utils.loadEffectLabels() + return fileparser.blesstemplate.readEffectsFromDir("./data/blesseffects") + +class BlessGenerator(object): + def __init__(self, **options): + self.blessEffectPool = _parseDataFiles() + self.options = options + self.numToGenerate = options.get("numtogenerate", 99) + self.blessEffectsByPath = {} + self.blessEffectsByCrosspath = {} + self.crosspathChance = options.get("crosspathchance", 20) + self.modoutput = "" + self.combinationTolerance = 0 + + for path in range(0, 8): + self.blessEffectsByPath[path] = {} + for level in range(1, 11): + self.blessEffectsByPath[path][level] = [] + for crossPath in range(path+1, 8): + crossPathSet = frozenset((path, crossPath)) + self.blessEffectsByCrosspath[crossPathSet] = [] + + self._cachedCombinationPool = None + self._lastLowestEffectCount = None + + def _buildRarestCombinationPool(self): + lowestEffectCount = None + pathAndLevelCombinationPool = [] + # Work out what the lowest number of effects for all combos is + for path, pathsBlessEffectsByLevel in self.blessEffectsByPath.items(): + for level, blessList in pathsBlessEffectsByLevel.items(): + numEffects = len(blessList) + if level < 5: + numEffects -= 1 + if lowestEffectCount is None or numEffects < lowestEffectCount: + lowestEffectCount = numEffects + for crossPathSet, spellList in self.blessEffectsByCrosspath.items(): + numEffects = len(blessList) + if numEffects < lowestEffectCount: + lowestEffectCount = numEffects + if self._lastLowestEffectCount is not None and lowestEffectCount != self._lastLowestEffectCount: + print(f"New lowest effect count = {lowestEffectCount} (old was {self._lastLowestEffectCount}), reset tolerance") + self.combinationTolerance = 0 + + # Now select anything within the given tolerance + for path, pathsBlessEffectsByLevel in self.blessEffectsByPath.items(): + for level, blessList in pathsBlessEffectsByLevel.items(): + numEffects = len(blessList) + # Give more non-incarnate effects + if level < 5: + numEffects -= 1 + if numEffects - lowestEffectCount <= self.combinationTolerance: + combo = BlessGenerationSettings(path, None, level) + pathAndLevelCombinationPool.append(combo) + for crossPathSet, spellList in self.blessEffectsByCrosspath.items(): + numEffects = len(blessList) + if numEffects - lowestEffectCount <= self.combinationTolerance: + combo = BlessGenerationSettings(*list(crossPathSet), None) + pathAndLevelCombinationPool.append(combo) + combo = BlessGenerationSettings(*reversed(list(crossPathSet)), None) + pathAndLevelCombinationPool.append(combo) + self._cachedCombinationPool = pathAndLevelCombinationPool + random.shuffle(self._cachedCombinationPool) + self._lastLowestEffectCount = lowestEffectCount + print(f"Possible path combination pool contains {len(self._cachedCombinationPool)} items!") + + def selectBlessSettings(self): + if self._cachedCombinationPool is None: + self._buildRarestCombinationPool() + if len(self._cachedCombinationPool) == 0: + self.combinationTolerance += 1 + self._buildRarestCombinationPool() + if self.combinationTolerance > 5: + raise ValueError("Failed to build an effect from the least common path/level combination pool") + settings = self._cachedCombinationPool.pop() + return settings + + def generateBless(self, settings): + print(f"Generate bless with settings: {settings}... ({len(self._cachedCombinationPool)} remain)") + attempt = 1 + bless = None + while 1: + effectPool = copy.copy(list(self.blessEffectPool.values())) + random.shuffle(effectPool) + settings.allowskipchance = attempt < 2 + while 1: + if len(effectPool) == 0: + break + effect = effectPool.pop() + if attempt == 1 and random.random() * 100 < effect.skipchance: + continue + print(f"Try effect {effect.name}... ({len(effectPool)} remain)") + bless = effect.generateBless(settings) + if bless is not None: + break + if bless is not None: + break + if attempt >= 2: + return False + attempt += 1 + + if bless is not None: + if bless.path2 == -1: + self.blessEffectsByPath[bless.path1][bless.path1level].append(bless) + else: + crosspathset = frozenset((bless.path1, bless.path2)) + self.blessEffectsByCrosspath[crosspathset].append(bless) + self.modoutput += bless.output() + return True + + def generateAll(self): + for x in range(0, self.numToGenerate): + while 1: + settings = self.selectBlessSettings() + if self.generateBless(settings): + break + +def main(**options): + utils.START_UNIT_ID = options.get("startunitid", 3501) + gen = BlessGenerator(**options) + gen.generateAll() + outfp = options.get("outfp", None) + if outfp is None: + outfp = f"blessgen-{random.random()}.dbm" + if not outfp.endswith(".dbm"): + outfp += ".dbm" + with open(os.path.join("./output", os.path.basename(outfp)), "w", encoding="utf-8") as f: + f.write(gen.modoutput) + + +if __name__ == "__main__": + n = input("Enter mod name:") + oldstdout = sys.stdout + log = open("log.txt", "w", encoding="u8") + sys.stdout = log + if len(n) == 0: + n = None + try: + main(outfp=n) + except Exception: + print(traceback.format_exc()) + sys.stdout = oldstdout + oldstdout.write(traceback.format_exc()) + input("Failed. Press ENTER to exit.") + sys.stdout = oldstdout + input("Complete! Press ENTER to exit.") diff --git a/blessgenerationsettings.py b/blessgenerationsettings.py new file mode 100644 index 0000000..6af4a0c --- /dev/null +++ b/blessgenerationsettings.py @@ -0,0 +1,11 @@ + + +class BlessGenerationSettings(object): + def __init__(self, path1, path2, level): + self.blesspointcost = level + self.primarypath = path1 + self.secondarypath = path2 + self.allowskipchance = True + def __repr__(self): + return(f"BlessSettings(path1={self.primarypath}, path2={self.secondarypath}, " + f"blesspts={self.blesspointcost})") \ No newline at end of file diff --git a/blesstemplate.py b/blesstemplate.py new file mode 100644 index 0000000..56b7d11 --- /dev/null +++ b/blesstemplate.py @@ -0,0 +1,217 @@ +import random +from blesseffect import BlessEffect + +class BlessTemplate(object): + def __init__(self, name): + self.name = name + self.paths = 0 + self.pathlevel = 0 + self.effect10buffs = 0 + self.multipick = 0 + self.alwaysactive = 0 + self.reqcrosspath = 0 + self.names = {} + self.skipchance = 0 + self.descr = "" + self.effects = {} + self.scaleeffects = {} + self.posscaleaffinities = {} + self.negscaleaffinities = {} + self.maxeffectvalues = {} + self.generations = [] + def generateBless(self, settings): + self.settings = settings + self.blessobj = BlessEffect() + if settings.allowskipchance and len(self.generations) > 0: + return None + if not self._canGenerate(): + return None + self._assignEffectPaths() + if self.blessobj.path1 in self.generations: + print(f"Effect has already generated for this path") + return None + self.finalpowerlevel = self._determineFinalPowerlevel() + if self.finalpowerlevel is None: + return None + if not self._determinePathLevels(): + return None + if not self._scaleToBlesspointCost(): + return None + self._assignNameToBless() + self._assignScalesToBless() + self.generations.append(self.blessobj.path1) + return self.blessobj + def _assignScalesToBless(self): + for scale, aff in self.posscaleaffinities.items(): + amt = aff // 100 + if aff > 0: + self.blessobj.scales[scale] = amt * -1 + for scale, aff in self.negscaleaffinities.items(): + amt = aff // 100 + if aff > 0: + self.blessobj.scales[scale] = amt + def _assignEffectPaths(self): + if self.settings.primarypath is not None: + self.blessobj.path1 = self.settings.primarypath + if self.settings.secondarypath is not None: + self.blessobj.path2 = self.settings.secondarypath + def _assignNameToBless(self): + if 2**self.blessobj.path1 not in self.names: + raise ValueError(f"Bless {self.name} is missing a name for path {self.blessobj.path1}") + self.blessobj.name = random.choice(self.names[2**self.blessobj.path1]) + def _determineAllowedPathLevelsAtPowerLevel(self, powerlevel): + if self.settings.secondarypath is None: + if not self.reqcrosspath: + if self.settings.primarypath is not None: + self.blessobj.path1level = powerlevel + if self._validatePowerLevelAndPathSelection(powerlevel): + return [(powerlevel, None)] + else: + print(f"Failed to generate: primary path only is not valid at given power level") + return [] + else: + print(f"Failed to generate: no primary path supplied") + return [] + else: + print(f"Failed to generate: this effect requires a crosspath") + return [] + else: + out = [] + totalpts = (powerlevel ** 1.2) + maxdivert = (totalpts // 2) + possiblediverts = list(range(1, int(maxdivert) - 1)) + for todivert in possiblediverts: + divertedpts = todivert ** 1.2 + remainingpts = totalpts - divertedpts + # Check to make sure that this isn't a better outcome than the next check + # IE: 9 -> 8+1 shouldn't happen when 9 -> 8+2 is possible + self.blessobj.path1level = int(round(remainingpts ** (1 / 1.2))) + self.blessobj.path2level = int(round(divertedpts ** (1 / 1.2))) + print(f"Try diverting {todivert}: uses {divertedpts}, leaves {remainingpts}...") + print(f"Results in path1lvl = {self.blessobj.path1level}, path2lvl = " + f"{self.blessobj.path2level}") + if todivert != possiblediverts[-1]: + nextremaining = totalpts - ((todivert + 1) ** 1.2) + if int(round(remainingpts ** (1/1.2))) == int(round(nextremaining ** (1/1.2))): + print(f"Invalid. Path1lvl matches that of the next split!") + continue + + if self.blessobj.path1level > 10: + print(f"Invalid. Results in 11+ path1lvl") + elif self.blessobj.path2level > 10: + print(f"Invalid. Results in 11+ path2lvl") + elif self.blessobj.path1level >= powerlevel: + print(f"Invalid. Results in path1lvl greater than or equal to value before split") + continue + elif self.blessobj.path2level > self.blessobj.path1level: + print(f"Invalid. Results in path2lvl > path1lvl") + continue + elif self._validatePowerLevelAndPathSelection(powerlevel): + print(f"Valid!") + out.append((self.blessobj.path1level, self.blessobj.path2level)) + else: + print(f"Invalid: didn't pass power level + path check.") + return out + def _determinePathLevels(self): + possibilities = self._determineAllowedPathLevelsAtPowerLevel(self.finalpowerlevel) + if len(possibilities) == 0: + return False + random.shuffle(possibilities) + real = possibilities[0] + self.blessobj.path1level = real[0] + if real[1] is None: + self.blessobj.path2level = 0 + else: + self.blessobj.path2level = real[1] + return True + + + def _canGenerate(self): + if len(self.scaleeffects) == 0: + if self.settings.blesspointcost is not None and self.pathlevel != self.settings.blesspointcost: + print(f"Fail to generate: no way to reach desired blesspoint cost {self.settings.blesspointcost}") + return False + if self.settings.blesspointcost is not None and self.pathlevel > self.settings.blesspointcost: + print(f"Fail to generate: this effect is too expensive for {self.settings.blesspointcost} blesspoints") + return False + if self.settings.primarypath is not None and self.paths & (2**self.settings.primarypath) == 0: + print(f"Fail to generate: missing primary path {self.settings.primarypath}") + return False + if self.settings.secondarypath is not None and self.paths & (2**self.settings.secondarypath) == 0: + print(f"Fail to generate: missing secondary path {self.settings.primarypath}") + return False + return True + def _determineFinalPowerlevel(self): + if self.settings.blesspointcost is not None: + if len(self._determineAllowedPathLevelsAtPowerLevel(self.settings.blesspointcost)) > 0: + allowedpowerlevels = [self.settings.blesspointcost] + else: + return None + else: + allowedpowerlevels = [] + for powerLevel in range(1, 15): + print(f"Test at power level {powerLevel}...") + if len(self._determineAllowedPathLevelsAtPowerLevel(powerLevel)) > 0: + allowedpowerlevels.append(powerLevel) + if len(allowedpowerlevels) == 0: + print(f"Fail to generate: no valid power levels") + return None + ret = random.choice(allowedpowerlevels) + print(f"Final power level choices: {allowedpowerlevels} -> {ret}") + return ret + def _validatePowerLevelAndPathSelection(self, finalpowerlevel): + powerlevelOverBase = int(round(finalpowerlevel - self.pathlevel)) + if finalpowerlevel < self.pathlevel: + return False + if len(self.scaleeffects) == 0 and finalpowerlevel > self.pathlevel: + return False + + hasRealEffect = False + for effectID in self.effects: + if effectID in self.maxeffectvalues: + if abs(self._getEffectMagnitudeAtPowerLevel(effectID, finalpowerlevel)) > abs(self.maxeffectvalues[effectID]): + print(f"Exceeds maximum effect value of {self.maxeffectvalues[effectID]}, cannot generate " + f"at PL{finalpowerlevel}") + return False + + if self.scaleeffects.get(effectID, 0.0) > 0.0: + if self._getEffectMagnitudeAtPowerLevel(effectID, finalpowerlevel) != \ + self._getEffectMagnitudeAtPowerLevel(effectID, finalpowerlevel - 1): + print(f"Effect {effectID} has diff magnitude at powerlevels {finalpowerlevel} + {finalpowerlevel-1}") + hasRealEffect = True + + if len(self.scaleeffects) > 0 and not hasRealEffect: + print(f"Power level {finalpowerlevel} doesn't give this effect anything new") + return False + + if powerlevelOverBase < 0: + return False + # Cannot split a path level of 1 into two + if finalpowerlevel < 2 and self.settings.secondarypath is not None: + return False + return True + def _getEffectMagnitudeAtPowerLevel(self, effectID, finalpowerlevel): + powerlevelOverBase = int(round(finalpowerlevel - self.pathlevel)) + baseMagnitude = self.effects.get(effectID, 0.0) + scaleRate = self.scaleeffects.get(effectID, 0.0) + scaleMagnitude = scaleRate * powerlevelOverBase + # Extra bit for things turning incarnate that didn't use to be + if self.pathlevel < 5 and self.blessobj.path1level >= 5: + scaleMagnitude *= 1.2 + finalMagnitude = baseMagnitude + int(round(scaleMagnitude)) + + print(f"Effect: {effectID} with {baseMagnitude}") + print(f"+ scalerate {scaleRate} * extra levels {powerlevelOverBase}") + print(f" = final magnitude {finalMagnitude}") + return finalMagnitude + def _scaleToBlesspointCost(self): + for effectID, baseMagnitude in self.effects.items(): + finalMagnitude = self._getEffectMagnitudeAtPowerLevel(effectID, self.finalpowerlevel) + self.blessobj.effects[effectID] = finalMagnitude + self.blessobj.effect10buffs = self.effect10buffs + self.blessobj.multipick = self.multipick + self.blessobj.alwaysactive = self.alwaysactive + self.blessobj.descr = self.descr + return True + def __repr__(self): + return(f"BlessTemplate({self.name})") \ No newline at end of file diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..e4af219 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,3 @@ +v1.0.0 - 19/04/22 + +Initial upload \ No newline at end of file diff --git a/data/blesseffects/combat.txt b/data/blesseffects/combat.txt new file mode 100644 index 0000000..19bcb22 --- /dev/null +++ b/data/blesseffects/combat.txt @@ -0,0 +1,993 @@ +#newbless "Morale" +#name f "Morale +[EFFECT308]" +#name b "Morale +[EFFECT308]" +#paths f +#pathlevel 1 +#addeffect 308 1 +#scaleeffect 308 1.8 +#maxeffectvalue 308 10 +#multipick 1 +#end + +#newbless "Death Explosion" +#name f "Death Explosion AoE [EFFECT297], +10 FR" +#paths f +#pathlevel 4 +#addeffect 297 6 -- death explosion bless type +#addeffect 198 10 -- Fire res +#scaleeffect 297 1.5 +#maxeffectvalue 297 14 +#descr "The explosion does 10 AP fire damage. The area of effect of the explosion is [EFFECT297] + sacred size - 2." +#end + +#newbless "Attack Skill" +#name f "Attack Skill +[EFFECT150]" +#paths f +#pathlevel 3 +#addeffect 150 2 +#scaleeffect 150 0.9 +#maxeffectvalue 150 2 +#multipick 1 +#end + +#newbless "Strength" +#name eb "Strength +[EFFECT151]" +#paths eb +#pathlevel 1 +#addeffect 151 1 +#scaleeffect 151 1.2 +#maxeffectvalue 151 8 +#multipick 1 +#end + +#newbless "Defence Skill" +#name w "Defence Skill +[EFFECT377]" +#paths w +#pathlevel 4 +#addeffect 377 2 +#scaleeffect 377 0.9 +#maxeffectvalue 377 2 +#multipick 1 +#end + +#newbless "MR Bonus" +#name s "Magic Resistance +[EFFECT161]" +#paths s +#pathlevel 3 +#addeffect 161 2 +#scaleeffect 161 0.4 +#maxeffectvalue 161 3 +#multipick 1 +#end + +#newbless "MR Bonus 1 only" +#name s "Magic Resistance +1" +#paths s +#pathlevel 1 +#addeffect 161 1 +#end + + +#newbless "Penetration Bonus" +#name s "Magic Penetration +[EFFECT162]" +#paths s +#pathlevel 3 +#addeffect 162 1 +#scaleeffect 162 0.3 +#maxeffectvalue 162 2 +#multipick 1 +#end + +#newbless "Plague Carrier" +#name d "Disease Aura [EFFECT172] + Disease Immune" +#paths d +#pathlevel 5 +#addeffect 172 2 -- disease aura +#addeffect 513 100 -- disease resist +#scaleeffect 172 1 +#negscaleaffinity 3 100 +#maxeffectvalue 172 4 +#end + +#newbless "Disease Explosion" +#name d "Disease Explosion [EFFECT401] + Immunity" +#paths d +#pathlevel 5 +#addeffect 401 5 -- disease explosion +#addeffect 513 100 -- disease resist +#scaleeffect 401 1 +#negscaleaffinity 3 100 +#maxeffectvalue 401 9 +#end + + +-- #newbless "Storm Power" +-- #name a "Storm Power +[EFFECT174]" +-- #paths a +-- #pathlevel 6 +-- #addeffect 174 2 -- storm power +-- #scaleeffect 174 1 +-- #maxeffectvalue 174 10 +-- #end + +#newbless "Storm Immunity" +#name a "Storm Immunity" +#paths a +#pathlevel 4 +#addeffect 175 1 -- storm immunity +#end + +#newbless "Extra Eye" +#name s "[EFFECT178] Trueseeing Eyes" +#name b "Extra [EFFECT178] Eyes" +#paths s +#pathlevel 2 +#alwaysactive 1 +#addeffect 178 666 -- eyes +#addeffect 607 1 -- spirit sight +#end + +#newbless "Precision" +#name a "Precision +[EFFECT181]" +#paths a +#pathlevel 2 +#multipick 1 +#addeffect 181 3 -- prec +#scaleeffect 181 1.8 +#maxeffectvalue 181 20 +#end + +#newbless "Fear" +#name d "Fear +5" +#name b "Fear +5" +#paths db +#pathlevel 8 +#addeffect 183 5 +#end + +#newbless "Poison Barbs" +#name n "Poison Barbs +[EFFECT188]" +#paths n +#pathlevel 4 +#multipick 1 +#addeffect 188 5 +#scaleeffect 188 2 +#maxeffectvalue 188 20 +#end + +#newbless "Berserker" +#name n "Berserker +[EFFECT190]" +#paths n +#pathlevel 5 +#addeffect 190 2 +#scaleeffect 190 0.75 +#maxeffectvalue 190 10 +#end + +#newbless "Fire Resistance" +#name f "Fire Resistance +[EFFECT198]" +#paths f +#pathlevel 1 +#addeffect 198 1 +#scaleeffect 198 1.2 +#maxeffectvalue 198 5 +#multipick 1 +#end + +#newbless "Cold Resistance" +#name w "Cold Resistance +[EFFECT201]" +#paths w +#pathlevel 1 +#addeffect 201 1 +#scaleeffect 201 1.2 +#maxeffectvalue 201 5 +#multipick 1 +#end + +#newbless "Shock Resistance" +#name a "Shock Resistance +[EFFECT199]" +#paths a +#pathlevel 1 +#addeffect 199 1 +#scaleeffect 199 1.2 +#maxeffectvalue 199 5 +#multipick 1 +#end + +#newbless "Poison Resistance" +#name n "Poison Resistance +[EFFECT200]" +#paths n +#pathlevel 1 +#addeffect 200 1 +#scaleeffect 200 1.2 +#maxeffectvalue 200 5 +#multipick 1 +#end + +#newbless "All Resistance" +#name n "All Resistances +[EFFECT200]" +#paths n +#pathlevel 4 +#addeffect 198 2 +#addeffect 199 2 +#addeffect 200 2 +#addeffect 201 2 +#scaleeffect 198 0.5 +#scaleeffect 199 0.5 +#scaleeffect 200 0.5 +#scaleeffect 201 0.5 +#maxeffectvalue 200 20 +#multipick 1 +#end + +#newbless "Damage Reversal" +#name b "Damage Reversal" +#paths b +#pathlevel 10 +#addeffect 202 1 +#end + +#newbless "Air Shield" +#name a "Air Shield +[EFFECT208]%" +#paths a +#pathlevel 2 +#addeffect 208 30 +#scaleeffect 208 15 +#maxeffectvalue 208 80 +#multipick 1 +#end + +#newbless "Chill Aura" +#name w "Chill Aura +[EFFECT220], +10 Cold Res" +#paths w +#pathlevel 5 +#addeffect 220 3 +#addeffect 201 10 +#scaleeffect 220 2 +#maxeffectvalue 220 6 +#multipick 1 +#end + +#newbless "Heat Aura" +#name f "Heat Aura +[EFFECT316], +10 Fire Res" +#paths f +#pathlevel 5 +#addeffect 316 3 +#addeffect 198 10 +#scaleeffect 316 2 +#maxeffectvalue 316 6 +#multipick 1 +#end + +#newbless "Banefire Shield" +#name fd "Banefire Shield +[EFFECT222]" +#reqcrosspath 1 +#paths fd +#pathlevel 8 +#addeffect 222 5 +#scaleeffect 222 0.6 +#maxeffectvalue 222 9 +#multipick 1 +#end + +-- #newbless "Farcaster Fire" +-- #name f "Farcaster (F): +[EFFECT40] Rit/[EFFECTTIMES25_40]% Cmbt" +-- #skipchance 80 +-- #paths f +-- #pathlevel 3 +-- #addeffect 40 1 +-- #scaleeffect 40 0.75 +-- #maxeffectvalue 40 8 +-- #descr "Sacred commanders gain +[EFFECT40] province range on fire rituals, and +[EFFECTTIMES25_40]% range on fire combat spells." +-- #alwaysactive 1 +-- #end +-- +-- #newbless "Farcaster Air" +-- #name a "Farcaster (A): +[EFFECT41] Rit/[EFFECTTIMES25_41]% Cmbt" +-- #skipchance 80 +-- #paths a +-- #pathlevel 3 +-- #addeffect 41 1 +-- #scaleeffect 41 0.75 +-- #maxeffectvalue 41 8 +-- #descr "Sacred commanders gain +[EFFECT41] province range on air rituals, and +[EFFECTTIMES25_41]% range on air combat spells." +-- #alwaysactive 1 +-- #end +-- +-- #newbless "Farcaster Water" +-- #name w "Farcaster (W): +[EFFECT42] Rit/[EFFECTTIMES25_42]% Cmbt" +-- #skipchance 80 +-- #paths w +-- #pathlevel 3 +-- #addeffect 42 1 +-- #scaleeffect 42 0.75 +-- #maxeffectvalue 42 8 +-- #descr "Sacred commanders gain +[EFFECT42] province range on water rituals, and +[EFFECTTIMES25_42]% range on water combat spells." +-- #alwaysactive 1 +-- #end +-- +-- #newbless "Farcaster Earth" +-- #name e "Farcaster (E): +[EFFECT43] Rit/[EFFECTTIMES25_43]% Cmbt" +-- #skipchance 80 +-- #paths e +-- #pathlevel 3 +-- #addeffect 43 1 +-- #scaleeffect 43 0.75 +-- #maxeffectvalue 43 8 +-- #descr "Sacred commanders gain +[EFFECT43] province range on earth rituals, and +[EFFECTTIMES25_43]% range on earth combat spells." +-- #alwaysactive 1 +-- #end +-- +-- #newbless "Farcaster Astral" +-- #name s "Farcaster (S): +[EFFECT44] Rit/[EFFECTTIMES25_44]% Cmbt" +-- #skipchance 80 +-- #paths s +-- #pathlevel 3 +-- #addeffect 44 1 +-- #scaleeffect 44 0.75 +-- #maxeffectvalue 44 8 +-- #descr "Sacred commanders gain +[EFFECT44] province range on astral rituals, and +[EFFECTTIMES25_44]% range on astral combat spells." +-- #alwaysactive 1 +-- #end +-- +-- #newbless "Farcaster Death" +-- #name d "Farcaster (D): +[EFFECT45] Rit/[EFFECTTIMES25_45]% Cmbt" +-- #skipchance 80 +-- #paths d +-- #pathlevel 3 +-- #addeffect 45 1 +-- #scaleeffect 45 0.75 +-- #maxeffectvalue 45 8 +-- #descr "Sacred commanders gain +[EFFECT45] province range on death rituals, and +[EFFECTTIMES25_45]% range on death combat spells." +-- #alwaysactive 1 +-- #end +-- +-- #newbless "Farcaster Nature" +-- #name n "Farcaster (N): +[EFFECT46] Rit/[EFFECTTIMES25_46]% Cmbt" +-- #skipchance 80 +-- #paths n +-- #pathlevel 3 +-- #addeffect 46 1 +-- #scaleeffect 46 0.75 +-- #maxeffectvalue 46 8 +-- #descr "Sacred commanders gain +[EFFECT46] province range on nature rituals, and +[EFFECTTIMES25_46]% range on nature combat spells." +-- #alwaysactive 1 +-- #end + +#newbless "Farcaster All" +#name s "Farcaster All +[EFFECT25] Rit/[EFFECTTIMES25_25]% Cmbt" +#paths s +#pathlevel 3 +#addeffect 25 1 +#scaleeffect 25 1 +#maxeffectvalue 25 4 +#descr "Sacred commanders gain +[EFFECT25] province range on all rituals, and +[EFFECTTIMES25_25]% range on all combat spells." +#alwaysactive 1 +#end + +#newbless "Awe" +#name f "Awe +[EFFECT105]" +#paths f +#pathlevel 6 +#addeffect 105 1 +#scaleeffect 105 1 +#maxeffectvalue 105 3 +#end + +#newbless "Halt Heretic" +#name f "Halt Heretic +[EFFECT327]" +#paths f +#pathlevel 4 +#addeffect 327 1 +#scaleeffect 327 1 +#maxeffectvalue 327 3 +#end + +#newbless "Poison Aura" +#name n "Poison Aura +[EFFECT106], Poison Res +20" +#paths n +#pathlevel 9 +#addeffect 106 2 +#addeffect 200 20 +#scaleeffect 106 1 +#maxeffectvalue 106 5 +#end + +#newbless "Reinvigoration" +#name e "Reinvigoration +[EFFECT117]" +#paths e +#pathlevel 3 +#addeffect 117 2 +#scaleeffect 117 1.1 +#maxeffectvalue 117 8 +#end + + +#newbless "Vine Shield" +#name n "Vine Shield +[EFFECT128] Pen" +#paths n +#pathlevel 10 +#posscaleaffinity 3 300 +#addeffect 128 1 +#end + +#newbless "Astral Shield" +#name s "Astral Shield +12" +#paths s +#pathlevel 10 +#posscaleaffinity 5 300 +#addeffect 321 1 +#end + +#newbless "Horror Mark Attackers" +#name s "Horror Mark Shield (MRN) +[EFFECT127] Pen" +#paths s +#pathlevel 4 +#addeffect 127 1 +#scaleeffect 127 0.7 +#maxeffectvalue 127 1 +#end + +#newbless "Corpse Eater" +#name d "Eat 1 Corpse/turn for +1 max HP" +#paths d +#pathlevel 7 +--#negscaleaffinity 3 80 +#addeffect 236 1 +#addeffect 237 1 +#alwaysactive 1 +#end + + +--#newbless "Curse Bestower" +--#name s "Curse Bestower" +--#name d "Curse Bestower" +--#paths sd +--#pathlevel 4 +--#addeffect 271 1 +--#end + +#newbless "Darkvision" +#name n "Darkvision +[EFFECT281]%" +#paths n +#pathlevel 1 +#addeffect 281 50 +#scaleeffect 281 25 +#maxeffectvalue 281 100 +#end + +--#newbless "Dark Power" +--#name d "Dark Power +[EFFECT293]" +--#paths d +--#pathlevel 2 +--#addeffect 293 1 +--#scaleeffect 293 0.6 +--#maxeffectvalue 293 4 +--#multipick 1 +--#end + +#newbless "Disbelieve" +#name a "Disbelieve +[EFFECT295]" +#name s "Disbelieve +[EFFECT295]" +#paths as +#pathlevel 2 +#addeffect 295 5 +#end + +#newbless "HP bonus" +#name n "Hitpoints +[EFFECT305]" +#name b "Hitpoints +[EFFECT305]" +#paths nb +#pathlevel 1 +#addeffect 305 1 +#scaleeffect 305 1.3 +#maxeffectvalue 305 25 +#multipick 1 +#end + +#newbless "Sleep Aura" +#name n "Sleep Aura +[EFFECT306]" +#paths n +#pathlevel 8 +#addeffect 306 2 +#scaleeffect 306 1 +#maxeffectvalue 306 5 +#end + +#newbless "Reforming" +#name n "Reforming +[EFFECT337]%" +#paths n +#pathlevel 2 +#addeffect 337 10 +#scaleeffect 337 5 +#maxeffectvalue 337 80 +#end + +-- Turns out to be a bad idea for multiple reasons... +-- swarmbody bless basically makes everything unkillable barring soul slay +-- #newbless "Swarm Body" +-- #name n "Swarm Body +[EFFECT338]" +-- #paths n +-- #posscaleaffinity 3 300 +-- #pathlevel 10 +-- #addeffect 338 1 +-- #end + +#newbless "Temp Fire Gem" +#name f "Temp F Gem (disables assassins)" +#paths f +#pathlevel 8 +#skipchance 80 +#addeffect 344 1 -- temp fire gems +#addeffect 213 -10 -- assassin +#addeffect 298 -10 -- seduction +#addeffect 224 -10 -- corruption +#addeffect 210 -10 -- dream seduction +#addeffect 247 -10 -- siren beckon +#end + +#newbless "Temp Air Gem" +#name a "Temp A Gem (disables assassins)" +#paths a +#pathlevel 8 +#skipchance 80 +#addeffect 345 1 -- temp gem +#addeffect 213 -10 -- assassin +#addeffect 298 -10 -- seduction +#addeffect 224 -10 -- corruption +#addeffect 210 -10 -- dream seduction +#addeffect 247 -10 -- siren beckon +#end + +#newbless "Temp Water Gem" +#name w "Temp W Gem (disables assassins)" +#paths w +#pathlevel 8 +#skipchance 80 +#addeffect 346 1 -- temp gem +#addeffect 213 -10 -- assassin +#addeffect 298 -10 -- seduction +#addeffect 224 -10 -- corruption +#addeffect 210 -10 -- dream seduction +#addeffect 247 -10 -- siren beckon +#end + +#newbless "Temp Earth Gem" +#name e "Temp E Gem (disables assassins)" +#paths e +#pathlevel 8 +#skipchance 80 +#addeffect 347 1 -- temp gem +#addeffect 213 -10 -- assassin +#addeffect 298 -10 -- seduction +#addeffect 224 -10 -- corruption +#addeffect 210 -10 -- dream seduction +#addeffect 247 -10 -- siren beckon +#end + +#newbless "Temp S Gem" +#name s "Temp S Gem (disables assassins)" +#paths s +#pathlevel 8 +#skipchance 80 +#addeffect 348 1 -- temp gem +#addeffect 213 -10 -- assassin +#addeffect 298 -10 -- seduction +#addeffect 224 -10 -- corruption +#addeffect 210 -10 -- dream seduction +#addeffect 247 -10 -- siren beckon +#end + +#newbless "Temp D Gem" +#name d "Temp D Gem (disables assassins)" +#paths d +#pathlevel 8 +#skipchance 80 +#addeffect 349 1 -- temp gem +#addeffect 213 -10 -- assassin +#addeffect 298 -10 -- seduction +#addeffect 224 -10 -- corruption +#addeffect 210 -10 -- dream seduction +#addeffect 247 -10 -- siren beckon +#end + +#newbless "Temp N Gem" +#name n "Temp N Gem (disables assassins)" +#paths n +#pathlevel 8 +#skipchance 80 +#addeffect 350 1 -- temp gem +#addeffect 213 -10 -- assassin +#addeffect 298 -10 -- seduction +#addeffect 224 -10 -- corruption +#addeffect 210 -10 -- dream seduction +#addeffect 247 -10 -- siren beckon +#end + +#newbless "Formation Fighter" +#name f "Formation Fighter +[EFFECT366]" +#paths f +#pathlevel 3 +#addeffect 366 1 +#multipick 1 +#alwaysactive 1 +#end + +#newbless "Inspirational" +#name f "Inspirational Presence" +#paths f +#pathlevel 2 +#addeffect 160 30 +#addeffect 368 1 +#multipick 1 +#alwaysactive 1 +#end + +#newbless "Invulnerability" +#name d "Invulnerability +[EFFECT382]" +#paths d +#pathlevel 5 +#addeffect 382 10 +#scaleeffect 382 2 +#maxeffectvalue 382 20 +#end + +#newbless "Protective Force" +#name a "Protective Force +[EFFECT383]" +#name e "Protective Force +[EFFECT383]" +#paths ae +#pathlevel 1 +#addeffect 383 2 +#scaleeffect 383 2 +#maxeffectvalue 383 20 +#end + +#newbless "Mind Slimer" +#name s "Mind Slimer [EFFECT402] + Void Sanity" +#paths s +#pathlevel 10 +#addeffect 402 2 +#addeffect 277 5 +#end + +#newbless "Affliction Resistance" +#name e "Affliction Resistance +[EFFECT406]" +#paths e +#pathlevel 1 +#addeffect 406 3 +#scaleeffect 406 3.5 +#maxeffectvalue 406 10 +#end + +#newbless "Slimer" +#name w "Slimer" +#name n "Slimer" +#paths nw +#pathlevel 10 +#addeffect 412 1 +#end + +#newbless "Blood Vengeance" +#name b "Blood Vengeance" +#paths b +#pathlevel 7 +#addeffect 414 1 +#end + +#newbless "Undying" +#name d "Undying +[EFFECT415]" +#paths d +#pathlevel 1 +#addeffect 415 2 +#scaleeffect 415 2.5 +#maxeffectvalue 415 25 +#multipick 1 +#end + +#newbless "Limited Regen" +#name n "Limited Regeneration +[EFFECT462]%" +#paths n +#pathlevel 6 +#addeffect 462 10 +#scaleeffect 462 3.5 +#maxeffectvalue 462 25 +#end + +#newbless "Limited Regen 1" +#name n "Limited Regeneration +1%" +#paths n +#pathlevel 3 +#addeffect 462 1 +#end + +#newbless "Undead Regen" +#name d "Undead Regeneration +[EFFECT615]%" +#paths d +#pathlevel 5 +#addeffect 615 10 +#scaleeffect 615 3.5 +#maxeffectvalue 615 25 +#end + +#newbless "Overcharged" +#name a "Overcharged" +#paths a +#pathlevel 4 +#addeffect 478 1 +#end + +#newbless "Acid Shield" +#name f "Acid Splash +[EFFECT497]" +#name w "Acid Splash +[EFFECT497]" +#paths fw +#reqcrosspath 1 +#pathlevel 8 +#addeffect 497 7 +#scaleeffect 497 2 +#maxeffectvalue 497 12 +#multipick 1 +#end + +#newbless "Reanimators" +#name d "Reanimators +[EFFECT514]%" +#paths d +#pathlevel 1 +#addeffect 514 25 +#scaleeffect 514 25 +#addeffect 159 1 -- undead leadership +#maxeffectvalue 514 100 +#end + +#newbless "Poison Skin" +#name n "Poison Skin +[EFFECT518]" +#paths n +#pathlevel 1 +#addeffect 518 3 +#scaleeffect 518 5 +#maxeffectvalue 518 25 +#multipick 1 +#end + +#newbless "Poison Weapons" +#name n "Poison Weapons +[EFFECT538]" +#paths n +#pathlevel 1 +#addeffect 538 3 +#scaleeffect 538 4 +#maxeffectvalue 538 25 +#multipick 1 +#end + +#newbless "Withering Weapons" +#name d "Withering Weapons" +#paths d +#pathlevel 3 +#addeffect 539 1 +#end + +#newbless "Death Weapons" +#name d "Death Weapons +[EFFECT540]" +#paths d +#pathlevel 7 +#addeffect 540 2 +#scaleeffect 540 1 +#maxeffectvalue 540 5 +#multipick 1 +#end + +#newbless "Twist Fate" +#name s "Twist Fate" +#paths s +#pathlevel 5 +#addeffect 541 1 +#end + +#newbless "Charged Body 10AN" +#name a "Charged Body + 10 Shock Res" +#paths a +#pathlevel 5 +#addeffect 547 1 +#addeffect 199 10 +#end + +#newbless "Magic Weapons" +#name s "Magic Weapons" +#paths s +#pathlevel 5 +#addeffect 542 1 +#end + +#newbless "Solar Weapons" +#name s "Solar Weapons +[EFFECT543]" +#name f "Solar Weapons +[EFFECT543]" +#paths fs +#pathlevel 2 +#addeffect 543 1 +#scaleeffect 543 1.2 +#maxeffectvalue 543 5 +#multipick 1 +#end + +#newbless "Unholy Weapons" +#name b "Unholy Weapons +[EFFECT544]" +#paths b +#pathlevel 2 +#addeffect 544 3 +#scaleeffect 544 2.4 +#maxeffectvalue 544 16 +#multipick 1 +#end + +#newbless "Flaming Weapons" +#name f "Flaming Weapons +[EFFECT545]" +#paths f +#pathlevel 1 +#addeffect 545 1 +#scaleeffect 545 1.2 +#maxeffectvalue 545 16 +#multipick 1 +#end + +#newbless "Cold Weapons" +#name w "Cold Weapons +[EFFECT549]" +#paths w +#pathlevel 1 +#addeffect 549 2 +#scaleeffect 549 2.2 +#maxeffectvalue 519 22 +#multipick 1 +#end + +#newbless "Thunder Weapons" +#name a "Thunder Weapons" +#paths a +#pathlevel 7 +#addeffect 546 1 +#end + +#newbless "Farshot" +#name a "Farshot +[EFFECT548]%" +#paths a +#pathlevel 1 +#addeffect 548 75 +#scaleeffect 548 75 +#maxeffectvalue 548 400 +#multipick 1 +#end + +#newbless "Blood Surge" +#name b "Blood Surge +[EFFECT554]" +#paths b +#pathlevel 4 +#addeffect 554 3 +#scaleeffect 554 0.7 +#maxeffectvalue 554 8 +#end + +#newbless "Blood Bond" +#name b "Blood Bond (range [EFFECT555])" +#paths b +#pathlevel 1 +#addeffect 555 1 +#scaleeffect 555 1 +#maxeffectvalue 555 10 +#end + +#newbless "Unhindered" +#name n "Unhindered +[EFFECT577]%" +#paths n +#pathlevel 1 +#addeffect 577 10 +#scaleeffect 577 10 +#maxeffectvalue 557 100 +#end + +#newbless "Combat Caster" +#name f "Combat Caster" +#paths f +#pathlevel 1 +#addeffect 581 1 +#end + +#newbless "Swiftness" +#name a "Swiftness +[EFFECT595]%, +[EFFECT377] Def Skill" +#paths a +#pathlevel 3 +#addeffect 595 30 +#addeffect 377 1 +#scaleeffect 595 15 +#scaleeffect 377 0.5 +#maxeffectvalue 595 120 +#multipick 1 +#end + +#newbless "Fateweaving" +#name s "Fateweaving +[EFFECT601]" +#paths s +#pathlevel 6 +#addeffect 601 1 +#negscaleaffinity 4 100 +#end + +#newbless "Sun Awe" +#name f "Sun Awe +[EFFECT605]" +#paths f +#pathlevel 5 +#addeffect 605 1 +#scaleeffect 605 1 +#maxeffectvalue 605 3 +#end + +#newbless "Spirit Sight" +#name s "Spirit Sight" +#name b "Spirit Sight" +#paths sd +#reqcrosspath 1 +#pathlevel 2 +#alwaysactive 1 +#addeffect 607 1 -- spirit sight +#end + +#newbless "Fast Casting" +#name s "Fast Casting +[EFFECT613]%" +#paths s +#pathlevel 2 +#alwaysactive 1 +#addeffect 613 5 +#scaleeffect 613 2.5 +#maxeffectvalue 613 50 +#end + +#newbless "Spellsinger" +#name a "Spellsingers" +#name n "Spellsingers" +#paths an +#pathlevel 2 +#addeffect 616 1 +#reqcrosspath 1 +#end + +-- doesn't want to work +--#newbless "Norange" +--#name a "Use Ranged Weapons while Moving" +--#paths a +--#pathlevel 1 +--#addeffect 634 1 +--#skipchance 50 +--#end + +#newbless "Polymorph Immunity" +#name n "Polymorph Immunity" +#skipchance 90 +#paths n +#pathlevel 1 +#addeffect 635 1 +#end + +#newbless "Stun Immunity" +#name a "Stun Immunity" +#skipchance 75 +#paths a +#pathlevel 1 +#addeffect 638 1 +#end + +#newbless "Animal Awe" +#name n "Animal Awe +[EFFECT646]" +#paths n +#pathlevel 3 +#addeffect 646 1 +#scaleeffect 646 1 +#maxeffectvalue 646 3 +#end + +#newbless "Fire Shield" +#name f "Fire Shield +[EFFECT652]" +#paths f +#pathlevel 3 +#addeffect 652 1 +#scaleeffect 652 1.2 +#maxeffectvalue 652 9 +#end + + diff --git a/data/blesseffects/effect10buffs.txt b/data/blesseffects/effect10buffs.txt new file mode 100644 index 0000000..c8b0299 --- /dev/null +++ b/data/blesseffects/effect10buffs.txt @@ -0,0 +1,173 @@ + +#newbless "Luck" +#name s "Luck" +#name b "Luck" +#paths s +#pathlevel 8 +#effect10buffs 2 +#posscaleaffinity 4 180 +#descr "Grants luck, giving non-inanimate and non-undead creatures a 75% chance to negate otherwise fatal damage." +#end + +#newbless "Aim" +#name a "Wind Guide" +#name n "Eagle Eyes" +#name b "Infernal Accuracy" +#paths an +#pathlevel 2 +#effect10buffs 4 +#descr "Grants the Wind Guide buff, giving +5 precision. This does not stack with spells providing this buff effect." +#end + +#newbless "Barkskin Nature" +#paths n +#name f "Desiccated Skin" +#name b "Desiccated Skin" +#name n "Barkskin" +#pathlevel 6 +#effect10buffs 16 +#descr "Grants Barkskin, setting natural protection to 10 (or +1 if it was higher than this), but adding 5 fire vulnerability." +#end + +#newbless "Legions of Steel" +#paths eb +#name e "Tempered Armour" +#name b "Armour of Infernal Forges" +#pathlevel 3 +#effect10buffs 64 +#posscaleaffinity 1 80 +#descr "Grants Legions of Steel, granting +3 protection to all armour pieces. Does not stack with spells providing this buff effect." +#end + +#newbless "Strength of Giants" +#paths eb +#name e "Strength of Giants" +#name b "Rush of Strength" +#pathlevel 3 +#effect10buffs 128 +#end + +#newbless "Gone Berserk" +#paths nb +#name n "Gone Berserk" +#name b "Gone Berserk" +--#name b "Infernal Rage" +#negscaleaffinity 0 50 +#pathlevel 2 +#effect10buffs 256 +#descr "Blessed sacreds immediately go berserk." +#end + +#newbless "Stoneskin" +#paths e +#name e "Stoneskin" +#pathlevel 8 +#effect10buffs 65536 +#end + +#newbless "Flight always active" +#paths a +#name a "Permanent Flight" +#alwaysactive 1 +#pathlevel 8 +#effect10buffs 131072 +#end + +#newbless "Fly When Blessed" +#name a "Flight when Blessed" +#paths a +#pathlevel 6 +#effect10buffs 131072 +#end + +#newbless "Quickness" +#paths sw +#name s "Quickness" +#name w "Quickness" +#pathlevel 9 +#effect10buffs 262144 +#end + +#newbless "Weapons of Sharpness" +#paths e +#name e "Weapons of Sharpness" +#pathlevel 10 +#posscaleaffinity 1 220 +#effect10buffs 524288 +#end + +#newbless "Life After Death" +#paths d +#name d "Life after Death" +#pathlevel 6 +#negscaleaffinity 3 80 +#effect10buffs 2097152 +#end + +#newbless "Holy Avenger" +#paths f +#name f "Holy Avenger" +#pathlevel 4 +#effect10buffs 4194304 +#end + +#newbless "Flaming Arrows" +#paths f +#name f "Flaming Arrows" +#pathlevel 2 +#effect10buffs 8388608 +#end + +#newbless "Etherealness" +#paths s +#name s "Etherealness" +#pathlevel 9 +#effect10buffs 134217728 +#end + +#newbless "Antimagic" +#paths s +#name s "Antimagic" +#pathlevel 3 +#effect10buffs 67108864 +#end + +#newbless "Larger" +#paths en +#name e "Larger" +#name n "Larger" +#pathlevel 5 +#alwaysactive 1 +#effect10buffs 2147483648 +#end + +#newbless "Liquid Body" +#paths w +#name w "Liquid Body" +#pathlevel 8 +#effect10buffs 2680059592704 +#end + +#newbless "Fortitude" +#paths e +#name e "Fortitude" +#pathlevel 8 +#effect10buffs 481036337152 +#end + +#newbless "Hard Skin" +#paths e +#name e "Hard Skin" +#pathlevel 5 +#effect10buffs 70368744177664 +#end + +-- redundant with prot force scalable effect +-- #newbless "Flying Shield" +-- #paths ae +-- #name e "Flying Shield" +-- #name a "Flying Shield" +-- #pathlevel 8 +-- #effect10buffs 549755813888 +-- #end + diff --git a/data/blesseffects/prophetshapes.txt b/data/blesseffects/prophetshapes.txt new file mode 100644 index 0000000..f3b33bb --- /dev/null +++ b/data/blesseffects/prophetshapes.txt @@ -0,0 +1,299 @@ +#newbless "Prophetshape angel of host" +#name s "Prophet: Angel of the Host" +#paths s +#pathlevel 2 +#addeffect 516 543 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape thing that shouldn't be" +#name s "Prophet:Thing that Shouldn't Be" +#paths s +#pathlevel 1 +#addeffect 516 751 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape behemoth" +#name d "Prophet Shape: Behemoth" +#paths d +#pathlevel 1 +#addeffect 516 452 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape cavecrab" +#name e "Prophet Shape: Cave Crab" +#paths e +#pathlevel 1 +#addeffect 516 2514 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape dark vines" +#name b "Prophet Shape: Dark Vines" +#paths b +#pathlevel 1 +#addeffect 516 330 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape draconian chief" +#name a "Prophet Shape: Draconian Chief" +#paths a +#pathlevel 1 +#addeffect 516 620 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape demon knight" +#name b "Prophet Shape: Demon Knight" +#paths b +#pathlevel 1 +#addeffect 516 489 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape fall bear" +#name e "Prophet Shape: Fall Bear" +#paths e +#pathlevel 1 +#addeffect 516 512 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape fiend of darkness" +#name b "Prophet: Fiend of Darkness" +#paths b +#pathlevel 1 +#addeffect 516 88 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape forest troll" +#name n "Prophet: Forest Troll Shaman" +#paths n +#pathlevel 1 +#addeffect 516 2220 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape formless spawn" +#name s "Prophet Shape: Formless Spawn" +#paths s +#pathlevel 1 +#addeffect 516 966 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape gelatinous cube" +#name w "Prophet Shape: Gelatinous Cube" +#paths w +#pathlevel 1 +#addeffect 516 2159 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape otherness" +#name s "Prophet Shape: Otherness" +#paths s +#pathlevel 1 +#addeffect 516 755 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape green lion" +#name w "Prophet Shape: Green Lion" +#paths w +#pathlevel 1 +#addeffect 516 1983 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape gryphon" +#name a "Prophet Shape: Gryphon" +#paths a +#pathlevel 1 +#addeffect 516 2131 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape hound of twilight" +#name d "Prophet: Hound of Twilight" +#paths d +#pathlevel 1 +#addeffect 516 3168 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape kithaironic lion" +#name n "Prophet Shape: Kithaironic Lion" +#paths n +#pathlevel 1 +#addeffect 516 514 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape lamia" +#name n "Prophet Shape: Lamia" +#paths n +#pathlevel 1 +#addeffect 516 394 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape living statue" +#name e "Prophet Shape: Living Statue" +#paths e +#pathlevel 1 +#addeffect 516 474 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape manticore" +#name e "Prophet Shape: Manticore" +#name n "Prophet Shape: Manticore" +#paths en +#pathlevel 1 +#addeffect 516 2130 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape released king" +#name d "Prophet Shape: Released King" +#paths d +#pathlevel 1 +#addeffect 516 3168 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape scorpion beast" +#name e "Prophet Shape: Scorpion Beast" +#name f "Prophet Shape: Scorpion Beast" +#paths ef +#pathlevel 1 +#addeffect 516 524 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape troll" +#name e "Prophet Shape: Troll" +#paths e +#pathlevel 1 +#addeffect 516 518 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape storm demon" +#name b "Prophet Shape: Storm Demon" +#name a "Prophet Shape: Storm Demon" +#paths ab +#reqcrosspath 1 +#pathlevel 2 +#addeffect 516 632 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape werewolf" +#name n "Prophet Shape: Werewolf" +#paths n +#pathlevel 1 +#addeffect 516 633 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape ether warrior" +#name s "Prophet Shape: Ether Warrior" +#paths s +#pathlevel 2 +#addeffect 516 736 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape faery queen" +#name a "Prophet Shape: Faery Queen" +#name n "Prophet Shape: Faery Queen" +#paths an +#reqcrosspath 1 +#pathlevel 2 +#addeffect 516 627 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape moundfiend" +#name n "Prophet Shape: Mound Fiend" +#paths n +#pathlevel 1 +#addeffect 516 439 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape sleeper" +#name n "Prophet Shape: Sleeper" +#paths n +#pathlevel 1 +#addeffect 516 559 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape chimera" +#name b "Prophet Shape: Chimera" +#name n "Prophet Shape: Chimera" +#paths bn +#pathlevel 2 +#reqcrosspath 1 +#addeffect 516 487 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape draco lion" +#name b "Prophet Shape: Draco Lion" +#name n "Prophet Shape: Draco Lion" +#paths bn +#pathlevel 2 +#reqcrosspath 1 +#addeffect 516 637 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Prophetshape big foulspawn" +#name b "Prophet Shape: Huge Foul Spawn" +#name n "Prophet Shape: Huge Foul Spawn" +#paths bn +#pathlevel 2 +#reqcrosspath 1 +#addeffect 516 550 +#skipchance 90 +#alwaysactive 1 +#end diff --git a/data/blesseffects/retinue.txt b/data/blesseffects/retinue.txt new file mode 100644 index 0000000..ffdbe4d --- /dev/null +++ b/data/blesseffects/retinue.txt @@ -0,0 +1,210 @@ +-- Montags can't be used without a self-killing secondshape dummy, which looks weird and requires a .dm + +#newbless "Retinue blackhawk" +#name a "Retinue: Black Hawk" +#paths a +#pathlevel 4 +#addeffect 436 517 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue boar" +#name n "Retinue: Boar" +#paths n +#pathlevel 2 +#addeffect 436 549 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue corpse candle" +#name f "Retinue: Corpse Candle" +#name d "Retinue: Corpse Candle" +#paths fd +#reqcrosspath 1 +#pathlevel 2 +#addeffect 436 528 +#addeffect 158 1 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +-- Montags don't work +--#newbless "Retinue soulless" +--#name d "Retinue: Soulless" +--#paths d +--#pathlevel 2 +--#addeffect 436 -15 +--#addeffect 159 1 -- undead leadership +--#skipchance 90 +--#alwaysactive 1 +--#end + +#newbless "Retinue deer" +#name n "Retinue: Deer" +#paths n +#pathlevel 2 +#addeffect 436 2228 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue dispossessed spirit" +#name d "Retinue: Dispossessed Spirit" +#paths d +#pathlevel 2 +#addeffect 436 674 +#addeffect 159 1 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + + +#newbless "Retinue dog" +#name n "Retinue: Dog" +#paths n +#pathlevel 2 +#addeffect 436 1560 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue s1 earth elemental" +#name e "Retinue: Earth Elemental (s1)" +#paths e +#pathlevel 1 +#addeffect 436 498 +#addeffect 158 1 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue fiery imp" +#name f "Retinue: Fiery Imp" +#name b "Retinue: Fiery Imp" +#paths fb +#reqcrosspath 1 +#pathlevel 3 +#addeffect 436 2286 +#addeffect 159 1 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue goat" +#name n "Retinue: Goat" +#paths n +#pathlevel 1 +#addeffect 436 2227 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue illearth 1" +#name e "Retinue: Illearth (size 1)" +#name b "Retinue: Illearth (size 1)" +#paths eb +#reqcrosspath 1 +#pathlevel 2 +#addeffect 436 2285 +#addeffect 158 1 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue imp" +#name b "Retinue: Imp" +#paths b +#pathlevel 4 +#addeffect 436 303 +#addeffect 159 1 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue phantasmal warrior" +#name a "Retinue: Phantasmal Warrior" +#paths a +#pathlevel 2 +#addeffect 436 297 +#addeffect 158 1 -- magic leadership +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Retinue phantasmal wolf" +#name a "Retinue: Phantasmal Wolf" +#paths a +#pathlevel 2 +#addeffect 436 298 +#addeffect 158 1 -- magic leadership +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Retinue phantasmal archer" +#name a "Retinue: Phantasmal Archer" +#paths a +#pathlevel 3 +#addeffect 436 3233 +#addeffect 158 1 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue shadow imp" +#name b "Retinue: Shadow Imp" +#paths b +#pathlevel 3 +#addeffect 436 2287 +#addeffect 159 1 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue sprite" +#name n "Retinue: Sprite" +#name na "Retinue: Sprite" +#paths na +#reqcrosspath 1 +#pathlevel 3 +#addeffect 436 592 +#addeffect 158 1 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +--#newbless "Retinue swarm bugs" +--#name n "Retinue: Random Insects" +--#paths n +--#pathlevel 2 +--#addeffect 436 -9 +--#addeffect 158 1 -- magic leadership +--#skipchance 90 +--#alwaysactive 1 +--#end + +#newbless "Retinue vine man" +#name n "Retinue: Vine Man" +#paths n +#pathlevel 2 +#addeffect 436 361 +#addeffect 158 1 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Retinue wolf" +#name n "Retinue: Wolf" +#paths n +#pathlevel 2 +#addeffect 436 284 +#skipchance 90 +#alwaysactive 1 +#end + + + + + diff --git a/data/blesseffects/summonallies.txt b/data/blesseffects/summonallies.txt new file mode 100644 index 0000000..c28e37a --- /dev/null +++ b/data/blesseffects/summonallies.txt @@ -0,0 +1,343 @@ +-- Montags will require a firstshape dummy to work. + +#newbless "Summonallies airele 1" +#name a "Summon: Air Elemental (size 1)" +#paths a +#pathlevel 4 +#addeffect 164 517 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies algae man" +#name w "Summon: Algae Man" +#name n "Summon: Algae Man" +#paths nw +#pathlevel 3 +#reqcrosspath 1 +#addeffect 164 2976 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies corpse construct" +#name a "Summon: Corpse Construct" +#name d "Summon: Corpse Construct" +#paths ad +#pathlevel 3 +#reqcrosspath 1 +#addeffect 164 534 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +--#newbless "Summonallies crossbreed" +--#name b "Summon: Lesser Foulspawn" +--#name n "Summon: Lesser Foulspawn" +--#paths bn +--#pathlevel 3 +--#reqcrosspath 1 +--#addeffect 164 -11 +--#skipchance 90 +--#alwaysactive 1 +--#end +-- +--#newbless "Summonallies 97% bad 3% good crossbreed" +--#name b "Summon: Foulspawn, 97% weak" +--#name n "Summon: Foulspawn, 97% weak" +--#paths bn +--#pathlevel 5 +--#reqcrosspath 1 +--#addeffect 164 -12 +--#skipchance 90 +--#alwaysactive 1 +--#end +-- +--#newbless "Summonallies ghoul" +--#name d "Summon: Ghoul" +--#paths d +--#pathlevel 3 +--#addeffect 164 -4 +--#addeffect 159 30 -- undead leadership +--#skipchance 90 +--#alwaysactive 1 +--#end + +#newbless "Summonallies longdead archer" +#name d "Summon: Longdead Archer" +#paths d +#pathlevel 3 +#addeffect 164 535 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies manikin" +#name d "Summon: Manikin" +#paths d +#pathlevel 4 +#addeffect 164 313 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies moose" +#name n "Summon: Moose" +#paths n +#pathlevel 4 +#addeffect 164 1084 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies sea dog" +#name n "Summon: Sea Dog" +#name w "Summon: Sea Dog" +#paths nw +#reqcrosspath 1 +#pathlevel 2 +#addeffect 164 1064 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies phantasmal knight" +#name a "Summon: Phantasmal Knight" +#paths a +#pathlevel 2 +#addeffect 164 696 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies terracotta warrior" +#name f "Summon: Terracotta Warrior" +#name e "Summon: Terracotta Warrior" +#paths fe +#reqcrosspath 1 +#pathlevel 4 +#addeffect 164 2134 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies water elemental s1" +#name w "Summon: Water Elemental (s1)" +#paths w +#pathlevel 4 +#addeffect 164 413 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies will o wisp" +#name f "Summon: Will o' the Wisp" +#paths f +#pathlevel 4 +#addeffect 164 527 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies blackhawk" +#name a "Summon: Black Hawk" +#paths a +#pathlevel 4 +#addeffect 164 517 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies boar" +#name n "Summon: Boar" +#paths n +#pathlevel 1 +#addeffect 164 549 +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Summonallies corpse candle" +#name f "Summon: Corpse Candle" +#name d "Summon: Corpse Candle" +#paths fd +#reqcrosspath 1 +#pathlevel 1 +#addeffect 164 528 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies deer" +#name n "Summon: Deer" +#paths n +#pathlevel 1 +#addeffect 164 2228 +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Summonallies dispossessed spirit" +#name d "Summon: Dispossessed Spirit" +#paths d +#pathlevel 1 +#addeffect 164 674 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies dog" +#name n "Summon: Dog" +#paths n +#pathlevel 1 +#addeffect 164 1560 +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Summonallies earth elemental size 1" +#name e "Summon: Earth Elemental (s1)" +#paths e +#pathlevel 1 +#addeffect 164 498 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies fiery imp" +#name b "Summon: Fiery Imp" +#name f "Summon: Fiery Imp" +#paths fb +#pathlevel 2 +#reqcrosspath 1 +#addeffect 164 2286 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies goat" +#name n "Summon: Goat" +#paths n +#pathlevel 1 +#addeffect 164 2227 +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Summonallies illearth s1" +#name e "Summon: Illearth (size 1)" +#name b "Summon: Illearth (size 1)" +#paths eb +#reqcrosspath 1 +#pathlevel 2 +#addeffect 164 2285 +#addeffect 158 30 -- magic leadership +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Summonallies imp" +#name b "Summon: Imp" +#paths b +#pathlevel 4 +#addeffect 164 303 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies phantasmal warrior" +#name a "Summon: Phantasmal Warrior" +#paths a +#pathlevel 1 +#addeffect 164 297 +#addeffect 158 30 -- magic leadership +#skipchance 95 +#alwaysactive 1 +#end + +#newbless "Summonallies phantasmal archer" +#name a "Summon: Phantasmal Archer" +#paths a +#pathlevel 1 +#addeffect 164 3233 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies phantasmal wolf" +#name a "Summon: Phantasmal Wolf" +#paths a +#pathlevel 1 +#addeffect 164 298 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies shadow imp" +#name b "Summon: Shadow Imp" +#paths b +#pathlevel 2 +#addeffect 164 2287 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies sprite" +#name n "Summon: Sprite" +#name a "Summon: Sprite" +#paths na +#reqcrosspath 1 +#pathlevel 2 +#addeffect 164 592 +#addeffect 159 30 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +--#newbless "Summonallies swarmbugs" +--#name n "Summon: Random Insect" +--#paths n +--#pathlevel 1 +--#addeffect 164 -9 +--#addeffect 158 30 -- magic leadership +--#skipchance 90 +--#alwaysactive 1 +--#end + +#newbless "Summonallies vineman" +#name n "Summon: Vine Man" +#paths n +#pathlevel 1 +#addeffect 164 361 +#addeffect 158 30 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Summonallies wolf" +#name n "Summon: Wolf" +#paths n +#pathlevel 1 +#addeffect 164 284 +#skipchance 90 +#alwaysactive 1 +#end + + diff --git a/data/blesseffects/templetrain.txt b/data/blesseffects/templetrain.txt new file mode 100644 index 0000000..392b80c --- /dev/null +++ b/data/blesseffects/templetrain.txt @@ -0,0 +1,607 @@ +-- Montags will require firstshape dummies to work + +#newbless "Templetrainer amphiptere" +#name a "Temple Train: Amphiptere" +#name n "Temple Train: Amphiptere" +#paths an +#reqcrosspath 1 +#pathlevel 2 +#addeffect 564 1412 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer air elem" +#name a "Temple Train: Air Elemental(s2)" +#paths a +#pathlevel 1 +#addeffect 564 571 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer angel choir" +#name s "Temple Train: Angel of Choirs" +#paths s +#pathlevel 1 +#addeffect 564 1367 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer bog beast" +#name n "Temple Train: Bog Beast" +#name w "Temple Train: Bog Beast" +#paths nw +#reqcrosspath 1 +#pathlevel 2 +#addeffect 564 578 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer bone fiend" +#name d "Temple Train: Bone Fiend" +#name b "Temple Train: Bone Fiend" +#paths db +#pathlevel 1 +#addeffect 564 433 +#skipchance 90 +#alwaysactive 1 +#end + +--#newbless "Templetrainer dungeon monsters" +--#name e "Temple Train: Dungeon Monsters" +--#name d "Temple Train: Dungeon Monsters" +--#paths ed +--#reqcrosspath 1 +--#pathlevel 5 +--#addeffect 564 -14 +--#skipchance 90 +--#alwaysactive 1 +--#end + +#newbless "Templetrainer cave cow" +#name e "Temple Train: Cave Cow" +#paths e +#pathlevel 1 +#addeffect 564 2512 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer cave spider" +#name e "Temple Train: Cave Spider" +#paths e +#pathlevel 1 +#addeffect 564 2513 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer clayman" +#name e "Temple Train: Clayman" +#paths e +#pathlevel 1 +#addeffect 564 817 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer clockwork soldier" +#name e "Temple Train: Clockwork Soldier" +#paths e +#pathlevel 1 +#addeffect 564 2321 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer clockwork horror" +#name e "Temple Train: Clockwork Horror" +#paths e +#pathlevel 1 +#addeffect 564 982 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer dire wolf" +#name n "Temple Train: Dire Wolf" +#paths n +#pathlevel 1 +#addeffect 564 1224 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer draconian" +#name a "Temple Train: Draconian" +#paths a +#pathlevel 1 +#addeffect 564 593 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer draconian" +#name a "Temple Train: Draconian" +#paths a +#pathlevel 1 +#addeffect 564 593 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer dust warrior" +#name e "Temple Train: Dust Warrior" +#name d "Temple Train: Dust Warrior" +#paths ed +#pathlevel 2 +#reqcrosspath 1 +#addeffect 564 1980 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer earth gnome" +#name e "Temple Train: Earth Gnome" +#paths e +#pathlevel 1 +#addeffect 564 561 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer earth elemental 2" +#name e "Temple Train: Earth Elemental 2" +#paths e +#pathlevel 1 +#addeffect 564 497 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer elder thing" +#name s "Temple Train: Elder Thing" +#paths s +#pathlevel 1 +#addeffect 564 752 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer fire ele 2" +#name f "Temple Train: Fire Elemental s2" +#paths f +#pathlevel 2 +#addeffect 564 598 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer fire ant" +#name f "Temple Train: Fire Ant" +#name n "Temple Train: Fire Ant" +#paths fn +#reqcrosspath 1 +#pathlevel 2 +#addeffect 564 2225 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer fire snake" +#name f "Temple Train: Fire Snake" +#paths f +#pathlevel 2 +#addeffect 564 814 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer forest troll" +#name n "Temple Train: Forest Troll" +#paths n +#pathlevel 2 +#addeffect 564 2219 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer gargoyle" +#name e "Temple Train: Gargoyle" +#paths e +#pathlevel 1 +#addeffect 564 2368 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer great bear" +#name n "Temple Train: Great Bear" +#paths n +#pathlevel 1 +#addeffect 564 694 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer great boar" +#name n "Temple Train: Great Boar" +#paths n +#pathlevel 1 +#addeffect 564 2136 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer great hawk" +#name a "Temple Train: Great Hawk" +#paths a +#pathlevel 1 +#addeffect 564 1380 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer great lion" +#name n "Temple Train: Great Lion" +#paths n +#pathlevel 1 +#addeffect 564 628 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer great spider" +#name n "Temple Train: Great Spider" +#paths n +#pathlevel 1 +#addeffect 564 884 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer horned serpent" +#name n "Temple Train: Horned Serpent" +#paths n +#pathlevel 1 +#addeffect 564 403 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer hydra hatchling" +#name n "Temple Train: Hydra Hatchling" +#paths n +#pathlevel 1 +#addeffect 564 1840 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer iron fly" +#name e "Temple Train: Iron Fly" +#paths e +#pathlevel 2 +#addeffect 564 3232 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer illearth 2" +#name b "Temple Train: Illearth size 2" +#name e "Temple Train: Illearth size 2" +#paths be +#pathlevel 2 +#reqcrosspath 1 +#addeffect 564 2284 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer killer mantis" +#name n "Temple Train: Killer Mantis" +#paths n +#pathlevel 1 +#addeffect 564 2226 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer kydnid" +#name w "Temple Train: Kydnid" +#paths w +#pathlevel 1 +#addeffect 564 1227 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer lesser otherness" +#name s "Temple Train: Lesser Otherness" +#paths s +#pathlevel 2 +#addeffect 564 756 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer lioness" +#name n "Temple Train: Lioness" +#paths n +#pathlevel 1 +#addeffect 564 2133 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer living statue" +#name e "Temple Train: Living Statue" +#paths e +#pathlevel 2 +#addeffect 564 474 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer longdead horseman" +#name d "Temple Train: Longdead Horseman" +#paths d +#pathlevel 1 +#addeffect 564 189 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer lumber construct" +#name n "Temple Train: Lumber Construct" +#paths n +#pathlevel 2 +#addeffect 564 476 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer mandragora" +#name n "Temple Train: Mandragora" +#name d "Temple Train: Mandragora" +#paths nd +#reqcrosspath 1 +#pathlevel 2 +#addeffect 564 314 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer mechanical man" +#name e "Temple Train: Mechanical Man" +#paths e +#pathlevel 1 +#addeffect 564 532 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer ogre" +#name e "Temple Train: Ogre" +#paths e +#pathlevel 2 +#addeffect 564 2135 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer released warrior" +#name e "Temple Train: Released Warrior" +#name d "Temple Train: Released Warrior" +#paths ed +#pathlevel 2 +#reqcrosspath 1 +#addeffect 564 2524 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer salamander" +#name f "Temple Train: Salamander" +#paths f +#pathlevel 2 +#addeffect 564 213 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer scorpion beast" +#name f "Temple Train: Scorpion Beast" +#name e "Temple Train: Scorpion Beast" +#paths fe +#reqcrosspath 1 +#pathlevel 2 +#addeffect 564 524 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer shade" +#name d "Temple Train: Shade" +#paths d +#pathlevel 1 +#addeffect 564 676 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer shade beast" +#name d "Temple Train: Shade Beast" +#paths d +#pathlevel 2 +#addeffect 564 442 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer spine devil" +#name b "Temple Train: Spine Devil" +#paths b +#pathlevel 2 +#addeffect 564 638 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer sylph" +#name a "Temple Train: Sylph" +#paths a +#pathlevel 2 +#addeffect 564 562 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer thing from beyond" +#name s "Temple Train: Thing from Beyond" +#paths s +#pathlevel 2 +#addeffect 564 750 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer thing from void" +#name s "Temple Train: Thing from Void" +#paths s +#pathlevel 2 +#addeffect 564 753 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer thing of many eyes" +#name s "Temple Train: Many Eyed Thing" +#paths s +#pathlevel 1 +#addeffect 564 758 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer tiger" +#name n "Temple Train: Tiger" +#paths n +#pathlevel 2 +#addeffect 564 1140 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer unfrozen warrior" +#name w "Temple Train: Unfrozen Warrior" +#name d "Temple Train: Unfrozen Warrior" +#paths wd +#reqcrosspath 1 +#pathlevel 2 +#addeffect 564 1202 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer Vile Thing" +#name s "Temple Train: Vile Thing" +#paths s +#pathlevel 2 +#addeffect 564 757 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer vine ogre" +#name n "Temple Train: Vine Ogre" +#paths n +#pathlevel 2 +#addeffect 564 1140 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer water elemental" +#name w "Temple Train: Water Elemental 2" +#paths w +#pathlevel 2 +#addeffect 564 412 +#addeffect 158 10 -- magic leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer werewolf" +#name n "Temple Train: Werewolf" +#paths n +#pathlevel 2 +#addeffect 564 633 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer wight" +#name d "Temple Train: Wight" +#paths d +#pathlevel 3 +#addeffect 564 533 +#addeffect 159 10 -- undead leadership +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer woodland spirit" +#name n "Temple Train: Woodland Spirit" +#paths n +#pathlevel 1 +#addeffect 564 932 +#skipchance 90 +#alwaysactive 1 +#end + +#newbless "Templetrainer wyvern" +#name a "Temple Train: Wyvern" +#paths a +#pathlevel 2 +#addeffect 564 520 +#skipchance 90 +#alwaysactive 1 +#end + diff --git a/data/blesseffects/utility.txt b/data/blesseffects/utility.txt new file mode 100644 index 0000000..06dfc3e --- /dev/null +++ b/data/blesseffects/utility.txt @@ -0,0 +1,534 @@ +#newbless "Standard" +#name f "Standard +[EFFECT103]" +#paths f +#pathlevel 2 +#addeffect 103 1 +#scaleeffect 103 1 +#maxeffectvalue 103 10 +#multipick 1 +#skipchance 50 +#end + +#newbless "Water Breathing" +#name w "Water Breathing" +#paths w +#pathlevel 2 +#addeffect 110 1 +#alwaysactive 1 +#skipchance 50 +#end + + +#newbless "Air Breathing" +#name a "Air Breathing" +#paths a +#pathlevel 5 +#addeffect 129 1 +#alwaysactive 1 +#skipchance 50 +#end +-- +-- #newbless "Gift of Water Breathing" +-- #name w "Gift of Water Breathing +[EFFECT111]" +-- #paths w +-- #pathlevel 2 +-- #addeffect 111 20 +-- #scaleeffect 111 20 +-- #maxeffectvalue 111 120 +-- #alwaysactive 1 +-- #skipchance 50 +-- #end +-- +-- #newbless "Gift of Air Breathing" +-- #name a "Gift of Air Breathing +[EFFECT130]" +-- #paths a +-- #pathlevel 2 +-- #addeffect 130 20 +-- #scaleeffect 130 20 +-- #maxeffectvalue 130 120 +-- #alwaysactive 1 +-- #skipchance 50 +-- #end + +#newbless "Sailing" +#name a "Sailing ([EFFECT112] size pts)" +#name w "Sailing ([EFFECT112] size pts)" +#paths aw +#reqcrosspath 1 +#pathlevel 5 +#addeffect 410 10 +#addeffect 112 40 +#scaleeffect 112 40 +#maxeffectvalue 112 80 +#alwaysactive 1 +#skipchance 50 +#end + + +#newbless "Siege Bonus" +#name e "Siege Strength +[EFFECT125]" +#paths e +#pathlevel 1 +#addeffect 125 2 +#scaleeffect 125 3 +#maxeffectvalue 125 20 +#alwaysactive 1 +#multipick 1 +#skipchance 50 +#end + +#newbless "Siege Defence" +#name e "Siege Defence +[EFFECT215]" +#paths e +#pathlevel 1 +#addeffect 215 1 +#scaleeffect 215 1.5 +#maxeffectvalue 215 10 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Alchemy Bonus" +#name f "Alchemy Bonus +[EFFECT132]%" +#name e "Alchemy Bonus +[EFFECT132]%" +#paths fe +#pathlevel 1 +#addeffect 132 10 +#scaleeffect 132 10 +#maxeffectvalue 132 60 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Soul Butcher" +#name d "Soul Butcher (max 1 gem/battle)" +#paths d +#pathlevel 4 +#addeffect 570 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Warning" +#name s "Warning +5" +#paths s +#pathlevel 1 +#addeffect 152 5 +#alwaysactive 1 +#multipick 1 +#skipchance 50 +#end + +#newbless "Magic Leadership" +#name s "Magic Leadership +[EFFECT158]" +#paths s +#pathlevel 1 +#addeffect 158 40 +#scaleeffect 158 40 +#maxeffectvalue 158 80 +#alwaysactive 1 +#multipick 1 +#skipchance 50 +#end + +#newbless "Undead Leadership" +#name d "Undead Leadership +[EFFECT159]" +#paths d +#pathlevel 1 +#addeffect 159 40 +#scaleeffect 159 40 +#maxeffectvalue 159 80 +#alwaysactive 1 +#multipick 1 +#skipchance 50 +#end + +#newbless "Patrol Bonus" +#name a "Patrol Bonus +[EFFECT170]" +#name s "Patrol Bonus +[EFFECT170]" +#paths as +#pathlevel 1 +#addeffect 170 1 +#scaleeffect 170 1.5 +#maxeffectvalue 170 10 +#alwaysactive 1 +#multipick 1 +#skipchance 50 +#end + +#newbless "Inquisitor" +#name f "Inquisitors" +#paths f +#pathlevel 2 +#addeffect 211 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Army Healer" +#name n "Army Healer +[EFFECT212]%" +#paths n +#pathlevel 1 +#addeffect 212 1 +#scaleeffect 212 2 +#maxeffectvalue 212 20 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Spies" +#name s "Spies" +#name a "Spies" +#paths as +#pathlevel 3 +#addeffect 214 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Reduce Unrest" +#name s "Reduce Unrest +[EFFECTDIV10_223]" +#name w "Reduce Unrest +[EFFECTDIV10_223]" +#paths ws +#pathlevel 1 +#addeffect 223 5 +#scaleeffect 223 8 +#maxeffectvalue 223 40 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Fortune Teller" +#name s "Fortune Teller +[EFFECT235]%" +#name b "Fortune Teller +[EFFECT235]%" +#paths sb +#pathlevel 1 +#addeffect 235 4 +#scaleeffect 235 6 +#maxeffectvalue 235 15 +#alwaysactive 1 +#skipchance 50 +#end + +-- #newbless "Dragon Master" +-- #name f "Dragon Master +[EFFECT270]" +-- #name w "Dragon Master +[EFFECT270]" +-- #paths fw +-- #pathlevel 3 +-- #addeffect 270 1 +-- #scaleeffect 270 1 +-- #maxeffectvalue 270 5 +-- #alwaysactive 1 +-- #skipchance 50 +-- #end + +#newbless "Reincarnation" +#name s "Reincarnation +[EFFECT304]%" +#name n "Reincarnation +[EFFECT304]%" +#paths sn +#pathlevel 1 +#addeffect 304 10 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Tax and gem Collector" +#name a "Tax/Gem Collector" +#paths a +#pathlevel 1 +#addeffect 342 1 +#addeffect 343 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Defence Organiser" +#name f "Defence Organiser +[EFFECT352]" +#paths f +#pathlevel 3 +#addeffect 352 1 +#scaleeffect 352 1 +#maxeffectvalue 352 5 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Healer" +#name n "Healer +[EFFECT354]" +#paths n +#pathlevel 5 +#addeffect 354 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Disease Healer" +#name n "Disease Healer +[EFFECT355]" +#paths n +#pathlevel 4 +#addeffect 355 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Extra Arm" +#name n "Number of Arms +[EFFECT361]" +#name e "Number of Arms +[EFFECT361]" +#paths ne +#pathlevel 5 +#addeffect 361 1 +#scaleeffect 361 0.45 +#maxeffectvalue 361 4 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Master Smith" +#name e "Master Smith +[EFFECT363]" +#paths e +#pathlevel 6 +#addeffect 363 1 +#scaleeffect 363 0.3 +#maxeffectvalue 363 3 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Master Ritualist" +#name s "Master Ritualist +[EFFECT463]" +#paths s +#pathlevel 7 +#addeffect 463 1 +#scaleeffect 463 0.3 +#maxeffectvalue 463 2 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Reanimator Priests" +#name d "Reanimator Priests" +#paths d +#pathlevel 10 +#addeffect 632 1 +#addeffect 159 40 -- undead leadership +#negscaleaffinity 3 200 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Passive Reanimator" +#name d "Commanders Raise [EFFECT466] Corpses" +#paths d +#pathlevel 1 +#addeffect 466 2 +#addeffect 159 10 -- +10 undead ldr +#scaleeffect 466 2 +#maxeffectvalue 466 20 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Bodyguard" +#name f "Bodyguard +[EFFECT408]" +#name s "Bodyguard +[EFFECT408]" +#paths fs +#pathlevel 1 +#addeffect 408 1 +#scaleeffect 408 1.5 +#maxeffectvalue 408 6 +#alwaysactive 1 +#skipchance 50 +#multipick 1 +#end + +#newbless "Elegist" +#name n "Elegist +[EFFECT411]" +#name b "Elegist +[EFFECT411]" +#paths nb +#pathlevel 3 +#addeffect 411 1 +#scaleeffect 411 0.8 +#maxeffectvalue 411 3 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Obfuscate positive" +#name a "Add +[EFFECT419] to Scout Reports" +#paths a +#pathlevel 1 +#addeffect 419 5 +#scaleeffect 419 10 +#maxeffectvalue 419 40 +#alwaysactive 1 +#skipchance 75 +#end + +#newbless "Obfuscate negative" +#name a "Hide +[EFFECT419] from Scout Reports" +#paths a +#pathlevel 1 +#addeffect 419 -3 +#scaleeffect 419 -5 +#maxeffectvalue 419 -50 +#alwaysactive 1 +#skipchance 75 +#end + +#newbless "Fool Scouts" +#name a "Scouts see only one Unit Type" +#paths a +#pathlevel 2 +#addeffect 420 1 +#alwaysactive 1 +#skipchance 75 +#end + +#newbless "Mapmove" +#name a "Mapmove +[EFFECT426]" +#paths a +#pathlevel 1 +#addeffect 426 2 +#scaleeffect 426 3 +#maxeffectvalue 426 30 +#alwaysactive 1 +#skipchance 75 +#end + +#newbless "Pearl Cultivator" +#name w "Pearl Cultivator +[EFFECT430]" +#name s "Pearl Cultivator +[EFFECT430]" +#paths ws +#reqcrosspath 1 +#pathlevel 2 +#addeffect 430 1 +#scaleeffect 430 2 +#maxeffectvalue 430 5 +#alwaysactive 1 +#skipchance 66 +#end + +#newbless "Carcass Collector" +#name n "Carcass Collector +[EFFECT658]" +#name d "Carcass Collector +[EFFECT658]" +#paths nd +#reqcrosspath 1 +#pathlevel 2 +#addeffect 658 1 +#scaleeffect 658 2 +#maxeffectvalue 658 5 +#alwaysactive 1 +#skipchance 66 +#end + +#newbless "Divine Insights" +#name s "Divine Insights ([EFFECT248] RP)" +#paths s +#pathlevel 1 +#addeffect 450 1 -- divine insights +#addeffect 451 1 -- research without magic +#addeffect 248 1 -- fixedresearch +#scaleeffect 248 0.3 +#maxeffectvalue 248 3 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Forge Bonus Percentile" +#name e "Forge Bonus +[EFFECT118]%" +#paths e +#pathlevel 4 +#addeffect 118 5 +#scaleeffect 118 5 +#maxeffectvalue 118 20 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Forge Bonus Fixed" +#name e "Forge Bonus +[EFFECT453]" +#paths e +#pathlevel 4 +#addeffect 453 1 +#scaleeffect 453 0.15 +#maxeffectvalue 453 2 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Unaging" +#name n "Unaging +[EFFECT479]%" +#paths n +#pathlevel 1 +#addeffect 479 25 +#scaleeffect 479 25 +#maxeffectvalue 479 100 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Disease Immunity" +#name d "Disease Immunity" +#paths d +#pathlevel 2 +#addeffect 513 100 -- disease resist +#alwaysactive 1 +#skipchance 50 +#end + +--#newbless "Astral Fetters" +--#name s "Astral Fetters" +--#paths s +--#pathlevel 2 +--#addeffect 563 1 +--#skipchance 50 +--#end + +#newbless "Recuperation" +#name n "Recuperation" +#paths n +#pathlevel 5 +#addeffect 568 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Masons" +#name e "Masons" +#paths e +#pathlevel 6 +#addeffect 594 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Dark Vessels" +#name a "Dark Vessels" +#name w "Dark Vessels" +#paths aw +#reqcrosspath 1 +#pathlevel 3 +#addeffect 645 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Autobless" +#name f "Always Blessed in Combat" +#paths f +#pathlevel 2 +#addeffect 684 1 +#alwaysactive 1 +#skipchance 50 +#end + +#newbless "Random Heroic Ability" +#name f "Commanders start w/ HoF Traits" +#paths f +#pathlevel 2 +#addeffect 672 100 +#alwaysactive 1 +#skipchance 50 +#end + + diff --git a/effectenum.txt b/effectenum.txt new file mode 100644 index 0000000..187110b --- /dev/null +++ b/effectenum.txt @@ -0,0 +1,571 @@ + COUNTS_AS_SUN=685, + COLD_REC=491, + DISEASE_GRINDER=356, + GUARDIAN_SPIRIT_MODIFIER=486, + DEATH_POWER=484, + CASTLE_DEFENCE_BONUS=215, + STARTMAJORAFF=610, + FOREST_SURVIVAL=422, + SOLAR_WEAPONS=543, + BATSTARTSUM7d6=447, + NOAGING=479, + CARCASS_COLLECTOR=658, + TWICEBORN_SHAPE=656, + START_ITEM=565, + ITEM_ONLY_USABLE_BY_UNIT_TYPE_MASK=456, + TAUROBOLIUM=651, + REANIMATE_ON_KILL_SHAPE=515, + FAST_CASTING=613, + PATROL_BONUS=170, + BLOOD_BOND=555, + LAND_DAMAGE=526, + REGENERATION=189, + DARK_VESSELS=645, + XPLOSS_ON_SHAPE_CHANGE=519, + CORPSE_EATER_NUM_CORPSES_EATEN=238, + ??DEFILER?=320, + NAMETYPE=251, + SLOTH_POWER=529, + POISON_BARBS=188, + DOMSUMMON20=219, + ?LAND_REINVIGORATION=680, + EYES=178, + STARTINGAFFLICTIONS=226, + SPELL_WALKABLE=707, + INSPIRATIONAL=368, + VOID_SANITY=277, + DEATH_CURSE=413, + HERO_TURN_ARRIVAL_LIMIT=534, + HEAT_AURA=316, + UNKNOWN_EFFECT_THAT_TARGETS_KILLER=433, + MIND_VESSEL=531, + AIRRANGE=41, + AIRATTUNED=502, + WATERRANGE=42, + BATSTARTSUM8d6=448, + THEFT_OF_SUN_AWE=520, + OBFUSCATE=419, + RETURNING_ON_DAMAGE=393, + CAUSE_UNREST=223, + ITEM_PREC_BONUS=181, + GOLD_MAKER=452, + GEMPROD_NATURE=36, + RESOURCE_SIZE=265, + ITEM_ONLY_USABLE_BY_FLIERS_OR_MOUNTED=457, + SPELL_REQFLY=715, + NATURERANGE=46, + START_AGE_MODIFIER=286, + ENCHREBATE_10GOLD=1000, + ITEMCOST2=597, + SPELL_HIDDENENCH=708, + FATEWEAVING=601, + STARTAGE=285, + ITEMCOST1=596, + DAMAGE_REVERSAL=202, + STARTDOM=242, + ???NOWISH=332, + SPELL_NOLANDTRACE=706, + SUMMON_ALLIES_1?=164, + INSANITY=309, + HORROR_SEED=289, + SEND_LESSER_HORROR_MULT=517, + STORM_POWER=174, + DOMREC=524, + SLAVER=642, + SPELL_ONLYOWNDST=709, + WATERATTUNED=503, + USE_RESTRICTED_ITEM=488, + SPELL_ONLYGEOSRC=702, + MAGICBOOST_S=14, + BATSTARTSUM5d6=445, + MAGICBOOST_ALL=22, + ITEM_CURSE_RANDOM_UNITS_IN_PROVINCE=225, + MAGICBOOST_W=12, + FOOLSCOUTS=420, + RECRUITMENT_LIMIT=381, + STUN=578, + UPGRADE_ETHEREAL_TO_TRUE=260, + MAGICBOOST_N=16, + ASTRALRANGE=44, + MAGICBOOST_D=15, + DUNGEON_CREATURE=481, + MAGICBOOST_A=11, + SUMMON_ALLIES_2?=165, + MAGICBOOST_F=10, + PETRIFY_ATTACKERS=104, + MAGICBOOST_E=13, + LEAVES_AFTER_BATTLE_IF_WOUNDED_OR_HAS_KILLED=409, + IS_ADVENTURER=460, + FOREIGNSHAPE=584, + DISEASE_EXPLOSION=401, + SPELL_ONLYGEODST=701, + STOLEN_STRENGTH=151, + HEALER_AUTO=354, + PLAGUE_DOCTOR=695, + TEMP_WATER_GEMS=346, + HEAT_REC=490, + COMBAT_FAR_CASTER=556, + ITEM_UNUSABLE_BY_UNIT_TYPE_MASK=455, + GEM_COLLECTOR=343, + SWALLOW_ON_TRAMPLE=373, + TEMP_FIRE_GEMS=344, + COLD_POWER=176, + SUMMON_ALLIES_3?=166, + %_MORE_LIKELY_TO_CAUSE_AFFLICTIONS=301, + TATTOO_BOAR=561, + UNTELEPORTABLE=376, + ITEM_LOSEEYE=370, + IND_AUTOBLESS=684, + ITEM_MORALE_BONUS=308, + BATSTARTSUM6d6=446, + REANIMATE_ON_KILL=514, + VOID_RETURNING=333, + ??GIVES_DEATH_GEMS_AFTER_BATTLE=570, + ITEM_MAXSIZE=385, + POISON_WEAPONS=538, + SECONDSHAPE_TYPE2=197, + START_AFFLICTION=185, + DOMSUMMON=241, + INSPIRING_RESEARCHER=341, + SPELL_NOCASTMINDLESS=404, + DEATH_EXPLOSION=135, + CURSE_BESTOWER=271, + SUMMON_ALLIES_4?=167, + AMBIDEXTROUS=217, + BLIND=171, + DESERTER=264, + CHARGE_BODY_10AN=547, + UNCURABLE_AFFLICTION=660, + CHAOS_RECRUITMENT=458, + MONSTER_SUMMONER_4?=142, + ADDRANDOMAGE=317, + REINVIGORATION=117, + SLAVE=380, + BUG_UW=428, + ITEM_REQEYES=454, + ??SEDUCTION_ABILITY?=298, + SPELL_ONLYFRIENDLYDST=738, + DOMINION_SPREADER=156, + THRONEKILL=628, + ITEM_AUTOBLESS=612, + COLD_WEAPONS=549, + BATSTARTSUM_1d3=690, + FEAR=183, + GRAPHICSIZE=372, + MAGIC_WEAPONS=542, + SPELL_ONLYCOASTSRC=713, + SUMMER_POWER=232, + LAND_ENCUMBRANCE=681, + POISON_AURA=106, + BATSTARTSUM3d6=443, + ?MAGICBOOST_B=17, + ITEM_WARNING=152, + POPULATION_KILLER=288, + ITEM_MAPSPEED=426, + ITEMDRAWSIZE=575, + IMMORTALITY_DOMINION=665, + PATHCOST=243, + ANIMAL_AWE=646, + BRINGER_OF_FORTUNE=228, + NOTSACRED=683, + AUTO_COM_MASTER=648, + RESOURCE_BONUS=407, + GEMPROD_EARTH=33, + NO_HOF=468, + PICUS_PROCAS_AXE=227, + SPELL_CASTTIME=723, + NO_MOVE_PEN_FROM_ARMOR=71, + MONTAGWEIGHT=699, + HPOVERFLOW=522, + ?ITEM_PEN_BONUS=162, + AI_SINGLE_REC=331, + COMBAT_CASTER=581, + BATSTARTSUM4d6=444, + WASTE_SURVIVAL=423, + SPELL_NOTFORNATION=279, + FORTUNE_TELLER=235, + TATTOO_BEAR=558, + HERETIC=184, + MIND_COLLAR_MAGNITUDE=666, + TRANSFORMATION=509, + STARTITEM=494, + EARTHRANGE=43, + UNDYING=415, + EYELOSS=126, + ITEM_NOFORGEBONUS=292, + ABOLETH=530, + DOMSHAPE=692, + ITEMSLOTS=182, + MOUNTAIN_SURVIVAL=421, + WINTER_POWER=234, + UNIFY=624, + SHAPECHANGE=193, + START_EFFECT_VALUE_1=662, + START_EFFECT_VALUE_2=663, + UNDISCIPLINED=367, + ?LIGHT_ON_UNIT=655, + REINCARNATION=304, + POISON_SKIN=518, + FIXED_RESEARCH=248, + CLEANSHAPE=465, + DEATHBANISH=434, + STARTAFFLICTION=609, + GROWHP=335, + BERSERK_WHILE_BLESSED=525, + DEATH_WEAPONS=540, + SWARM_BODY=338, + HPOVERSLOW=523, + HORROR_MARK_MELEE_ATTACKERS=127, + RANDOMSPELL=389, + SPY=214, + DEATH_RECRUITMENT=485, + BATSTARTSUM1d6=441, + INSANE_SHATTERED_SOUL_COMMAND_BLOCK=310, + FARSHOT_BLESS=548, + WITHERING_WEAPONS=539, + ADEPT_RESEARCHER=121, + STARTS_WITH_HEROIC_ABILITY=672, + ICE_FORGING=489, + PETRIFIED=580, + ASSASSIN=461, + UNHINDERED=577, + MONPRESENTREC=586, + ITEM_STEALTHBOOST=390, + ONI_SUMMONER=598, + SUMMERSHAPE=591, + ITEM_MR_BONUS=161, + ITEM_CHANCE_TO_BECOME_WEREWOLF=123, + SPELL_NEXTINGEO=724, + SALT_VULN=698, + ALCHEMIST=132, + ACID_DIGEST=496, + STONE_BEING=280, + IMMORTAL_TIMER?=147, + SIGHT_VENGEANCE=244, + RESTRICTEDITEM=487, + SPIRIT_SIGHT=607, + FIRE_SHIELD=652, + ASTRAL_FETTERS=563, + ITEM_WATERBREATHING=110, + DISEASE_RESISTANCE=513, + BATSTARTSUM2d6=442, + EXPLODE_ON_DEATH=297, + REANIMATION_BONUS_DIVINE=364, + FARSAIL=649, + BLOOD_SEARCHER=116, + REANIMATION_BONUS_ARCANE=365, + FORTKILL=627, + UNSEEN=688, + DRAKE=498, + FLAMING_WEAPONS=545, + TATTOO_SNAKE=562, + ICE_PROTECTION=191, + DIGEST=374, + STYGIAN_GUIDE=664, + ENCHREBATE_50PERCENT=678, + DEATHATTUNED=506, + FAR_THRONEKILL=629, + ADDITIONAL_LEADERSHIP=157, + TRIPLE3MON=625, + TEMP_ASTRAL_GEMS=348, + AUTO_COM_SLAVE_2=647, + INQUISITOR=211, + BLOODATTUNED=508, + REGENERATION_LIMITED=462, + MIND_COLLAR_ACTIVATED=667, + SPELL_ONLYATSITE=711, + DEATHWAIL=204, + SHRINKHP=336, + COLDSUMMON=146, + SPRING_POWER=231, + SPELLSINGER=616, + WATERSHAPE=246, + PILLAGER=131, + FIRE_RESISTANCE=198, + SUN_AWE=605, + OVERCHARGED=478, + REAPER=124, + PATHBOOST_LAND=51, + CURSED_LUCK=255, + ASTRAL_SHIELD=321, + TASKMASTER=379, + TRINITY=622, + DEFECTOR=467, + SAILSIZE=535, + SPELL_FARSUMMONCOM=716, + ITEM_YEARAGING=303, + FORMATION_FIGHTER=366, + PLAGUE_CARRIER=172, + SWAMP_SURVIVAL=424, + INSANIFY=315, + MUMMIFY=511, + MAXAGE=284, + NUMBER_OF_LOST_ARMS=800, + AI_NO_RECRUIT=429, + GEMPROD_FIRE=30, + NO_WISH=588, + ADDITIONAL_LDR_MAGIC=158, + TATTOO_WOLF=560, + DOM_MONSTER_SUMMON_RARE=417, + WISH_STRENGTH_BONUS=291, + SPELL_PROVRANGE=700, + SPELL_NOTMNR=744, + ITEM_HP_BONUS=305, + ITEM_NATION_RESTRICTED=278, + ITEM_CHANCE_TO_BE_SENT_TO_VOID=311, + ONEBATTLESPELL=209, + RECUPERATION=568, + SPELL_REQSUN=741, + INNATE_CASTER=334, + SAILING_SHIP_SIZE=112, + BUG=427, + SLEEP_AURA=306, + AUTOSUM=143, + ITEM_NATIONREBATE=574, + IS_YAZAD=492, + DIVINE_INSIGHTS=450, + STANDARD=103, + STUN_IMMUNE=638, + DRAGON_MASTER=270, + ??SPECIAL_PASSIVE_REANIMATOR=466, + FOREIGNPATHBOOST=52, + DEATHRANGE=45, + IMMUNE_TO_ARMOR_MAPMOVE_PENALTY=344, + FORGE_BONUS_FIXED=453, + COMMANDS_SLAVE_VESSEL=533, + ITEM_EFFECT_TAINTED=262, + DOM_MONSTER_AUTOSUM?=107, + NORANGE=634, + SECONDTMPSHAPE=196, + INVULNERABILITY=382, + CORPSE_EATER=236, + FLOATING=606, + CORRUPTOR=224, + FORGE_BONUS_PERCENTILE=118, + FLIES_WHEN_BLESSED=240, + SPELL_STRIKESOUND=721, + WOLF=659, + PLAIN_SHAPE=323, + SKIRMISHER=641, + INCORPORATE=375, + UW_REGEN=615, + SPELL_AIBADLVL=735, + ENCHREBATE_20GOLD=1001, + SPELL_POLYGETMAGIC=732, + AUTOSPELL_REPEAT=133, + UNHOLY_WEAPONS=544, + AUTUMNSHAPE=592, + BLESSING_OF_GOD_SLAYER=654, + NOTDOMSHAPE=693, + IS_ILLUSION=294, + ??CHANGE_GENDER_FOR_SEDUCTION=218, + FIRSTSHAPE=195, + MASTER_RITUALIST=463, + OFFSCRIPT_RESEARCH_LEVEL=388, + SPELL_SETHOME=733, + PROPHET_SHAPE=516, + COLD_RESISTANCE=201, + SAILING_MAX_UNIT_SIZE=410, + UNIQUE=275, + ??MOUNTAIN_RECRUIT=676, + FIRERANGE=40, + REFORM=394, + CHILL_AURA=220, + BEASTMASTER=369, + INFERNO_RETURNING=313, + IRON_VULN=689, + ADDITIONAL_LDR_UNDEAD=159, + SHATTERED_SOUL=328, + SECONDSHAPE=194, + ?NEEDNOTEAT=537, + TRINITY_MAG=623, + ITEM_ISLANCE=621, + MASTER_SMITH=363, + MAXPRISON=1003, + PROTECTIVE_FORCE=383, + PLANT=500, + ITEM_ATT_SKILL_BONUS=150, + SPELL_AINOCAST=742, + HEAT_AURA_UW=527, + SUPAYA_REANIMATION_COUNT=521, + SPELL_AISPELLMOD=743, + REALM=602, + AWE=105, + CLOCKWORK_LORD=249, + POWER_OF_THE_TURNING_YEAR=626, + PRETENDER_ORIGINAL_FORM=636, + POISON_RESISTANCE=200, + POLYMORPH_IMMUNE=635, + GEMPROD_AIR=31, + EXTRA_LIFE=115, + ARMY_HEALER=212, + MUNDANE_RESEARCHER=273, + UNSURROUNDABLE=573, + NOAGINGLAND=357, + SCALE_WALLS=483, + MAGIC_ATTUNED_RESEARCHER=618, + ACID_SHIELD=497, + ALLRANGE=25, + TEMP_EARTH_GEMS=347, + SUPPLYSIZE=307, + SPECIALLOOK=330, + MUST_FIGHT_IN_ARENA=459, + AUTO_COMSLAVE=432, + CHAOS_POWER=416, + INDEPMOVE=630, + REFORMING=337, + MONTAG=637, + ?PERCENT_MAX_HP_DAMAGE_EVERY_TURN=325, + SPELL_REQ_NO_ABILITY=719, + LOST_X_EYES=802, + DISBELIEVE=295, + PROMOTION=510, + GEMPROD_ASTRAL=34, + HORROR=391, + NO_ARMOR_MAPMOVE_PENALTY=583, + BLOODRANGE=47, + OWNSMONREC=587, + MIND_SLIMER=402, + MASON=594, + ASTRALATTUNED=505, + GEMPROD_BLOOD=37, + SUMMON_ALLIES_5?=168, + SUPPLY_BONUS=122, + ??USED_BY_SWARM_BODY_REFORMING=339, + MOUNTED_BERSERKER=639, + MONSTER_SUMMONER_3?=141, + LANDSHAPE=245, + AUTUMN_POWER=233, + TEMP_AIR_GEMS=345, + BODYGUARD=408, + SPELL_NOWATERTRACE=705, + STORM_IMMUNITY=175, + ALL_PLANE_RETURNING=435, + HORROR_MARK=261, + HOMESICK=253, + ISLANCE=669, + ?IMMORTALITY_REFORM_TIME_SCALE_WITH_DIST=149, + LAMIABONUS=169, + TEMP_DEATH_GEMS=349, + INVISIBLE=608, + MONSTER_SUMMONER_2?=140, + ITEM_CHAMPPRIZE=239, + ELEMENTRANGE=23, + DEFENCE_ORGANIZER=352, + MAGIC_POWER=324, + ADEPT_CROSSBREEDER=431, + PHILOSOPHER=272, + BATTLESUM4=398, + VINE_SHIELD_EFFECT=128, + BATTLESUM3=397, + REGEN_UW=221, + IVY_LORD=101, + BATTLESUM5=399, + GIFT_OF_WATER_BREATHING=111, + ITEM_DEF_SKILL_BONUS=377, + CANNOT_PASS_RIVERS=418, + TEMP_NATURE_GEMS=350, + LORD_OVER_HEATHEN_TRIBES=686, + DREAM_SEDUCTION=210, + INDEP_SPELL_LEVEL_PLUS_ONE=480, + SLAVER_BONUS=643, + UWDAMAGE=258, + SORCERYRANGE=24, + MUMMIFY_PARTNER=512, + MONSTER_SUMMONER_1?=139, + STARTS_HORRORMARKED=471, + SPREAD_NEGATIVE_SCALE=472, + TEMPLE_TRAINER=564, + SLIMER=412, + EARTHATTUNED=504, + SPELL_FRIENDLY_ENCHANTMENT=729, + GEMPROD_DEATH=35, + LAND_REINVIGORATION=300, + SWIFTNESS=595, + BATSTARTSUM1=436, + SPELL_MAXBOUNCES=617, + TURMOILSUMMON=173, + BATSTARTSUM5=440, + BATSTARTSUM4=439, + BATSTARTSUM3=438, + BATSTARTSUM2=437, + FIRE_SHIELD_UW=653, + AIR_SHIELD=208, + IS_DAEVA=493, + BANEFIRE_SHIELD=222, + HOMESHAPE=585, + RESEARCH_WITHOUT_MAGIC=451, + CORPSE_EATER_HP_PER_CORPSE=237, + MIN_IMPRISONMENT=600, + FATIGUE_SACRED_AURA=326, + HALT_HERETIC=327, + PARALYZED=186, + ITEM_LESSER_HORROR_ATTACK_CHANCE=120, + BATTLESUM2=396, + BATTLESUM1=395, + THUNDER_WEAPONS=546, + BECKON=247, + MIN_SIZE_LEADER=644, + KOKYTOS_RETURNING=314, + PERCENT_PATH_REDUCTON=187, + PATHBOOST_UW=50, + CORPSELORD=154, + UNKNOWN_INVOLVED_IN_BLOOD_SLAVE_USAGE=687, + BERSERKER=190, + ADDUPKEEP=589, + INDEPSTAY=631, + REANIMATOR_PRIEST=632, + BATSTARTSUM9d6=449, + DISEASE_HEALER=355, + LAB_PROMOTION=668, + FOREST_SHAPE=322, + ADEPT_SACRIFICER=216, + SPRINGSHAPE=590, + TEMP_BLOOD_SLAVES=351, + FIREATTUNED=501, + SPELL_GODPATHSPELL=722, + SHOCK_RESISTANCE=199, + EXTRA_ARMS=361, + REQ_LAB_TO_RECRUIT=469, + CAN_USE_LANCES=670, + SPREAD_POSITIVE_SCALE=473, + SPELL_NOGEODST=703, + BLOOD_SURGE_MAGNITUDE=554, + DESICCATION=250, + ENCASE_IN_ICE=299, + DARKVISION=281, + IS_SLAVE_VESSEL=532, + PATIENCE=205, + SPELL_ONLYMNR=731, + ENCHREBATE_50GOLD=1002, + NEVER_HEALS=614, + DARK_POWER=293, + DOMINION_POWER=694, + WINTERSHAPE=593, + ALTERNATIVE_FIRSTSHAPE_EATER_OF_DEAD=392, + REQ_TEMPLE_TO_RECRUIT=470, + BLOOD_VENGEANCE=414, + STEALTHY=108, + NATUREATTUNED=507, + SPELL_REQ_UNITABILITY=718, + AFFLICTION_RESISTANCE=406, + ?IMMORTALITY_SPRING=153, + SPELL_NOGEOSRC=703, + TATTOO_HORSE=559, + ITEM_MINSIZE=384, + SIEGE_BONUS=125, + ?WINTER_SUMMON_1D3=671, + BLESS_TWIST_FATE=541, + PEARL_CULTIVATOR=430, + ASSASSIN_2?=213, + TAX_COLLECTOR=342, + ELEGIST=411, + ?SHAPECHANCE=192, + SUMMONING_SKILL=206, + SWIMMING=571, + FIRE_POWER=177, + GEMPROD_WATER=32, + DOOM_GREATER_HORROR_DESERTION=274, + ENCHREBATE_25PERCENT=677, + ?DO_NOT_RETAIN_BUFFS2_AFTER_COMBAT=569 + diff --git a/exceptions.py b/exceptions.py new file mode 100644 index 0000000..831cca9 --- /dev/null +++ b/exceptions.py @@ -0,0 +1,2 @@ +class ParseError(Exception): + pass diff --git a/fileparser/__init__.py b/fileparser/__init__.py new file mode 100644 index 0000000..f41d18b --- /dev/null +++ b/fileparser/__init__.py @@ -0,0 +1 @@ +from . import blesstemplate \ No newline at end of file diff --git a/fileparser/blesstemplate.py b/fileparser/blesstemplate.py new file mode 100644 index 0000000..42cd56d --- /dev/null +++ b/fileparser/blesstemplate.py @@ -0,0 +1,168 @@ +import os +import re +import utils +import traceback + +from blesstemplate import BlessTemplate +from exceptions import ParseError +import fileparserutils + +simple_params_int = ["paths","pathlevel", "effect10buffs", "multipick", "alwaysactive", "reqcrosspath", "skipchance"] +simple_params_str = ["descr"] +simple_params_float = [] + + +def readEffectFile(fp): + "Read one file and return all the bless effects within." + try: + lineno = None + out = {} + curreff = None + with open(fp, "r") as f: + for lineno, line in enumerate(f): + line = line.strip() + if line == "": continue + if line.startswith("--"): continue + + if line.startswith("#newbless"): + if curreff is not None: + raise ParseError( + f"{fp} line {lineno}: Unexpected #neweffect (still parsing previous effect)") + m = re.match("#newbless\W+\"(.*)\"\W*$", line) + if m is None: + raise ParseError(f"{fp} line {lineno}: Expected an effect name, none was found") + curreff = BlessTemplate(fp) + curreff.name = m.groups()[0] + currPriority = 0 + + else: + if curreff is None: + raise ParseError(f"{fp} line {lineno}: Expected a #neweffect line") + + sorted = False + + # Params to simply copy + for simple in simple_params_int: + if fileparserutils.parsesimpleint(simple, line, curreff): + sorted = True + break + + if sorted: continue + + for simple in simple_params_str: + m = re.match(f"#{simple}" + "\\W+?\"(.*)\"\\W*", line) + if m is not None: + pval = m.groups()[0] + setattr(curreff, simple, pval) + sorted = True + continue + + if sorted: continue + + for simple in simple_params_float: + m = re.match(f"#{simple}\W+?([-.0-9]+)\W*$", line) + if m is not None: + pval = float(m.groups()[0]) + setattr(curreff, simple, pval) + sorted = True + continue + + if sorted: continue + + if line.startswith("#addeffect"): + m = re.match('#addeffect\\W+([-0-9]+)\\W+?([-.0-9]+)', line) + if m is None: + raise ParseError(f"{fp} line {lineno}: bad #addeffect") + effect = int(m.groups()[0]) + magnitude = int(m.groups()[1]) + if effect in curreff.effects: + raise ParseError(f"Attempting to assign effect {effect} to {cureff.name} twice") + curreff.effects[effect] = magnitude + continue + + if line.startswith("#scaleeffect"): + m = re.match('#scaleeffect\\W+([-0-9]+)\\W+?([-.0-9]+)', line) + if m is None: + raise ParseError(f"{fp} line {lineno}: bad #scaleeffect") + effect = int(m.groups()[0]) + magnitude = float(m.groups()[1]) + if effect in curreff.scaleeffects: + raise ParseError(f"Attempting to set scaling for {effect} on {cureff.name} twice") + curreff.scaleeffects[effect] = magnitude + continue + + if line.startswith("#posscaleaffinity"): + m = re.match('#posscaleaffinity\\W+([-0-9]+)\\W+([-0-9]+)', line) + if m is None: + raise ParseError(f"{fp} line {lineno}: bad #posscaleaffinity") + effect = int(m.groups()[0]) + magnitude = float(m.groups()[1]) + if effect in curreff.posscaleaffinities: + raise ParseError(f"Attempting to set posscaleaffinity for {effect} on {cureff.name} twice") + curreff.posscaleaffinities[effect] = magnitude + continue + + if line.startswith("#negscaleaffinity"): + m = re.match('#negscaleaffinity\\W+([-0-9]+)\\W+([-0-9]+)', line) + if m is None: + raise ParseError(f"{fp} line {lineno}: bad #negscaleaffinity") + effect = int(m.groups()[0]) + magnitude = int(m.groups()[1]) + if effect in curreff.negscaleaffinities: + raise ParseError(f"Attempting to set negscaleaffinity for {effect} on {cureff.name} twice") + curreff.negscaleaffinities[effect] = magnitude + continue + + if line.startswith("#maxeffectvalue"): + m = re.match('#maxeffectvalue\\W+([-0-9]+)\\W+([-0-9]+)', line) + if m is None: + raise ParseError(f"{fp} line {lineno}: bad #addeffect") + effect = int(m.groups()[0]) + magnitude = int(m.groups()[1]) + if effect in curreff.maxeffectvalues: + raise ParseError(f"Attempting to set max value for {effect} on {cureff.name} twice") + curreff.maxeffectvalues[effect] = magnitude + continue + + if line.startswith("#name"): + m = re.match('#name\\W+(.*?)\\W+"(.*)"', line) + if m is None: + raise ParseError(f"{fp} line {lineno}: bad #name") + paths = fileparserutils.parsepathalias(m.groups()[0]) + for path in utils.breakdownflagcomponents(paths): + if path not in curreff.names: + curreff.names[path] = [] + curreff.names[path].append(m.groups()[1]) + continue + + if line.startswith("#end"): + out[curreff.name] = curreff + curreff = None + continue + + raise ParseError(f"{fp} line {lineno}: Unrecognised content: {line}") + return out + except: + print(traceback.format_exc()) + if lineno is not None: + raise ParseError(f"Failed to read {fp}, failed at line {lineno}") + else: + raise ParseError(f"Failed to read {fp}, undetermined line") + + +def readEffectsFromDir(dir): + out = utils.blesseffects + new = [] + for f in os.listdir(dir): + if f.endswith(".txt"): + c = readEffectFile(os.path.join(dir, f)) + for key in c: + if key in out: + raise ParseError(f"Bless named {key} already exists and was redefined in {f}") + out[key] = c[key] + new.append(key) + o = {} + for key in new: + o[key] = out[key] + return o + diff --git a/fileparserutils.py b/fileparserutils.py new file mode 100644 index 0000000..dbdebb0 --- /dev/null +++ b/fileparserutils.py @@ -0,0 +1,85 @@ +import re + +def parsepathalias(alias): + try: + return int(alias) + except ValueError: + pass + tmp = alias.replace(" ", "").replace("+", "").lower() + shortformchars = {"f":1, "a":2, "w":4, "e":8, "s":16, "d":32, "n":64, "b":128, "h":256} + longform = {"none":-1, "fire":1, "air":2, "water":4, "earth":8, "astral":16, "death":32, "nature":64, + "blood":128, "holy":256} + isshortform = True + ret = 0 + for char in tmp: + if char not in shortformchars: + isshortform = False + break + ret |= shortformchars[char] + if isshortform: + print(f"Shortform paths: {alias} -> {ret}") + return ret + tmp = alias.replace(" ", "").lower() + components = tmp.split("+") + ret = 0 + for component in components: + if component in shortformchars: + ret |= shortformchars[component] + else: + if component in longform: + ret |= longform[component] + else: + try: + ret += int(component) + except: + raise ValueError(f"Unrecognised path alias {component} in string {alias}") + print(f"Longform paths: {alias} -> {ret}") + return ret + +def parsesimpleint(simple, line, curreff): + if simple in ["schools"]: + specialparser = parseschool + elif simple in ["paths", "secondarypaths"]: + specialparser = parsepathalias + else: + specialparser = None + if specialparser is not None: + m = re.match(f"#{simple}\\W+?(.*?)\\W*$", line) + if m is None: + #raise Exception(f"Failed special parser {specialparser.__name__} for line {line}") + return False + setattr(curreff, simple, specialparser(m.groups()[0])) + return True + + m = re.match(f"#{simple}\\W+?([-0-9+^ ]*)\\W*$", line) + if m is not None: + arg = m.groups()[0].strip() + try: + pval = int(arg) + setattr(curreff, simple, pval) + return True + except ValueError: + print(f"{line} is not a simple int") + arg = arg.replace(" ","") + # Do powers first + if "^" in arg: + while "^" in arg: + m = re.search("([0-9]*)\\W*?\\^\\W*?([0-9]*)", arg) + if m is None: + raise ValueError(f"Error while parsing exponent in: {line}") + prev = int(m.groups()[0]) + after = int(m.groups()[1]) + val = prev ** after + arg = re.sub("([0-9]*)\\W*?\\^\\W*?([0-9]*)", str(val), arg, 1) + print(f"After exponent replaces: {arg}") + + + components = arg.split("+") + real = 0 + for component in components: + component = component.strip() + real += int(component) + print(f"Parser addition: {line} -> {real}") + setattr(curreff, simple, real) + return True + return False diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..ea202bd --- /dev/null +++ b/readme.md @@ -0,0 +1,25 @@ +# BlessGen + +This tool generates semi-random bless effects for Illwinter's Dominions 5. Using its output requires [the Blessmodder tool](https://github.com/Logg-y/blessmodder) I wrote. + +Describing this as "procedurally generated" might be a bit of a stretch: essentially this tool draws 99 effects out of a pool of several hundred and presents them as options, in a way that makes a nice spread of paths and point costs. Unlike other similar tools for Dominions, there are (figuratively) not very many possible permutations. While bless effect descriptions remain unmoddable, this will likely not dramatically change: it is very difficult to explain compounded bless effects in a mere 31 characters. + +Effects that can be taken multiple times (like vanilla Undying) are marked with an asterisk at the end of their names. + +## Answers to anticipated questions + +See the caveats section of Blessmodder's readme for side effects relating to modifing bless data within executables. + +Test to make sure things work as you'd expect before committing to your build in multiplayer. Please. I won't have caught all my mistakes. + +Many bless effects that say +X will stack with attributes on units that have them already. Others, such as "Solar Weapons +5" means that weapons do 5 AP fire damage, x3 vs undead/demons; NOT +8. (The reason one might think this is in the base game Solar Weapons always have a value of three, but in reality there are no hard limits on the damage they can deal!) + +"Summon: (Creature)" means that all sacred commanders gain the Summon Allies command to summon one of the named creature type. + +"Retinue: (Creature)" means that all sacred units summon one of the named creatures at the start of every battle. + +"Prophet" or "Prophet Shape: (Creature)" means that all appointed prophets will immediately become one of the named creature type. + +"Temple Train: (Creature)" means that all sacred commanders gain the Temple Trainer command, allowing them to spend a turn at a temple to create one of the named creatures. Only one commander may train at each temple. + +Taking multiple of same type of creature related effect is a waste of points: it will cause only the creature with the highest ID to be used. So if you took Summon: Wolf and Summon: Dispossessed Spirit, the summon allies command would yield only a dispossessed spirit (ID 674) over a wolf (ID 284). \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..b4de2c9 --- /dev/null +++ b/setup.py @@ -0,0 +1,68 @@ +# This script should NOT BE EXECUTED DIRECTLY +# use "python setup.py build" instead (this is how you correctly invoke cx_freeze) + +import os +import shutil +import zipfile +import time +import re +import cx_Freeze + +if os.path.isdir("build"): + shutil.rmtree("build") + +# Apparently importing the actual script that is built is bad practice and may cause issues +ver = None +with open("blessgen.py", "r") as f: + for line in f: + m = re.match('ver = "(.*)"', line) + if m is not None: + ver = m.groups()[0] + print(f"Found version: {ver}") + break + +if ver is None: + raise Exception("Failed to find version") + +build_exe_options = {"include_msvcr": False, "excludes": ["distutils", "test"]} + +cx_Freeze.setup(name="BlessGen", version=ver, + description="BlessGen: A random bless effect generator for Dominions 5", + options={"build_exe": build_exe_options}, + executables=[cx_Freeze.Executable("blessgen.py")]) + +# Permissions. +time.sleep(5) + +buildfilename = os.listdir("build")[0] +os.rename(f"build/{buildfilename}", f"build/blessgen-{ver}") + +# cx_Freeze tries to include a bunch of dlls that Windows users may not have permissions to distribute +# but should be present on any recent system (and available through the MS VC redistributables if not) +# therefore clear them from the distribution + +for root, dirs, files in os.walk(f"build/blessgen-{ver}"): + for file in files: + if file.startswith("api-ms") or file in ["ucrtbase.dll", "vcruntime140.dll"]: + print(f"Strip file {file} from output...") + os.unlink(os.path.join(root, file)) + elif "api-ms" in file: + print(f"Not stripping {file}, but maybe should be?") + +shutil.copy("LICENSE", f"build/blessgen-{ver}/LICENSE") +shutil.copy("readme.md", f"build/blessgen-{ver}/readme.md") +shutil.copy("changelog.txt", f"build/blessgen-{ver}/changelog.txt") +shutil.copy("effectenum.txt", f"build/blessgen-{ver}/effectenum.txt") + +shutil.copytree("data", f"build/blessgen-{ver}/data") +os.mkdir(f"build/blessgen-{ver}/output") + +# change working dir so the /build folder doesn't end up in the zip +os.chdir("build") + +zipf = zipfile.ZipFile(f"blessgen-{ver}.zip", "w", zipfile.ZIP_DEFLATED) +for root, dirs, files in os.walk(f"blessgen-{ver}"): + for file in files: + zipf.write(os.path.join(root, file)) + +zipf.close() \ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..47e6131 --- /dev/null +++ b/utils.py @@ -0,0 +1,83 @@ +import re + +START_BLESS_ID = 1 +START_UNIT_ID = 3501 +blesseffects = {} +EFFECT_IDS_TO_LABELS = {} + +def loadEffectLabels(): + global EFFECT_IDS_TO_LABELS + if len(EFFECT_IDS_TO_LABELS) == 0: + with open("effectenum.txt", "r", encoding="utf8") as f: + for line in f: + if line.strip() == "": + continue + m = re.match("\\W*(.*)=(\\d*)", line) + if m is None: + raise ValueError(f"Bad effect enum line: {line}") + effectID = int(m.group(2)) + effectLabel = m.group(1) + print(f"{effectID} -> {effectLabel}") + EFFECT_IDS_TO_LABELS[effectID] = effectLabel + +def _selectFlag(flagpool, allowed): + "From flagpool, chooses one bitflag at random which is specified in allowed. Returns None if there were no flags to return" + l = [] + for x in flagpool: + if x.value > -1: + if allowed & x: + l.append(x) + if len(l) == 0: + return None + return random.choice(l) + + +def breakdownflag(flag): + "Split a given bitflag into a list of exponents such that sum([2 ** x for x in breakdownflag(flag)]) == flag" + n = 0 + out = [] + while 1: + if 2 ** n > flag: return out + if flag & 2 ** n: out.append(n) + n += 1 + +def breakdownflagcomponents(flag): + "Split a given bitflag into a list of its components, such that sum(breakdownflag(flag)) == flag" + n = 0 + out = [] + while 1: + if 2 ** n > flag: return out + if flag & 2 ** n: out.append(2**n) + n += 1 + + +def pathstotext(path: int) -> str: + acc = "" + if path & PathFlags.FIRE: + acc += "F" + if path & PathFlags.AIR: + acc += "A" + if path & PathFlags.WATER: + acc += "W" + if path & PathFlags.EARTH: + acc += "E" + if path & PathFlags.ASTRAL: + acc += "S" + if path & PathFlags.DEATH: + acc += "D" + if path & PathFlags.NATURE: + acc += "N" + if path & PathFlags.BLOOD: + acc += "B" + if acc == "": + acc += "_" + return acc + + +def _writetoconsole(line): + """Because PyInstaller and PySimpleGUI don't play nice unless specifying STDIN as well, I had to make + this be converted to exe with --window to avoid the console coming up. + For some reason after doing that, sys.stderr has to be flushed after every line to allow the GUI process + to pick it up""" + sys.stderr.write(line) + sys.stderr.flush()