def __init__(self, name, argn): PythonModifier.__init__(self, name, 3+argn, 0) self.AddHook(ET_OnGetTooltip, EK_NONE, touchTooltip, ()) self.AddHook(ET_OnGetEffectTooltip, EK_NONE, touchEffectTooltip, ()) # Handle queries for whether the affected creature is # 'holding charge'? self.AddHook(ET_OnD20Query, EK_Q_HoldingCharge, touchHoldingCharge, ()) # get notifications of other charge attacks being added self.AddHook( ET_OnD20Signal, EK_S_TouchAttackAdded, touchTouchAttackAdded, ()) # casting another spell ends held charge spells self.AddHook(ET_OnD20Signal, EK_S_Spell_Cast, touchOtherCast, ()) # modify the menus to allow for touch attacks self.AddHook(ET_OnConditionAdd, EK_NONE, touchAdd, ()) self.AddHook(ET_OnNewDay, EK_NEWDAY_REST, End, ()) self.AddSpellDispellCheckHook() self.AddSpellTeleportPrepareStandard() self.AddSpellTeleportReconnectStandard() self.AddSpellTouchAttackDischargeRadialMenuHook()
if (flags & (1 << (D20STD_F_SPELL_SCHOOL_ENCHANTMENT - 1))): evt_obj.bonus_list.add(2, 31, 139) # Racial Bonus return 0 def ConditionImmunityOnPreAdd(attachee, args, evt_obj): val = evt_obj.is_modifier("sp-Sleep") if val: evt_obj.return_val = 0 attachee.float_mesfile_line('mes\\combat.mes', 5059, tf_red) # "Sleep Immunity" game.create_history_from_pattern(31, attachee, OBJ_HANDLE_NULL) return 0 raceSpecObj = PythonModifier(GetConditionName(), 0) race_utils.AddBaseMoveSpeed(raceSpecObj, 30) race_utils.AddSkillBonuses( raceSpecObj, { skill_listen: 1, skill_search: 1, skill_spot: 1, skill_diplomacy: 2, skill_gather_information: 2 }) raceSpecObj.AddHook(ET_OnSaveThrowLevel, EK_NONE, ElvenSaveBonusEnchantment, ()) raceSpecObj.AddHook(ET_OnConditionAddPre, EK_NONE, ConditionImmunityOnPreAdd, ()) raceSpecObj.AddHook(ET_OnD20Query, EK_Q_FavoredClass, OnGetFavoredClass, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp #Magic Item Compendium, p. 7 print "Adding Berserker Weapon" def DamageBonusWeaponBerserker(attachee, args, evt_obj): if (attachee.d20_query(Q_Barbarian_Raged) == 1): damage_dice = dice_new('1d8') #1d8 bonus damage evt_obj.damage_packet.add_dice(damage_dice, -1, 100) #Damage Type = weapon return 0 weaponBerserker = PythonModifier("Weapon Berserker", 3) # spare, spare, inv_idx weaponBerserker.AddHook(ET_OnDealingDamage, EK_NONE, DamageBonusWeaponBerserker, ())
from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Tripping Bite" def OnDamage2(attachee, args, evt_obj): target = evt_obj.attack_packet.target if (target != OBJ_HANDLE_NULL): if (target.d20_query(Q_Prone) == 0 and attachee.trip_check(target)): target.fall_down() target.condition_add("Prone") target.float_mesfile_line('mes\\combat.mes', 104, 1) # Tripped! tripBite = PythonModifier("Tripping Bite", 0) tripBite.AddHook(ET_OnDealingDamage2, EK_NONE, OnDamage2, ())
# add radial menu action Defensive Stanch if not isAdded: # means it's not a newly added condition isWinded = attachee.d20_query("Defensive Stance Is Winded") isActive = attachee.d20_query("Defensive Stance Is Active") #print "is active: " + str(isActive) + " is winded: " + str(isWinded) if isActive and (isWinded == 0): # if already active, show the "Winded" option a la Barbarian Rage radialAction = tpdp.RadialMenuEntryPythonAction(-1, D20A_PYTHON_ACTION, defensiveStanceWindedEnum, 0, "TAG_INTERFACE_HELP") else: #print str(D20A_PYTHON_ACTION) + " " + str(defensiveStanceEnum) radialAction = tpdp.RadialMenuEntryPythonAction(-1, D20A_PYTHON_ACTION, defensiveStanceEnum, 0, "TAG_INTERFACE_HELP") radialAction.add_child_to_standard(attachee, tpdp.RadialMenuStandardNode.Class) 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, ()) classSpecObj.AddHook(ET_OnGetAC, EK_NONE, DwarvenDefenderAcBonus, ()) classSpecObj.AddHook(ET_OnGetAC, EK_NONE, DwDTrapSenseDodgeBonus, ()) classSpecObj.AddHook(ET_OnSaveThrowLevel , EK_SAVE_REFLEX , DwDTrapSenseReflexBonus, ()) classSpecObj.AddHook(ET_OnTakingDamage2, EK_NONE, DwDDamageReduction, ()) classSpecObj.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, DefensiveStanceRadial, ()) def DefensiveStanceIsWinded(attachee, args, evt_obj): if args.get_arg(3) != 0: evt_obj.return_val = 1 return 0
return 0 def DivineArmorEffectTooltip(attachee, args, evt_obj): # not active, do nothing if not args.get_arg(0): return 0 # Set the tooltip evt_obj.append(tpdp.hash("DIVINE_ARMOR"), -2, "") return 0 #Setup the feat divineArmorFeat = PythonModifier("Divine Armor Feat", 2) divineArmorFeat.MapToFeat("Divine Armor") divineArmorFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, DivineArmorRadial, ()) #Setup the effect divineArmorEffect = PythonModifier("Divine Armor Effect", 2) divineArmorEffect.AddHook(ET_OnD20PythonActionCheck, divineArmorEnum, OnDivineArmorCheck, ()) divineArmorEffect.AddHook(ET_OnD20PythonActionPerform, divineArmorEnum, OnDivineArmorPerform, ()) divineArmorEffect.AddHook(ET_OnBeginRound, EK_NONE, DivineArmorBeginRound, ()) divineArmorEffect.AddHook(ET_OnGetTooltip, EK_NONE, DivineArmorTooltip, ()) divineArmorEffect.AddHook(ET_OnTakingDamage2, EK_NONE, DivineArmorDamageReduction, ()) divineArmorEffect.AddHook(ET_OnGetEffectTooltip, EK_NONE,
from templeplus.pymod import PythonModifier from toee import * import tpdp #Magic Item Compendium, p. 7 print "Adding Precise Weapon" def PreciseWeaponQuery(attachee, args, evt_obj): evt_obj.return_val = 1 return 0 weaponPrecise = PythonModifier("Weapon Precise", 3) # spare, spare, inv_idx weaponPrecise.AddHook(ET_OnD20PythonQuery, "No Shot into Melee Penalty", PreciseWeaponQuery, ())
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 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 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, ()) classSpecObj.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) # Helper Functions def is_ranged_weapon(weap): if weap == OBJ_HANDLE_NULL: return 0 weap_flags = weap.obj_get_int(obj_f_weapon_flags)
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 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
#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, ())
if shield != OBJ_HANDLE_NULL: return 0 return 1 def DeadlyDefenseDamageBonus(attachee, args, evt_obj): #Test the check box for fighting defensively only (the ability won't be active yet on the first attack) IsFightingDefensively = attachee.d20_query("Fighting Defensively Checked") #Combat Expertise Penalty >= 2 will also trigger the bonus CombatExpertiseValue = attachee.d20_query("Combat Expertise Value") if IsFightingDefensively or (CombatExpertiseValue >= 2): LightOnly = HasLightArmorNoShield(attachee) ValidWeapon = IsFinesseWeapon(attachee, evt_obj.attack_packet.get_weapon_used()) #No armor or shield and a weapon finesse usable weapon if LightOnly and ValidWeapon: damage_dice = dice_new('1d6') evt_obj.damage_packet.add_dice(damage_dice, -1, 127) return 0 deadlyDefense = PythonModifier("Deadly Defense", 2) # args are just-in-case placeholders deadlyDefense.MapToFeat("Deadly Defense") deadlyDefense.AddHook(ET_OnDealingDamage, EK_NONE, DeadlyDefenseDamageBonus, ())
def RapidMMActionCostMod(attachee, args, evt_obj): if evt_obj.d20a.action_type != tpdp.D20ActionType.CastSpell: return 0 if evt_obj.cost_orig.action_cost <= 2: # original is already less than full round return 0 if evt_obj.cost_new.action_cost <= 0: # adjusted amount is already free action return 0 # check if the original spell is standard action or less - if so reduce action cost to standard action spData = evt_obj.d20a.spell_data spEntry = tpdp.SpellEntry(spData.spell_enum) if spEntry.spell_enum == 0: return 0 castingTimeType = spEntry.casting_time mmData = spData.get_metamagic_data() isQuicken = mmData.get_quicken() if isQuicken and not (evt_obj.turnbased_status.flags & TBSF_FreeActionSpellPerformed): evt_obj.cost_new.action_cost = 0 evt_obj.turnbased_status.flags |= TBSF_FreeActionSpellPerformed #print "reducing cost to 0" return 0 return 0 rapidMM = PythonModifier("Rapid Metamagic Feat", 2) # args are just-in-case placeholders rapidMM.MapToFeat("Rapid Metamagic") rapidMM.AddHook(ET_OnActionCostMod, EK_NONE, RapidMMActionCostMod, ())
raceSpecModule = __import__('race010_hill_giant') ################################################### #### standard callbacks - BAB and Save values def OnGetToHitBonusBase(attachee, args, evt_obj): classLvl = attachee.stat_level_get(classEnum) babvalue = game.get_bab_for_class(classEnum, classLvl) evt_obj.bonus_list.add(babvalue, 0, 137) # untyped, description: "Class" return 0 def OnGetSpellResistance(attachee, args, evt_obj): classLvl = attachee.stat_level_get(stat_level) evt_obj.bonus_list.add(11+classLvl, 36, "Racial Bonus (Drow)") return 0 def OnGetSpellResistanceTooltip(attachee, args, evt_obj): classLvl = attachee.stat_level_get(stat_level) evt_obj.append("Spell Resistance [" + str(11 + classLvl) + "]") return 0 raceSpecObj = PythonModifier(GetConditionName(), 0) race_utils.AddAbilityModifierHooks(raceSpecObj, raceSpecModule) race_utils.AddFavoredClassHook(raceSpecObj, stat_level_barbarian) race_utils.AddSaveThrowBonusHook(raceSpecObj, D20_Save_Fortitude, 8) race_utils.AddSaveThrowBonusHook(raceSpecObj, D20_Save_Will, 4) race_utils.AddSaveThrowBonusHook(raceSpecObj, D20_Save_Reflex, 4) race_utils.AddBaseMoveSpeed(raceSpecObj, 30)
spell_id = args.get_arg(0) # check that this spell was struck if evt_obj.data1 != spell_id: return 0 game.particles('sp-Mirror Image Loss', attachee) game.sound(32228,1) images = args.get_arg(2) if images <= 1: args.remove_spell() args.remove_spell_mod() else: args.set_arg(2, images-1) return 0 cond = PythonModifier('sp-Greater Mirror Image', 7) cond.AddHook(ET_OnGetTooltip,EK_NONE,MirrorTooltip,()) cond.AddHook(ET_OnGetEffectTooltip,EK_NONE,spellEffectTooltip,()) cond.AddHook(ET_OnBeginRound,EK_NONE,AddImage,()) cond.AddHook(ET_OnD20Query,EK_Q_Critter_Has_Mirror_Image,HasImage,()) cond.AddHook(ET_OnD20Query,EK_Q_Critter_Has_Spell_Active,queryActiveSpell,()) cond.AddHook(ET_OnD20Signal,EK_S_Killed,spellKilled,()) cond.AddHook(ET_OnD20Signal,EK_S_Spell_Mirror_Image_Struck,ImageStruck,()) cond.AddHook(ET_OnD20Signal,EK_S_Dismiss_Spells,checkRemoveSpell,()) cond.AddSpellDispelCheckStandard() cond.AddSpellTeleportPrepareStandard() cond.AddSpellTeleportReconnectStandard() cond.AddSpellCountdownStandardHook()
metaMagicData.set_silent(true) return 0 def SuddenSlientDeductCharge(attachee, args, evt_obj): #Check for a charge and the enable flag charges = args.get_arg(0) if charges < 1 or not args.get_arg(1): return 0 #Decriment the charges charges = charges - 1 args.set_arg(0, charges) return 0 #Setup the feat tpdp.register_metamagic_feat("Sudden Silent") suddenSilentFeat = PythonModifier("Sudden Silent Feat", 4) #Charges, Toggeled On, Spare, Spare suddenSilentFeat.MapToFeat("Sudden Silent") suddenSilentFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, SuddenSilentRadial, ()) suddenSilentFeat.AddHook(ET_OnNewDay, EK_NEWDAY_REST, SuddenSilentNewDay, ()) suddenSilentFeat.AddHook(ET_OnMetaMagicMod, EK_NONE, SuddenSilentMetamagicUpdate, ()) suddenSilentFeat.AddHook(ET_OnD20PythonSignal, "Sudden Metamagic Deduct Charge", SuddenSlientDeductCharge, ())
# Natural Bond: Complete Adventurer, p. 111 print "Registering Natural Bond" def QueryNaturalBond(attachee, args, evt_obj): animalCompanionLevel = 0 #Add Druid Level to Ranger effective druid level rangerLevel = attachee.stat_level_get(stat_level_ranger) if rangerLevel >= 4: animalCompanionLevel = math.floor(rangerLevel / 2) animalCompanionLevel += attachee.stat_level_get(stat_level_druid) characterLevel = attachee.stat_level_get(stat_level) nonAnimalCompanionLevel = characterLevel - animalCompanionLevel #Level bonus is up to 3 levels but not more than the character level levelBonus = min(nonAnimalCompanionLevel, 3) #Return the bonus evt_obj.return_val += levelBonus return 0 NaturalBondFeat = PythonModifier("Natural Bond Feat", 2) # spare, spare NaturalBondFeat.MapToFeat("Natural Bond") NaturalBondFeat.AddHook(ET_OnD20PythonQuery, "Animal Companion Level Bonus", QueryNaturalBond, ())
#Get the weapon type or set to the appropriate unarmed weapon type if weaponObj != OBJ_HANDLE_NULL: usedWeapon = weaponObj.get_weapon_type() else: size = attachee.obj_get_int(obj_f_size) if size == STAT_SIZE_SMALL: usedWeapon = wt_unarmed_strike_small_being else: usedWeapon = wt_unarmed_strike_medium_sized_being if featWeapon == usedWeapon: evt_obj.bonus_list.add_from_feat(4, 0, 114, "Power Critical") return 0 powerCriticalList = list() for weapon in range(wt_gauntlet, wt_mindblade): featEnum = game.get_feat_for_weapon_type(weapon, "Power Critical") #Some weapons don't have the power critical feat, skip them if featEnum != feat_none: featName = game.get_feat_name(featEnum) powerCriticalList.append(PythonModifier(featName, 3)) #Weapon, Spare, Spare powerCriticalList[-1].MapToFeat(featName) powerCriticalList[-1].AddHook(ET_OnConfirmCriticalBonus, EK_NONE, PowerCriticalBonus, (weapon, ))
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 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, ()) #Checks for a load greater than light or armor greater than light (to enable various abilities) def SwashbucklerEncumberedCheck(obj): #Light armor or no armor armor = obj.item_worn_at(5) if armor != OBJ_HANDLE_NULL: armorFlags = armor.obj_get_int(obj_f_armor_flags) if (armorFlags != ARMOR_TYPE_LIGHT) and (armorFlags !=
return 0 def SuddenQuickenDeductCharge(attachee, args, evt_obj): #Check for a charge and the enable flag charges = args.get_arg(0) if charges < 1 or not args.get_arg(1): return 0 #Decriment the charges charges = charges - 1 args.set_arg(0, charges) return 0 #Setup the feat tpdp.register_metamagic_feat("Sudden Quicken") suddenQuickenFeat = PythonModifier("Sudden Quicken Feat", 4) #Charges, Toggeled On, Spare, Spare suddenQuickenFeat.MapToFeat("Sudden Quicken") suddenQuickenFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, SuddenQuickenRadial, ()) suddenQuickenFeat.AddHook(ET_OnConditionAdd, EK_NONE, SuddenQuickenNewDay, ()) suddenQuickenFeat.AddHook(ET_OnNewDay, EK_NEWDAY_REST, SuddenQuickenNewDay, ()) suddenQuickenFeat.AddHook(ET_OnMetaMagicMod, EK_NONE, SuddenQuickenMetamagicUpdate, ()) suddenQuickenFeat.AddHook(ET_OnD20PythonSignal, "Sudden Metamagic Deduct Charge", SuddenQuickenDeductCharge, ())
ass_lvl = attachee.stat_level_get(classEnum) evt_obj.return_val += 1+(ass_lvl-1) /2 return 0 def AssassinPoisonSaveBonus(attachee, args, evt_obj): ass_lvl = attachee.stat_level_get(classEnum) if ass_lvl < 2: return 0 if evt_obj.flags & 8: # D20STD_F_POISON value = ass_lvl / 2 evt_obj.bonus_list.add(value, 0, 137) 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, ()) classSpecObj.AddHook(ET_OnD20PythonQuery, "Sneak Attack Dice", AssassinSneakAttackDice, ()) classSpecObj.AddHook(ET_OnSaveThrowLevel, EK_NONE, AssassinPoisonSaveBonus, ()) ### 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)
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, ())
#Battle Caster Complete Arcane, p. 75 from templeplus.pymod import PythonModifier from toee import * import tpdp print "Registering Battle Caster" #Query is to be made from any class that allows a caster to wear some armor without arcane failure def ImprovedArcaneFailure(attachee, args, evt_obj): evt_obj.return_val = 1 #Return 1 to improve the class's arcane failure resistance for armor return 0 battleCaster = PythonModifier("Battle Caster", 2) # args are just-in-case placeholders battleCaster.MapToFeat("Battle Caster") battleCaster.AddHook(ET_OnD20PythonQuery, "Improved Armored Casting", ImprovedArcaneFailure, ())
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, ())
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, ())
return 0 def StaggeringStrikeEffectGetEffectTooltip(attachee, args, evt_obj): # not active, do nothing if not args.get_arg(0): return 0 # Set the tooltip evt_obj.append(tpdp.hash("STAGGERING_STRIKE"), -2, "") return 0 #Setup the feat StaggeringStrikeFeat = PythonModifier("Staggering Strike Feat", 2) #Apply Effect, Extra StaggeringStrikeFeat.MapToFeat("Staggering Strike") StaggeringStrikeFeat.AddHook(ET_OnD20PythonSignal, "Sneak Attack Damage Applied", StaggeringStrikeFeatOnSneakAttack, ()) StaggeringStrikeFeat.AddHook(ET_OnDealingDamage2, EK_NONE, StaggeringStrikeFeatOnDamage, ()) #Setup the effect StaggeringStrikeEffect = PythonModifier("Staggering Strike Effect", 2) #Rounds, Extra StaggeringStrikeEffect.AddHook(ET_OnTurnBasedStatusInit, EK_NONE, StaggeringStrikeEffectTurnBasedStatusInit, ()) StaggeringStrikeEffect.AddHook(ET_OnBeginRound, EK_NONE, StaggeringStrikeEffectBeginRound, ()) StaggeringStrikeEffect.AddHook(ET_OnReceiveHealing, EK_NONE,
evt_obj.return_val = 1 return 0 def MindBlankTooltip(attachee, args, evt_obj): # Set the tooltip evt_obj.append("Mind Blank (" + str(args.get_arg(1)) + " rounds)") return 0 def MindBlankEffectTooltip(attachee, args, evt_obj): # Set the tooltip evt_obj.append(tpdp.hash("MIND_BLANK"), -2, " (" + str(args.get_arg(1)) + " rounds)") return 0 def MindBlankRemove(attachee, args, evt_obj): # Show the remove spell effect game.particles('sp-Mind Blank-END', attachee) return 0 mindBlank = PythonModifier("sp-Mind Blank", 4) mindBlank.AddHook(ET_OnSpellImmunityCheck, EK_NONE, MindBlankImmunity, ()) # spell_id, duration, spare, spare mindBlank.AddHook(ET_OnGetTooltip, EK_NONE, MindBlankTooltip, ()) mindBlank.AddHook(ET_OnGetEffectTooltip, EK_NONE, MindBlankEffectTooltip, ()) mindBlank.AddHook(ET_OnConditionRemove, EK_NONE, MindBlankRemove, ()) mindBlank.AddSpellCountdownStandardHook()
args.set_arg( 1, new_max ) # adjust max points by the amount specified in the event object return 0 def PsiPointsNewDay(attachee, args, evt_obj): args.set_arg(0, 0) # set depleted psi points to 0 #args.set_arg(1, args.get_arg(1)) # set max points to itself, but it never changed! #args.set_arg(2, 0) # unused #args.set_arg(3, 0) # unused return 0 psiPoints = PythonModifier( "Psi Points", 4 ) # arg0 - depleted psi points; arg1 - max psi points; arg2 - unused; arg3 - unused psiPoints.AddHook(ET_OnD20PythonQuery, "Max Psi", PsiPointsGetMax, ()) # hook PsiPointsGetMax to event of python query psiPoints.AddHook(ET_OnD20PythonQuery, "Base Max Psi", PsiPointsGetBaseMax, ()) # hook PsiPointsGetBaseMax to event of python query psiPoints.AddHook(ET_OnD20PythonQuery, "Current Psi", PsiPointsGetCurrent, ()) # hook PsiPointsGetCurrent to event of python query psiPoints.AddHook(ET_OnD20PythonSignal, "Subtract Psi", SubtractPsi, ()) # hook SubtractPsi to event of python signal psiPoints.AddHook(ET_OnD20PythonSignal, "Increase Max Psi", IncreaseMaxPsi, ()) # hook IncreaseMaxPsi to event of python signal psiPoints.AddHook( ET_OnNewDay, EK_NEWDAY_REST, PsiPointsNewDay, ()) # hook PsiPointsNewDay to event of resting 8 hours safely
#If charging apply the attack bonus if charging: evt_obj.bonus_list.add( 2, 0, "Reckless Charge" ) #+2 Bonus makes up for the -2 Rapid shot penalty return 0 def RecklessChargeACPenalty(attachee, args, evt_obj): #Check if the feat is enabled if not args.get_arg(0): return 0 charging = attachee.d20_query("Charging") #If charging apply the ac penatly if charging: evt_obj.bonus_list.add( -2, 0, "Reckless Charge") # Dodge bonus, ~Class~[TAG_LEVEL_BONUSES] return 0 recklessCharge = PythonModifier("Reckless Charge", 2) # Enabled, Place Holder recklessCharge.MapToFeat("Reckless Charge") recklessCharge.AddHook(ET_OnToHitBonus2, EK_NONE, RecklessChargeHitBonus, ()) recklessCharge.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, RecklessChargeRadial, ()) recklessCharge.AddHook(ET_OnGetAC, EK_NONE, RecklessChargeACPenalty, ())
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, ())
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 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 # Mystic Theurge raises the caster level for its two base classes specified in Modifier args 0 & 1 # configure the spell casting condition to hold the highest two Arcane/Divine classes as chosen-to-be-extended classes def OnAddSpellCasting(attachee, args, evt_obj): #arg0 holds the arcane class