Now that @dolio wants to do some spells as well, I started to create a spell_utils.py that does most of the standard spell work and can be simply imported in any spell. Spoiler: Old version of spell Code: from templeplus.pymod import PythonModifier from toee import * import tpdp from utilities import * print "Registering sp-Appraising Touch" def appraisingTouchSpellBonus(attachee, args, evt_obj): evt_obj.bonus_list.add(10, 18, "~Appraising Touch~[TAG_SPELLS_APPRAISING_TOUCH] ~Insight~[TAG_MODIFIER_INSIGHT] Bonus") #Appraising Touch is a flat +10 insight bouns to Appraise return 0 def appraisingTouchSpellTooltip(attachee, args, evt_obj): if args.get_arg(1) == 1: evt_obj.append("Appraising Touch ({} round)".format(args.get_arg(1))) else: evt_obj.append("Appraising Touch ({} rounds)".format(args.get_arg(1))) return 0 def appraisingTouchSpellEffectTooltip(attachee, args, evt_obj): if args.get_arg(1) == 1: evt_obj.append(tpdp.hash("APPRAISING_TOUCH"), -2, " ({} round)".format(args.get_arg(1))) else: evt_obj.append(tpdp.hash("APPRAISING_TOUCH"), -2, " ({} rounds)".format(args.get_arg(1))) return 0 def appraisingTouchSpellHasSpellActive(attachee, args, evt_obj): spellPacket = tpdp.SpellPacket(args.get_arg(0)) if evt_obj.data1 == spellPacket.spell_enum: evt_obj.return_val = 1 return 0 def appraisingTouchSpellKilled(attachee, args, evt_obj): args.remove_spell() args.remove_spell_mod() return 0 def appraisingTouchSpellSpellEnd(attachee, args, evt_obj): print "appraisingTouchSpellSpellEnd" return 0 appraisingTouchSpell = PythonModifier("sp-Appraising Touch", 2) # spell_id, duration appraisingTouchSpell.AddHook(ET_OnGetSkillLevel, EK_SKILL_APPRAISE, appraisingTouchSpellBonus,()) appraisingTouchSpell.AddHook(ET_OnGetTooltip, EK_NONE, appraisingTouchSpellTooltip, ()) appraisingTouchSpell.AddHook(ET_OnGetEffectTooltip, EK_NONE, appraisingTouchSpellEffectTooltip, ()) appraisingTouchSpell.AddHook(ET_OnD20Signal, EK_S_Spell_End, appraisingTouchSpellSpellEnd, ()) appraisingTouchSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, appraisingTouchSpellHasSpellActive, ()) appraisingTouchSpell.AddHook(ET_OnD20Signal, EK_S_Killed, appraisingTouchSpellKilled, ()) appraisingTouchSpell.AddSpellDispelCheckStandard() appraisingTouchSpell.AddSpellTeleportPrepareStandard() appraisingTouchSpell.AddSpellTeleportReconnectStandard() appraisingTouchSpell.AddSpellCountdownStandardHook() Spoiler: New Version Code: from templeplus.pymod import PythonModifier from toee import * import tpdp from utilities import * import spell_utils print "Registering sp-Appraising Touch" def appraisingTouchSpellBonus(attachee, args, evt_obj): evt_obj.bonus_list.add(10, 18, "~Appraising Touch~[TAG_SPELLS_APPRAISING_TOUCH] ~Insight~[TAG_MODIFIER_INSIGHT] Bonus") #Appraising Touch is a flat +10 insight bouns to Appraise return 0 appraisingTouchSpell = PythonModifier("sp-Appraising Touch", 2) # spell_id, duration appraisingTouchSpell.AddHook(ET_OnGetSkillLevel, EK_SKILL_APPRAISE, appraisingTouchSpellBonus,()) appraisingTouchSpell.AddHook(ET_OnGetTooltip, EK_NONE, spell_utils.spellTooltip, ()) appraisingTouchSpell.AddHook(ET_OnGetEffectTooltip, EK_NONE, spell_utils.spellEffectTooltip, ()) appraisingTouchSpell.AddHook(ET_OnD20Signal, EK_S_Spell_End, spell_utils.spellEnd, ()) appraisingTouchSpell.AddHook(ET_OnD20Query, EK_Q_Critter_Has_Spell_Active, spell_utils.queryActiveSpell, ()) appraisingTouchSpell.AddHook(ET_OnD20Signal, EK_S_Killed, spell_utils.spellKilled, ()) appraisingTouchSpell.AddSpellDispelCheckStandard() appraisingTouchSpell.AddSpellTeleportPrepareStandard() appraisingTouchSpell.AddSpellTeleportReconnectStandard() appraisingTouchSpell.AddSpellCountdownStandardHook() I will add dismiss, concentration as templates as well and will post the spell_utils as soon as I am finished. Just ran out of time for now. Will be done latest on monday. Just a heads up for dolio Spoiler: spell_utils Code: def spellTooltip(attachee, args, evt_obj): spellEnum = tpdp.SpellPacket(args.get_arg(0)).spell_enum spellName = game.get_spell_mesline(spellEnum) spellDuration = args.get_arg(1) if spellDuration == 1: evt_obj.append("{} ({} round)".format(spellName, spellDuration)) else: evt_obj.append("{} ({} rounds)".format(spellName, spellDuration)) return 0 def spellEffectTooltip(attachee, args, evt_obj): spellEnum = tpdp.SpellPacket(args.get_arg(0)).spell_enum spellName = game.get_spell_mesline(spellEnum) spellName = (spellName.upper()).replace(" ", "_") spellDuration = args.get_arg(1) if args.get_arg(1) == 1: evt_obj.append(tpdp.hash("{}".format(spellName)), -2, " ({} round)".format(spellDuration)) else: evt_obj.append(tpdp.hash("{}".format(spellName)), -2, " ({} rounds)".format(spellDuration)) return 0 def queryActiveSpell(attachee, args, evt_obj): spellPacket = tpdp.SpellPacket(args.get_arg(0)) if evt_obj.data1 == spellPacket.spell_enum: evt_obj.return_val = 1 return 0 def spellKilled(attachee, args, evt_obj): args.remove_spell() args.remove_spell_mod() return 0 def spellEnd(attachee, args, evt_obj): spellEnum = tpdp.SpellPacket(args.get_arg(0)).spell_enum spellName = game.get_spell_mesline(spellEnum) print "{} SpellEnd".format(spellName) return 0 def checkRemoveSpell(attachee, args, evt_obj): if evt_obj.data1 == args.get_arg(0): args.remove_spell() args.remove_spell_mod() return 0 def addConcentration(attachee, args, evt_obj): spellPacket = tpdp.SpellPacket(args.get_arg(0)) spellPacket.caster.condition_add_with_args('sp-Concentrating', args.get_arg(0)) return 0 def addDimiss(attachee, args, evt_obj): spellPacket = tpdp.SpellPacket(args.get_arg(0)) spellPacket.caster.condition_add_with_args('Dismiss', args.get_arg(0)) return 0 def removeTempHp(attachee, args, evt_obj): attachee.d20_send_signal(S_Spell_End, 'Temporary_Hit_Points') return 0 I think this is what you meant by adding a template @Sitra Achara right? EDIT: added Concentration, Dismiss and RemoveTempHp
Pretty much yeah. You can also go one step further and create an inherited class from PythonModifier that includes all the boilerplate hooks by default (with optional args to disable each one).
Oh, cool. I had noticed that a lot of stuff could seemingly be made general like that. In fact, some of that e.g. tooltip code is better than is in a lot of new conditions, because it takes the display from the spell that was cast rather than the condition, which is how it tends to work in the base game (e.g. if you make a spell 'Greater Enlarge Person', and it reuses the same condition as 'Enlarge Person', the tooltip still says 'Greater'). I was trying to make anything I added act this way. I basically have Kelgore's Fire Bolt done. The only minor issue is that it's impossible for it to be dual school (as far as I can tell). So I just made it evocation. The conjuration part is just making a small rock, which could just be lying around in most cases. I could change it if Temple+ gets support for dual school spells, but there's probably more interesting things to add than that. I'm trying to do tripping hand next. @Sagenlicht Do you want pull requests for spells? I wasn't really intending on just sticking to spell compendium or PHB2. So I could just submit spell compendium spells, or that plus PHB2 (since it's kind of core). Or whatever.
Ok No, you can ofc do spells form the Spell compendium too If you want to, you can pm me and I add your github acc to my spell_compendium hub. Then you can simply open a branch and push new spells to it Do you care what spells do you want to do? If not I can share you my list of spells, I am working on currently and you tell me what you wanna do from them so we avoid doing work twice. You can simply use then the next pell_enum from the list, no need to pick one form your fresh pool then And again if you need any help let me know, I will gladly try to help Edit: I added the first version of the spell_utils for you, so you can start using it. I will add more to it, but alot of standard wokr is already implemented. To use dimiss: [pythonModifier].AddHook(ET_OnConditionAdd, EK_NONE, spell_utils.addDimiss, ()) [pythonModifier].AddHook(ET_OnD20Signal, EK_S_Dismiss_Spells, spell_utils.checkRemoveSpell, ()) Concentration: [pythonModifier].AddHook(ET_OnConditionAdd, EK_NONE, spell_utils.addConcentration, ()) [pythonModifier].AddHook(ET_OnD20Signal, EK_S_Concentration_Broken, spell_utils.checkRemoveSpell, ()) removeTempHP: [pythonModifier].AddHook(ET_OnD20Signal, EK_S_Temporary_Hit_Points_Removed, spell_utils.removeTempHp, ())
I already have a pretty big list of spells I'd like to try implementing. I might just prioritize things that didn't make it into the compendium since you have that covered pretty well. I think the only compendium spell I've done anything on so far is Reciprocal Gyre.
I can also add helpful code which was developed for SGoS. One thing which helped me a lot was "header" like toee.py substitution file, which I generated \ coded for Visual Studio lookup. toee.py It was either lookup cpp code each time, or use VS lookup feature. I mostly used both. For modifiers, which I created like 60 of them, I also created substitution file tpdp.py, which is quite complex. One of the most lookuped thing was determination of which class instance will be present in the evt_obj argument. Code: def OnGetAC(attachee, args, evt_obj): assert isinstance(attachee, toee.PyObjHandle) assert isinstance(args, tpdp.EventArgs) assert isinstance(evt_obj, tpdp.EventObjAttack) evt_obj.bonus_list.add_cap(8, 0, 189)#{189}{~Blinded~[TAG_BLINDED]} evt_obj.bonus_list.add_cap(3, 0, 189)#{189}{~Blinded~[TAG_BLINDED]} return 0 modObj = templeplus.pymod.PythonModifier(GetConditionName(), 3) # reserved modObj.AddHook(toee.ET_OnGetAC, toee.EK_NONE, OnGetAC, ()) That is why I used such code: assert isinstance(evt_obj, tpdp.EventObjAttack), plus full evaluation path to methods. It allows VS to determine object type or class. For example blind.py, which I created as modifier for Blind Troll in my Adventure. And still I strongly recommend to look at Temple + modifiers created by Sitra and Doug, they are great place to learn.
By the way, there's some boilerplate for creating touch spells (the sort that actually use the charge holding mechanics) that I can add to this once it gets added to version control somewhere.
I sadly found no time to work on the spell_utils the last tow days Pushed it to the temple+ github (did create a new branch) what I've done so far.