### Spell casting def OnGetBaseCasterLevel(attachee, args, evt_obj): if (evt_obj.arg0 != classEnum): return 0 classLvl = attachee.stat_level_get(classEnum) caster_levels = classSpecModule.GetCasterLevels() base_cl = char_class_utils.GetBaseCasterLevel(caster_levels, classLvl) if base_cl <= 0: return 0 evt_obj.bonus_list.add(base_cl, 0, 137) return 0 def OnLevelupSpellsFinalize(attachee, args, evt_obj): if (evt_obj.arg0 != classEnum): return 0 classSpecModule.LevelupSpellsFinalize(attachee) return # spellCasterSpecObj = PythonModifier(GetSpellCasterConditionName(), 8) # spellCasterSpecObj.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender = PythonModifier() classSpecExtender.ExtendExisting("Ranger") classSpecExtender.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Finalize, OnLevelupSpellsFinalize, ())
import tpdp print "Registering Extra Smiting" def ExtraSmitingNewDayDestructionDomain(attachee, args, evt_obj): ExtraSmiting = attachee.has_feat("Extra Smiting") #Extra Smiting grants 2 additional uses of smite each time the feat is taken args.set_arg(0, args.get_arg(0) + 2 * ExtraSmiting) return 0 extendDestructionDomain = PythonModifier() extendDestructionDomain.ExtendExisting("Destruction Domain") extendDestructionDomain.AddHook(ET_OnNewDay, EK_NEWDAY_REST, ExtraSmitingNewDayDestructionDomain, ()) def ExtraSmitingNewDaySmiteEvil(attachee, args, evt_obj): ExtraSmiting = attachee.has_feat("Extra Smiting") #Extra Smiting grants 2 additional uses of smite each time the feat is taken args.set_arg(0, args.get_arg(0) + 2 * ExtraSmiting) return 0 extendSmiteEvil = PythonModifier() extendSmiteEvil.ExtendExisting("Smite Evil") extendSmiteEvil.MapToFeat(feat_smite_evil)
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Combat Casting extender" def CombatCastingBonus(attachee, args, evt_obj): evt_obj.return_val += 4 return 0 def CombatCastingUsed(attachee, args, evt_obj): print "Removing" args.condition_remove() print "Removing - Done" return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Combat_Casting") modExtender.AddHook(ET_OnD20PythonQuery, "Combat Casting Bonus", CombatCastingBonus, ()) modExtender.AddHook(ET_OnD20PythonSignal, "Combat Casting Used", CombatCastingUsed, ())
print "Registering Extra Music" def EMNewDay(attachee, args, evt_obj): ExtraMusicCount = attachee.has_feat("Extra Music") #Extra Music grants 4 additional uses of Bardic Music each time the feat is taken MusicCount = args.get_arg(0) MusicCount += ExtraMusicCount * 4 MusicCount += attachee.d20_query("Bardic Music Bonus Levels") args.set_arg(0, MusicCount) return 0 def QueryMaxBardicMusic(attachee, args, evt_obj): #Total uses = bard level + extra music count * 4 + Bard Bonus Levels MaxMusicCount = attachee.has_feat("Extra Music") * 4 MaxMusicCount += attachee.stat_level_get(stat_level_bard) MaxMusicCount += attachee.d20_query("Bardic Music Bonus Levels") evt_obj.return_val = MaxMusicCount return 0 eSF = PythonModifier() eSF.ExtendExisting("Bardic Music") eSF.AddHook(ET_OnNewDay, EK_NEWDAY_REST, EMNewDay, ()) eSF.AddHook(ET_OnD20PythonQuery, "Max Bardic Music", QueryMaxBardicMusic, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Shield Extender" def MaxDexShield(attachee, args, evt_obj): shield = attachee.item_worn_at(item_wear_shield) if shield != OBJ_HANDLE_NULL: max_dex_bonus = shield.get_max_dex_bonus() if max_dex_bonus > 0: capType = 3 # Effects Dex Bonus bonusMesline = 112 # Bonus Reduced by item evt_obj.bonus_list.set_cap_with_custom_descr( capType, max_dex_bonus, bonusMesline, shield.description) return 0 shieldBonusExtender = PythonModifier() shieldBonusExtender.ExtendExisting("Shield Bonus") shieldBonusExtender.AddHook(ET_OnGetAC, EK_NONE, MaxDexShield, ())
return 0 classSpecModule.InitSpellSelection(attachee) return 0 def OnLevelupSpellsFinalize(attachee, args, evt_obj): if evt_obj.arg0 != classEnum: return 0 classSpecModule.LevelupSpellsFinalize(attachee) return def ArcaneSpellFailure(attachee, args, evt_obj): if evt_obj.data1 != classEnum and evt_obj.data1 != stat_level_sorcerer: return 0 equip_slot = evt_obj.data2 item = attachee.item_worn_at(equip_slot) if item == OBJ_HANDLE_NULL: return 0 evt_obj.return_val += item.obj_get_int(obj_f_armor_arcane_spell_failure) return 0 classSpecExtender = PythonModifier() classSpecExtender.ExtendExisting("Wizard") classSpecExtender.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Activate, OnInitLevelupSpellSelection, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Finalize, OnLevelupSpellsFinalize, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Check_Complete, OnLevelupSpellsCheckComplete, ()) classSpecExtender.AddHook(ET_OnD20Query, EK_Q_Get_Arcane_Spell_Failure, ArcaneSpellFailure, ())
return 0 #classSpecObj = PythonModifier(GetConditionName(), 0) #classSpecObj.AddHook(ET_OnToHitBonusBase, EK_NONE, OnGetToHitBonusBase, ()) #classSpecObj.AddHook(ET_OnSaveThrowLevel, EK_SAVE_FORTITUDE, OnGetSaveThrowFort, ()) #classSpecObj.AddHook(ET_OnSaveThrowLevel, EK_SAVE_REFLEX, OnGetSaveThrowReflex, ()) #classSpecObj.AddHook(ET_OnSaveThrowLevel, EK_SAVE_WILL, OnGetSaveThrowWill, ()) ### Spell casting def OnGetBaseCasterLevel(attachee, args, evt_obj): if (evt_obj.arg0 != classEnum): return 0 classLvl = attachee.stat_level_get(classEnum) evt_obj.bonus_list.add(classLvl, 0, 137) return 0 def OnLevelupSpellsFinalize(attachee, args, evt_obj): if (evt_obj.arg0 != classEnum): return 0 classSpecModule.LevelupSpellsFinalize(attachee) return # spellCasterSpecObj = PythonModifier(GetSpellCasterConditionName(), 8) # spellCasterSpecObj.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender = PythonModifier() classSpecExtender.ExtendExisting("Druid") classSpecExtender.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Finalize, OnLevelupSpellsFinalize, ())
def OnGetSaveThrowFort(attachee, args, evt_obj): value = char_class_utils.SavingThrowLevel(classEnum, attachee, D20_Save_Fortitude) evt_obj.bonus_list.add(value, 0, 137) return 0 def OnGetSaveThrowReflex(attachee, args, evt_obj): value = char_class_utils.SavingThrowLevel(classEnum, attachee, D20_Save_Reflex) evt_obj.bonus_list.add(value, 0, 137) return 0 def OnGetSaveThrowWill(attachee, args, evt_obj): value = char_class_utils.SavingThrowLevel(classEnum, attachee, D20_Save_Will) evt_obj.bonus_list.add(value, 0, 137) return 0 def RogueSneakAttackDice(attachee, args, evt_obj): rogLvl = attachee.stat_level_get(classEnum) rogLvlBonus = attachee.d20_query("Rogue Sneak Attack Level Bonus") rogLvl = rogLvl + rogLvlBonus if evt_obj.data1 == classEnum: #class leveling up rogLvl = rogLvl + 1 if rogLvl <= 0: return 0 evt_obj.return_val += 1+ (rogLvl - 1)/2 return 0 classSpecExtender = PythonModifier() classSpecExtender.ExtendExisting("Rogue") classSpecExtender.AddHook(ET_OnD20PythonQuery, "Sneak Attack Dice", RogueSneakAttackDice, ())
#Fix for bug 184 Stinking Cloud: Nauseated creatures still make Attacks of opportunity but not normal attacks. from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Stinking Cloud AOO Fix" def StinkingCloudEffectAOOPossible(attachee, args, evt_obj): # No making AOOs when Nauseated evt_obj.return_val = 0 return 0 stinkingCloudEffect = PythonModifier() stinkingCloudEffect.ExtendExisting("sp-Stinking Cloud Hit") stinkingCloudEffect.AddHook(ET_OnD20Query, EK_Q_AOOPossible, StinkingCloudEffectAOOPossible, ())
if equip_slot == item_wear_armor: # bards can cast in light armor with no spell failure armor_flags = item.obj_get_int(obj_f_armor_flags) if (armor_flags & ARMOR_TYPE_NONE) or (armor_flags == ARMOR_TYPE_LIGHT): return 0 if attachee.d20_query("Improved Armored Casting") and ( armor_flags == ARMOR_TYPE_MEDIUM): return 0 evt_obj.return_val += item.obj_get_int(obj_f_armor_arcane_spell_failure) return 0 classSpecExtender = PythonModifier() classSpecExtender.ExtendExisting("Bard") classSpecExtender.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Activate, OnInitLevelupSpellSelection, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Finalize, OnLevelupSpellsFinalize, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Check_Complete, OnLevelupSpellsCheckComplete, ()) classSpecExtender.AddHook(ET_OnD20Query, EK_Q_Get_Arcane_Spell_Failure, BardSpellFailure, ()) bardFascEnum = 801
#Extend Rage: Complete Warrior, p. 97 from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Extend Rage" def AddCondition(attachee, args, evt_obj): #Add 5 rounds for the extend rage feat if attachee.has_feat("Extend Rage"): args.set_arg(0, args.get_arg(0) + 5) return 0 extendRageFeat = PythonModifier() extendRageFeat.ExtendExisting("Barbarian_Raged") extendRageFeat.AddHook(ET_OnConditionAdd, EK_NONE, AddCondition, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Combat Expertise Extender" def CombatExpertiseValue(attachee, args, evt_obj): evt_obj.return_val = args.get_arg(0) return 0 powerAttackExtender = PythonModifier() powerAttackExtender.ExtendExisting("Feat Expertise") powerAttackExtender.MapToFeat(feat_combat_expertise) powerAttackExtender.AddHook(ET_OnD20PythonQuery, "Combat Expertise Value", CombatExpertiseValue, ())
import tpdp print "Registering Greater Turn Undead extender" # Fix greater turning so it is usable once per day and uses up a turn undead charge (bug 071). # SRD: Once per day, you can perform a greater turning against undead in place of a # regular turning. The greater turning is like a normal turning except that the undead # creatures that would be turned are destroyed instead. #Called to deduct a turn undeac charge def DeductGreaterTurnUndeadCharge(attachee, args, evt_obj): NewCharges = args.get_arg(1) - 1 if NewCharges > 0: args.set_arg(1, NewCharges) else: args.set_arg(1, 0) return 0 def OnNewDay(attachee, args, evt_obj): args.set_arg(1, 1) #One Charge Per Day return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Greater Turning") modExtender.AddHook(ET_OnNewDay, EK_NEWDAY_REST, OnNewDay, ()) modExtender.AddHook(ET_OnD20PythonSignal, "Deduct Greater Turn Undead Charge", DeductGreaterTurnUndeadCharge, ())
### Spell casting def OnGetBaseCasterLevel(attachee, args, evt_obj): if (evt_obj.arg0 != classEnum): return 0 classLvl = attachee.stat_level_get(classEnum) caster_levels = classSpecModule.GetCasterLevels() base_cl = char_class_utils.GetBaseCasterLevel(caster_levels, classLvl) if base_cl <= 0: return 0 evt_obj.bonus_list.add(base_cl, 0, 137) return 0 def OnLevelupSpellsFinalize(attachee, args, evt_obj): if (evt_obj.arg0 != classEnum): return 0 classSpecModule.LevelupSpellsFinalize(attachee) return # spellCasterSpecObj = PythonModifier(GetSpellCasterConditionName(), 8) # spellCasterSpecObj.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender = PythonModifier() classSpecExtender.ExtendExisting("Paladin") classSpecExtender.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Finalize, OnLevelupSpellsFinalize, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Rapid Shot Ranger extender" def RapidShotEnabled(attachee, args, evt_obj): evt_obj.return_val = args.get_arg(0) return 0 rapidShotRangerExtender = PythonModifier() rapidShotRangerExtender.ExtendExisting("Rapid_Shot_Ranger") rapidShotRangerExtender.MapToFeat(feat_ranger_rapid_shot) rapidShotRangerExtender.AddHook(ET_OnD20PythonQuery, "Rapid Shot Ranger Enabled", RapidShotEnabled, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Fighting Defensively addendum" def IsFightingDefensively(attachee, args, evt_obj): #Return true value on fighting defensively or total defense if (args.get_arg(0) != 0) or (args.get_arg(1) != 0): evt_obj.return_val = 1 return 0 return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Fighting Defensively") modExtender.AddHook(ET_OnD20Query, EK_Q_FightingDefensively, IsFightingDefensively, ())
return 0 # Called to deduct a wild shape charge def DeductWildshapeCharge(attachee, args, evt_obj): #Wildshape charges are the lower bits, elemental charges are the higher bits numTimes = args.get_arg(0) numTimes = numTimes & 0xFF #Deduct one regular wild shape charge (make sure there is at least one or things could get really goofed up) if numTimes > 0: wildshapeValue = args.get_arg(0) - 1 args.set_arg(0, wildshapeValue) return 0 def WildshapeConditionAdded(attachee, args, evt_obj): #Used by the C++ side to make sure the condition does not get added multiple times evt_obj.return_val = 1 return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Wild Shaped") #Note: Arg 0 = number of charges modExtender.AddHook(ET_OnD20PythonSignal, "Deduct Wild Shape Charge", DeductWildshapeCharge, ()) modExtender.AddHook(ET_OnD20PythonQuery, "Wild Shape Charges", GetWildshapeCharges, ()) modExtender.AddHook(ET_OnD20PythonQuery, "Wild Shaped Condition Added", WildshapeConditionAdded, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Opportunist extender" def OpportunistReset(attachee, args, evt_obj): args.set_arg(0, 1) return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Opportunist") modExtender.AddHook(ET_OnBeginRound, EK_NONE, OpportunistReset, ()) modExtender.MapToFeat(feat_opportunist)
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Total Defense extender" #The fighting defensively query needs to cover both fighting defensively and total defense def FightingDefensivelyQuery(attachee, args, evt_obj): if (args.get_arg(0) != 0): evt_obj.return_val = 1 return 0 return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Total Defense") modExtender.AddHook(ET_OnD20Query, EK_Q_FightingDefensively, FightingDefensivelyQuery, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Power Attack Extender" def PowerAttackValue(attachee, args, evt_obj): evt_obj.return_val = args.get_arg(0) return 0 powerAttackExtender = PythonModifier() powerAttackExtender.ExtendExisting("Power Attack") powerAttackExtender.MapToFeat(feat_power_attack) powerAttackExtender.AddHook(ET_OnD20PythonQuery, "Power Attack Value", PowerAttackValue, ())
#Extra Stunning: Complete Warrior, p. 98 from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Extra Stunning" def ExtraStunningNewDay(attachee, args, evt_obj): #Add 3 extra stunning attacks per feat taken featCount = attachee.has_feat("Extra Stunning") args.set_arg(0, args.get_arg(0) + 3 * featCount) return 0 extendRageFeat = PythonModifier() extendRageFeat.ExtendExisting("feat_stunning_fist") extendRageFeat.MapToFeat(feat_stunning_fist) extendRageFeat.AddHook(ET_OnNewDay, EK_NEWDAY_REST, ExtraStunningNewDay, ())
# Gets the number of turn undead charges def GetTurnUndeadCharges(attachee, args, evt_obj): evt_obj.return_val = args.get_arg(1) return 0 # Called to deduct a turn undead charge def DeductTurnUndeadCharge(attachee, args, evt_obj): #Deduct one turn undead charge NewCharges = args.get_arg(1) - 1 if NewCharges > 0: args.set_arg(1, NewCharges) else: args.set_arg(1, 0) attachee.d20_send_signal( "Deduct Greater Turn Undead Charge") #Zero out greater turning return 0 modExtender = PythonModifier() modExtender.ExtendExisting( "Turn Undead" ) #Note: Arg 0 = turn undead type, Arg 1 = is the number of chrages modExtender.AddHook(ET_OnD20PythonSignal, "Turn Undead Perform", TurnUndeadPerform, ()) modExtender.AddHook(ET_OnD20PythonSignal, "Deduct Turn Undead Charge", DeductTurnUndeadCharge, ()) modExtender.AddHook(ET_OnD20PythonQuery, "Turn Undead Charges", GetTurnUndeadCharges, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Charging Extender" def ChargingQuery(attachee, args, evt_obj): #Always return true since the condition is set evt_obj.return_val = 1 return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Charging") modExtender.AddHook(ET_OnD20PythonQuery, "Charging", ChargingQuery, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp # Fix for Atari Bug 90 # Extend bracers of archery (greater - 6267 and lesser - 6268) to provide the appropriate proficiencies print "Bracers of Archery extender" def BracersOfArcheryProficientWithWeapon(attachee, args, evt_obj): # Makes the character proficient with all bows (except crossbows) weaponType = evt_obj.data1 if (weaponType == wt_longbow or weaponType == wt_shortbow or weaponType == wt_composite_shortbow or weaponType == wt_composite_longbow): evt_obj.return_val = 1 return 0 modExtender = PythonModifier() modExtender.ExtendExisting("Bracers of Archery") modExtender.AddHook(ET_OnD20PythonQuery, "Proficient with Weapon", BracersOfArcheryProficientWithWeapon, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Rapid Shot extender" def RapidShotEnabled(attachee, args, evt_obj): evt_obj.return_val = args.get_arg(0) return 0 rapidShotExtender = PythonModifier() rapidShotExtender.ExtendExisting("Rapid_Shot") rapidShotExtender.MapToFeat(feat_rapid_shot) rapidShotExtender.AddHook(ET_OnD20PythonQuery, "Rapid Shot Enabled", RapidShotEnabled, ())
#classSpecObj.AddHook(ET_OnToHitBonusBase, EK_NONE, OnGetToHitBonusBase, ()) #classSpecObj.AddHook(ET_OnSaveThrowLevel, EK_SAVE_FORTITUDE, OnGetSaveThrowFort, ()) #classSpecObj.AddHook(ET_OnSaveThrowLevel, EK_SAVE_REFLEX, OnGetSaveThrowReflex, ()) #classSpecObj.AddHook(ET_OnSaveThrowLevel, EK_SAVE_WILL, OnGetSaveThrowWill, ()) ### Spell casting def OnGetBaseCasterLevel(attachee, args, evt_obj): if evt_obj.arg0 != classEnum: return 0 classLvl = attachee.stat_level_get(classEnum) evt_obj.bonus_list.add(classLvl, 0, 137) return 0 def OnLevelupSpellsFinalize(attachee, args, evt_obj): if evt_obj.arg0 != classEnum: return 0 classSpecModule.LevelupSpellsFinalize(attachee) return # spellCasterSpecObj = PythonModifier(GetSpellCasterConditionName(), 8) # spellCasterSpecObj.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender = PythonModifier() classSpecExtender.ExtendExisting("Cleric") classSpecExtender.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecExtender.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Finalize, OnLevelupSpellsFinalize, ())