evt_obj.damage_packet.bonus_list.add_from_feat(bon_val, bon_type_mwm, 114, "Melee Weapon Mastery") return 0 elif featDamType == D20DT_PIERCING and ( weapDamType == D20DT_BLUDGEONING_AND_PIERCING or weapDamType == D20DT_PIERCING_AND_SLASHING): evt_obj.damage_packet.bonus_list.add_from_feat(bon_val, bon_type_mwm, 114, "Melee Weapon Mastery") return 0 return 0 mwmBludg = PythonModifier("Melee Weapon Mastery - Bludgeoning", 3) mwmBludg.MapToFeat("Melee Weapon Mastery - Bludgeoning") mwmBludg.AddHook(ET_OnToHitBonus2, EK_NONE, MWMToHit, (D20DT_BLUDGEONING, )) mwmBludg.AddHook(ET_OnDealingDamage, EK_NONE, MWMToDam, (D20DT_BLUDGEONING, )) mwmSlash = PythonModifier("Melee Weapon Mastery - Slashing", 3) mwmSlash.MapToFeat("Melee Weapon Mastery - Slashing") mwmSlash.AddHook(ET_OnToHitBonus2, EK_NONE, MWMToHit, (D20DT_SLASHING, )) mwmSlash.AddHook(ET_OnDealingDamage, EK_NONE, MWMToDam, (D20DT_SLASHING, )) mwmPierc = PythonModifier("Melee Weapon Mastery - Piercing", 3) mwmPierc.MapToFeat("Melee Weapon Mastery - Piercing") mwmPierc.AddHook(ET_OnToHitBonus2, EK_NONE, MWMToHit, (D20DT_PIERCING, )) mwmPierc.AddHook(ET_OnDealingDamage, EK_NONE, MWMToDam, (D20DT_PIERCING, )) # MWM bonuses do not stack for weapons with multiple damage types. See: # http://rpg.stackexchange.com/questions/57989/can-you-take-melee-weapon-mastery-twice-and-have-it-apply-twice-to-the-same-weap
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, ())
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, StaggeringStrikeEffectOnHealing, ())
#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, ())
# 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, ())
#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 SwashbucklerEncumberedCheck(attachee): return 0 classLvl = attachee.stat_level_get(classEnum) if classLvl < 11: bonval = 1 elif classLvl < 20: bonval = 2 else: bonval = 3 evt_obj.bonus_list.add(bonval, 0, "Swashbuckler Grace") #Competence Bonus return 0 swashbucklerGrace = PythonModifier("Swashbuckler Grace", 2) #Spare, Spare swashbucklerGrace.MapToFeat("Swashbuckler Grace") swashbucklerGrace.AddHook(ET_OnSaveThrowLevel, EK_SAVE_REFLEX, SwashbucklerGraceReflexBonus, ()) # Swashbuckler Insightful Strike def SwashbucklerInsightfulStrikeDamageBonus(attachee, args, evt_obj): #Must not be encumbered if SwashbucklerEncumberedCheck(attachee): return 0 #Must be usable with weapon finesse weaponUsed = evt_obj.attack_packet.get_weapon_used() if not IsFinesseWeapon(attachee, weaponUsed): return 0
from templeplus.pymod import PythonModifier from toee import * import tpdp # Fast Wild Shape: Complete Divine, p. 81 print "Registering Fast Wild Shape" def FastWildShapeCostMod(attachee, args, evt_obj): if evt_obj.d20a.action_type != tpdp.D20ActionType.ClassAbility: return 0 WildshapeValue = 1 << 24 #Check for the wildshape bit if (evt_obj.d20a.data1 & WildshapeValue): #Always a move action with the feat evt_obj.cost_new.action_cost = D20ACT_Move_Action return 0 fastWildShape = PythonModifier( "Fast Wild Shape Feat", 2) # First argument is the wildshape, second is extra fastWildShape.MapToFeat("Fast Wild Shape") fastWildShape.AddHook(ET_OnActionCostMod, EK_NONE, FastWildShapeCostMod, ())
import tpdp # Shielded Casting: Races of Stone, p. 144 print "Registering Shielded Casting" def ShieldedCastingDisableAOO(attachee, args, evt_obj): #Only effects spell casting action = evt_obj.get_d20_action() if action.action_type != tpdp.D20ActionType.CastSpell: return 0 #Must be wearing a shield item = attachee.item_worn_at(item_wear_shield) if item == OBJ_HANDLE_NULL: return 0 #Buckler is not good enough if item.is_buckler(): return 0 evt_obj.return_val = 0 #Avoid AOO return 0 shieldedCasting = PythonModifier("Shielded Casting Feat", 2) # Spare, Spare shieldedCasting.MapToFeat("Shielded Casting") shieldedCasting.AddHook(ET_OnD20Query, EK_Q_ActionTriggersAOO, ShieldedCastingDisableAOO, ())
metaMagicData.set_extend_count(1) return 0 def SuddenExtendDeductCharge(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 Extend") suddenExtendFeat = PythonModifier("Sudden Extend Feat", 4) #Charges, Toggeled On, Spare, Spare suddenExtendFeat.MapToFeat("Sudden Extend") suddenExtendFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, SuddenExtendRadial, ()) suddenExtendFeat.AddHook(ET_OnNewDay, EK_NEWDAY_REST, SuddenExtendNewDay, ()) suddenExtendFeat.AddHook(ET_OnMetaMagicMod, EK_NONE, SuddenExtendMetamagicUpdate, ()) suddenExtendFeat.AddHook(ET_OnD20PythonSignal, "Sudden Metamagic Deduct Charge", SuddenExtendDeductCharge, ())
print "Registering Favored Power Attack" def favoredPowerAttackDamageBonus(attachee, args, evt_obj): weapon = evt_obj.attack_packet.get_weapon_used() wieldType = attachee.get_wield_type(weapon) weap_flags = weapon.obj_get_int(obj_f_weapon_flags) #No Power attack for light weapons or ranged weapons if (wieldType != 0) and not (weap_flags & OWF_RANGED_WEAPON): target = evt_obj.attack_packet.target favored_enemy = attachee.is_favored_enemy(target) if favored_enemy: #Bonus Value Based on power attack selection PowerAttackValue = attachee.d20_query("Power Attack Value") if PowerAttackValue > 0: #Add 1x more power attack for one or two handed for a total of x2 or x3 damage evt_obj.damage_packet.bonus_list.add_from_feat( PowerAttackValue, 0, 114, "Favored Power Attack") return 0 favoredPowerAttack = PythonModifier("Favored Power Attack", 2) # args are just-in-case placeholders favoredPowerAttack.MapToFeat("Favored Power Attack") favoredPowerAttack.AddHook(ET_OnDealingDamage, EK_NONE, favoredPowerAttackDamageBonus, ())
elif classLevel < 10: enhancementBonus = 2 else: enhancementBonus = 3 if not evt_obj.damage_packet.attack_power & D20DAP_MAGIC: evt_obj.damage_packet.attack_power |= D20DAP_MAGIC evt_obj.damage_packet.bonus_list.add( enhancementBonus, 12, "~Enhancement~[TAG_ENHANCEMENT_BONUS] : ~Stormlord Enhanced Javelins~[TAG_CLASS_FEATURES_STORMLORD_ENHANCED_JAVELINS]" ) #evt_obj.damage_packet.bonus_list.add_from_feat(enhancementBonus, 12, 114, "Stormlord Enhanced Javelins") return 0 enhancedJavelins = PythonModifier("Stormlord Enhanced Javelins Feat", 0) enhancedJavelins.MapToFeat("Stormlord Enhanced Javelins") enhancedJavelins.AddHook(ET_OnToHitBonus2, EK_NONE, featEnhancedJavelinsToHit, ()) enhancedJavelins.AddHook(ET_OnDealingDamage, EK_NONE, featEnhancedJavelinsDamage, ()) ## Resistance to Electricity ## def featResistanceToElectricity(attachee, args, evt_obj): classLevel = attachee.stat_level_get(classEnum) if classLevel >= 9: return 0 if classLevel < 4: resistanceBonus = 5 elif classLevel < 7: resistanceBonus = 10
return 0 def DivineVigorHasTemporaryHitpoints(attachee, args, evt_obj): evt_obj.return_val = 0 #Default to false #Set to true if divine vigor is active and hit points remain if args.get_arg(0) > 0 and args.get_arg(2) > 0: evt_obj.return_val = 1 return 0 return 0 #Setup the feat divineVigorFeat = PythonModifier("Divine Vigor Feat", 2) divineVigorFeat.MapToFeat("Divine Vigor") divineVigorFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, DivineVigorRadial, ()) #Setup the effect divineVigorEffect = PythonModifier("Divine Vigor Effect", 3) divineVigorEffect.AddHook(ET_OnD20PythonActionCheck, divineVigorEnum, OnDivineVigorCheck, ()) divineVigorEffect.AddHook(ET_OnD20PythonActionPerform, divineVigorEnum, OnDivineVigorPerform, ()) divineVigorEffect.AddHook(ET_OnBeginRound, EK_NONE, DivineVigorBeginRound, ()) divineVigorEffect.AddHook(ET_OnGetTooltip, EK_NONE, DivineVigorTooltip, ()) divineVigorEffect.AddHook(ET_OnGetEffectTooltip, EK_NONE, DivineVigorEffectTooltip, ()) divineVigorEffect.AddHook(ET_OnGetMoveSpeed, EK_NONE, DivineVigorMoveSpeed, ()) divineVigorEffect.AddHook(ET_OnTakingDamage2, EK_NONE,
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, ())
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, ())
#Augment Healing, Complete Divine: p. 79 print "Registering Augment Healing" def QueryHealingBonus(attachee, args, evt_obj): #Note: This implementation effects only damage healed by effected spells. Damage done to undead is not increased. # Also empower will apply to this bonus. This seems to be the best interpretation of the feat. healingBonus = 0 #Argument is the spell id, 0 indicates non spell healing if evt_obj.data1 > 0: spPacket = tpdp.SpellPacket(evt_obj.data1) if spPacket.spell_enum > 0: spEntry = tpdp.SpellEntry(spPacket.spell_enum) #Is it a conjuration(healing) spell if spEntry.spell_school_enum == Conjuration and spEntry.spell_subschool_enum == Healing: #Bonus is twice the spell level healingBonus = 2 * spPacket.spell_known_slot_level #Return the bonus evt_obj.return_val += healingBonus return 0 AugmentHealing = PythonModifier("Augment Healing", 2) #Extra, Extra AugmentHealing.MapToFeat("Augment Healing") AugmentHealing.AddHook(ET_OnD20PythonQuery, "Healing Bonus", QueryHealingBonus, ())
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, ())
evt_obj.return_val = args.get_arg( 0) #Returns 1 if turn undead has already been used return 0 def TurnUndeadPerform(attachee, args, evt_obj): args.set_arg(0, 1) #Set the flag that turn undead has been used this round return 0 def QuickenTurningCostMod(attachee, args, evt_obj): if evt_obj.d20a.action_type != tpdp.D20ActionType.TurnUndead: return 0 # Always a free action with the feat evt_obj.cost_new.action_cost = 0 return 0 quickenTurning = PythonModifier( "Quicken Turning Feat", 2) # First argument is whether or not turn undead is used, second is extra quickenTurning.MapToFeat("Quicken Turning") quickenTurning.AddHook(ET_OnBeginRound, EK_NONE, QuickenTurningBeginRound, ()) quickenTurning.AddHook(ET_OnD20PythonQuery, "Turn Undead Disabled", TurnUndeadDisabled, ()) quickenTurning.AddHook(ET_OnD20PythonSignal, "Turn Undead Perform", TurnUndeadPerform, ()) quickenTurning.AddHook(ET_OnActionCostMod, EK_NONE, QuickenTurningCostMod, ())
if equip_slot == item_wear_armor: # beguiler can cast in light armor (and medium armor at level 8 or greater) 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 armoredMage = PythonModifier("Beguiler Armored Mage", 2) #Spare, Spare armoredMage.MapToFeat("Beguiler Armored Mage") armoredMage.AddHook(ET_OnD20Query, EK_Q_Get_Arcane_Spell_Failure, BeguilerSpellFailure, ()) #Cloaked Casting def QuickenFeintCostMod(attachee, args, evt_obj): if evt_obj.d20a.action_type != tpdp.D20ActionType.Feint: return 0 #Change to a swift or move equivalent action as appropriate if attachee.has_feat(feat_improved_feint): if not (evt_obj.turnbased_status.flags & TBSF_FreeActionSpellPerformed): evt_obj.turnbased_status.flags |= TBSF_FreeActionSpellPerformed #Swift action uses the quickened spell action
return 0 def SuddenWidenDeductCharge(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 Widen") suddenWidenFeat = PythonModifier("Sudden Widen Feat", 4) #Charges, Toggeled On, Spare, Spare suddenWidenFeat.MapToFeat("Sudden Widen") suddenWidenFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, SuddenWidenRadial, ()) suddenWidenFeat.AddHook(ET_OnConditionAdd, EK_NONE, SuddenWidenNewDay, ()) suddenWidenFeat.AddHook(ET_OnNewDay, EK_NEWDAY_REST, SuddenWidenNewDay, ()) suddenWidenFeat.AddHook(ET_OnMetaMagicMod, EK_NONE, SuddenWidenMetamagicUpdate, ()) suddenWidenFeat.AddHook(ET_OnD20PythonSignal, "Sudden Metamagic Deduct Charge", SuddenWidenDeductCharge, ())
classSpecObj.AddHook(ET_OnGetBaseCasterLevel, EK_NONE, OnGetBaseCasterLevel, ()) classSpecObj.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Activate, OnInitLevelupSpellSelection, ()) classSpecObj.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Finalize, OnLevelupSpellsFinalize, ()) classSpecObj.AddHook(ET_OnLevelupSystemEvent, EK_LVL_Spells_Check_Complete, OnLevelupSpellsCheckComplete, ()) classSpecObj.AddHook(ET_OnD20Query, EK_Q_Get_Arcane_Spell_Failure, AssassinSpellFailure, ()) ############################# # Hide in Plain Sight # ############################# def HideInPlainSightQuery(attachee, args, evt_obj): evt_obj.return_val = 1 return 0 hips_feat = PythonModifier("Hide In Plain Sight Feat", 2) hips_feat.MapToFeat("Hide in Plain Sight") hips_feat.AddHook(ET_OnD20PythonQuery, "Can Hide In Plain Sight", HideInPlainSightQuery, () ) ########################## # Death Attack # ########################## deathAttackStudyEnum = 2100 def AssassinDeathAttackRadial(attachee, args, evt_obj): radial_action = tpdp.RadialMenuEntryPythonAction("Study Target", D20A_PYTHON_ACTION, deathAttackStudyEnum, 0, "TAG_INTERFACE_HELP") spell_data = tpdp.D20SpellData(3210) ass_lvl = attachee.stat_level_get(classEnum) spell_data.set_spell_level(ass_lvl) radial_action.set_spell_data(spell_data)
def DivineSpellPowerCastSpell(attachee, args, evt_obj): # not active, do nothing if not args.get_arg(0): return 0 #Incriment the spell cast with spell power count sepllCastCount = args.get_arg(2) args.set_arg(2, sepllCastCount + 1) return 0 #Setup the feat DivineSpellPowerFeat = PythonModifier("Divine Spell Power Feat", 4) DivineSpellPowerFeat.MapToFeat("Divine Spell Power") DivineSpellPowerFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, DivineSpellPowerRadial, ()) #Setup the effect DivineSpellPowerEffect = PythonModifier("Divine Spell Power Effect", 4) #Enabled, Bonus, Extra, Extra DivineSpellPowerEffect.AddHook(ET_OnD20PythonActionCheck, divineSpellPowerEnum, OnDivineSpellPowerCheck, ()) DivineSpellPowerEffect.AddHook(ET_OnD20PythonActionPerform, divineSpellPowerEnum, OnDivineSpellPowerPerform, ()) DivineSpellPowerEffect.AddHook(ET_OnBeginRound, EK_NONE, DivineSpellPowerBeginRound, ()) DivineSpellPowerEffect.AddHook(ET_OnGetTooltip, EK_NONE, DivineSpellPowerTooltip, ())
#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, ())
# Set the tooltip evt_obj.append("Divine Shield (" + str(args.get_arg(1)) + " rounds)") return 0 def DivineShieldEffectTooltip(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_SHIELD"), -2, " (" + str(args.get_arg(1)) + " rounds)") return 0 #Setup the feat divineShieldFeat = PythonModifier("Divine Shield Feat", 2) divineShieldFeat.MapToFeat("Divine Shield") divineShieldFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, DivineShieldRadial, ()) #Setup the condition added by the feat divineShieldEffect = PythonModifier("Divine Shield Effect", 2) divineShieldEffect.AddHook(ET_OnD20PythonActionCheck, divineShieldEnum, OnDivineShieldCheck, ()) divineShieldEffect.AddHook(ET_OnD20PythonActionPerform, divineShieldEnum, OnDivineShieldPerform, ()) divineShieldEffect.AddHook(ET_OnGetAC, EK_NONE, DivineShieldAcBonus, ()) divineShieldEffect.AddHook(ET_OnBeginRound, EK_NONE, DivineShieldBeginRound, ()) divineShieldEffect.AddHook(ET_OnGetTooltip, EK_NONE, DivineShieldTooltip, ()) divineShieldEffect.AddHook(ET_OnGetEffectTooltip, EK_NONE, DivineShieldEffectTooltip, ()) divineShieldEffect.AddHook(ET_OnD20Signal, EK_S_Inventory_Update, DivineShieldInventoryUpdate, ())
projectileHandle.obj_set_float(obj_f_offset_z, 60.0) cur_seq.spell_packet.spell_id = evt_obj.d20a.spell_id cur_seq.spell_packet.set_projectile(0, projectileHandle) ammoItem = OBJ_HANDLE_NULL if evt_obj.d20a.projectile_append(projectileHandle, ammoItem): #print "Imbue Arrow Action Frame: Projectile Appended" attachee.apply_projectile_particles(projectileHandle, evt_obj.d20a.flags) evt_obj.d20a.flags |= D20CAF_NEED_PROJECTILE_HIT else: tpactions.trigger_spell_effect(evt_obj.d20a.spell_id) return 0 imbArrowFeat = PythonModifier("Imbue Arrow Feat", 3) imbArrowFeat.MapToFeat("Imbue Arrow") imbArrowFeat.AddHook(ET_OnBuildRadialMenuEntry, EK_NONE, ImbueArrowRadial, ()) imbArrowFeat.AddHook(ET_OnD20PythonActionPerform, imbueArrowEnum, ImbueArrowPerform, ()) imbArrowFeat.AddHook(ET_OnD20PythonActionFrame, imbueArrowEnum, ImbueArrowActionFrame, ()) ### Seeker Arrow feat def SeekerArrowRadial(attachee, args, evt_obj): if not has_ranged_weapon(attachee): return 0 if args.get_arg(0): print str(args.get_arg(0))
from toee import * import tpdp print "Improved Buckler Defense" #Signal disables the Buckler penalty on the C++ side if two weapon fighting def DisableBucklerPenalty(attachee, args, evt_obj): mainWeapon = attachee.item_worn_at(item_wear_weapon_primary) secondaryWeapon = attachee.item_worn_at(item_wear_weapon_secondary) evt_obj.return_val = 0 # Disable the penalty if two weapon fighting. It could be argued that this feat should apply to two-handed # weapons as well but I am interpreting it as only applying when two weapon fighting. if (mainWeapon != secondaryWeapon) and ( mainWeapon != OBJ_HANDLE_NULL) and (secondaryWeapon != OBJ_HANDLE_NULL): if (mainWeapon.obj_get_int(obj_f_type) == obj_t_weapon) and (secondaryWeapon.obj_get_int(obj_f_type) == obj_t_weapon): evt_obj.return_val = 1 return 0 improvedBucklerDefense = PythonModifier( "Improved Buckler Defense", 2) # args are just-in-case placeholders improvedBucklerDefense.MapToFeat("Improved Buckler Defense") improvedBucklerDefense.AddHook(ET_OnD20PythonQuery, "Disable Buckler Penalty", DisableBucklerPenalty, ())
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, DivineArmorEffectTooltip, ())
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, ())
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, ())
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, ())