I'm not completely sure but I think the new framework for creating feats is going to be in the next update along with the assassin, which hasn't been released yet as far as I'm aware.
Edit: now with its own Wiki entry. ----------------- Making a feat has two parts: 1. Making a formatted .txt entry under rules\feats The format is Code: name: <feat name> flags: <flags> prereqs: <code> <value> <code> <value> ... <code> <value> description: <description; must be one line; use vertical tab character if you need line breaks ( 0xB in hex, see the help.tab file for example) > prereq descr: <short prerequisitive description> The flags field is a number representing a bitfield composed of the following flags: Spoiler Code: FPF_CAN_GAIN_MULTIPLE_TIMES = 0x1, FPF_DISABLED = 0x2, FPF_RACE_AUTOMATIC = 0x4, FPF_CLASS_AUTMATIC = 0x8 , FPF_FIGHTER_BONUS = 0x10, FPF_MONK_BONUS_1st = 0x20, FPF_MONK_BONUS_2nd = 0x40, FPF_MONK_BONUS_6th = 0x80, FPF_MULTI_SELECT_ITEM = 0x100, FPF_EXOTIC_WEAP_ITEM = 0x300, FPF_IMPR_CRIT_ITEM = 0x500, FPF_MARTIAL_WEAP_ITEM = 0x900, FPF_SKILL_FOCUS_ITEM = 0x1100, FPF_WEAP_FINESSE_ITEM = 0x2100, FPF_WEAP_FOCUS_ITEM = 0x4100, FPF_WEAP_SPEC_ITEM = 0x8100, FPF_GREATER_WEAP_FOCUS_ITEM = 0x10100, FPF_WIZARD_BONUS = 0x20000, FPF_ROGUE_BONUS = 0x40000, // rogue bonus at 10th level FPF_MULTI_MASTER = 0x80000, // head of multiselect class of feats (NEW) FPF_GREAT_WEAP_SPEC_ITEM = 0x100100, // NEW You have to choose the relevant flag values, OR them, and input the resultant number in decimal. I think most of these aren't really relevant under the new class spec system except for: * FPF_CLASS_AUTMATIC - causes the feat to be hidden from normal feat selection * FPF_CAN_GAIN_MULTIPLE_TIMES - like it says * FPF_RACE_AUTOMATIC - in the future, if/when new races are added Example: Spoiler Let's say, for the sake of example, we want the flags FPF_CAN_GAIN_MULTIPLE_TIMES, FPF_RACE_AUTOMATIC and FPF_MULTI_SELECT_ITEM. The hex number is then 0x1 | 0x4 | 0x100 = 0x105 = 261. Making general Multiselect feats (a la Weapon Focus) is not yet supported, I want to generalize it as well since the current method is very shitty (you have to create a feat entry for each and every item) The "prereqs:" field is more interesting, this is where the prerequisite codes and prerequisite values for the feat are listed. These come in pairs of <code> <value>, where the codes are either: * A stat_X enum (e.g. stat_strength, stat_level_fighter, stat_attack_bonus for minimum BAB) * A number between 1000-1999 which represents a feat enum via feat_enum = value-1000 (e.g. if you want feat_dodge, the number is 1000 + 24 ; see constants.py inside tpdata\templeplus\lib\templeplus for the list of feat enums) * One of the following special codes: Code: featReqCodeMinCasterLevel = -2, featReqCodeTurnUndeadRelated = -3, featReqCodeWeaponFeat = -4, featReqCodeEvasionRelated = -5, featReqCodeFastMovement = -6, featReqCodeUncannyDodgeRelated = -7, featReqCodeMinArcaneCasterLevel = -8, featReqCodeAnimalCompanion = -9, featReqCodeCrossbowFeat = -10 The <value> is contextual, e.g. if the feat code is MinCasterLevel (-2) then the value specified is the required minimum caster level. For feats keep it at 1, and for the special codes it's not always relevant, check out the _FeatPrereqsCheck function in feats.cpp. Still have to add support for prerequisite definitions that corresponding to new feats, which I imagine you'll want for some of the general Psi feats. 2. Creating a PythonModifier to handle the actual effect This is a topic of its own, though you personally should already be familiar with it. To link a Modifier to the feat use the PythonModifier method .MapToFeat("<FEAT NAME>") Where <FEAT NAME> must be the same as the feat name in the .txt file. e.g. Code: death_attack_feat = PythonModifier("Death Attack Feat", 3) death_attack_feat.MapToFeat("Death Attack")
Allright, I'm just about finished messing around with the new particle effect for mind blade manifestation, so I'll be able to start working on the feats needed for the class. Would you be able to add a flag for FPF_PSIONIC_BONUS ? The group of psi specific feats are available as extra feats on some levels for psionic classes like fighters get fighter specific feats. And yeah, I'll probably need to be able to have new feats as prerequisite for other new feats. One thing I'm debating, Psionic feats mention that they can only be used by characters who have an existing power point pool. I have two options for this, but I'm not fully sure how to add them in the prerequisites. 1. Prereq is that character either has taken Wild Talent as a feat, or has levels in a psionic class that gives power points. 2. Prereq queries the max_psi modifier for a value > 0
I can add a FPF_PSIONIC, but you should use the class definition files for class-specific bonus feat picks. I'm not sure if that's what you meant, but fighter-like bonus feat selection is handled that way now, the flag isn't really relevant. If anything I'm thinking the flags should be used to filter Psi Feats for when Psi isn't enabled in the House Rules menu. I think max_psi > 0 is the most general? Also seems fairly simple to do. I can add it to the "special codes" list, or alternatively add it to the stats list (so you'll also be able to access it via obj.stat_level_get(stat_max_psi) ), which should probably be the case for such a basic quantity
Yep, that's how it would work, like Psion gets a pick among the psionic feats as a bonus feat every x levels. I double checked it and it sounds like max_psi > 0 is the best. I'll probably want to query only the base max in this case? Not sure if there's a difference that would matter here, since temporary boosts to max psi such as through items increasing your key stat to increase psi only affects classes that have psi points to begin with. Whichever is simplest to check it for a prerequisite.
For my speed of thought feat, I have the following Code: from templeplus.pymod import PythonModifier from toee import * import tpdp import char_class_utils import d20_action_utils def SpeedOfThought(attachee, args, evt_obj): isFocused = attachee.d20_query("Psionically Focused") # Character must be psionically focused if not isFocused: return 0 armor = obj.item_worn_at(5) # Character must not be wearing heavy armor if armor != OBJ_HANDLE_NULL: armorFlags = armor.obj_get_int(obj_f_armor_flags) if armorFlags == ARMOR_TYPE_HEAVY: return 0 return 0 feat_speed_of_thought = PythonModifier("feat_speed_of_thought", 1) feat_speed_of_thought.MapToFeat("feat_speed_of_thought") I'm not exactly sure what is needed to make it work. I need to give an insight bonus of 10 feet to the character in the function. http://www.d20srd.org/srd/theBasics.htm#insightBonus Could I make it so this would show up in the window if you click on speed to show that the reason of +10 is insight bonus?
You need to hook it to a ET_OnGetMoveSpeed or ET_OnGetMoveSpeedBase event (depending on what this modifies). Then you just evt_obj.bonus_list.add() as usual. Does it matter to you that it actually displays as insight bonus rather than stemming from a feat? Also note that if you named your feat "feat_speed_of_thought" in the txt file then that's how it'll be displayed. The name has to match in the MapToFeat arg (though possibly it does convert to lower case and strip the underscores when indexing). Another thing, I think the armor check should be with an & operator rather than ==, gotta check though.
Actually yeah, it would probably be better to have it display as coming from the feat. How about this? Code: from templeplus.pymod import PythonModifier from toee import * import tpdp import char_class_utils import d20_action_utils def SpeedOfThought(attachee, args, evt_obj): isFocused = attachee.d20_query("Psionically Focused") # Character must be psionically focused if not isFocused: return 0 armor = obj.item_worn_at(5) # Character must not be wearing heavy armor if armor != OBJ_HANDLE_NULL: armorFlags = armor.obj_get_int(obj_f_armor_flags) if armorFlags == ARMOR_TYPE_HEAVY: return 0 evt_obj.bonus_list.add(10, ?, 114) # Add 10 insight bonus to move speed return 0 feat_speed_of_thought = PythonModifier("feat_speed_of_thought", 1) feat_speed_of_thought.AddHook(ET_OnGetMoveSpeed, EK_NONE, SpeedOfThought, ()) feat_speed_of_thought.MapToFeat("Speed of Thought") -Is it possible to make a new bonus type in ?, because it is an insight bonus which do not stack with others of their kind. Otherwise, which bonus type should I use? -Is 114 correct for the bonus construction string? Will it show in game that it came from Speed of Thought this way? -What makes sure about this file that speed of thought modifier only applies to characters who have the feat? I don't fully understand how any character with psionic focus and no heavy armor won't just get this bonus now.
Are there any insight bonuses in ToEE? As far as I can tell there are none. Here's the list of bonus types I found in ToEE: https://github.com/GrognardsFromHell/DllDocumentation/wiki/Bonus-Types If nothing from there fits, just pick a new number in the upper range (like 41). Also for feats use Code: evt_obj.bonus_list.add_from_feat(xx, xx, xx, feat) Where xx are the same as before and feat is either a feat enum or the feat identifier string. And yeah 114 is good (line 114 from bonus.mes which is {114}{~Feat~[TAG_FEATS_DES]}). The feat Modifier will be automatically applied to any character who has the feat. You get feats the usual way - either as a class bonus or by selecting it on levelup. The MapToFeat takes care of linking the feat ID (the string hash of "Speed of Thought" in this case) to the Modifier, and the engine handles the rest behind the scenes. I assume you've also created a matching .txt file?
Neat, I didn't know if I was allowed to use numbers that weren't on there. I guess I will make use of 41 for Insight Bonus, so avoid using it for other purposes please. Updated the modifier on git, check it to make sure I got it right. I do have .txt files, I made all of the .txt's for Soulknife stuff last night, you might wanna check those out too. Wild Talent and Speed of Thought only have the new psi flag, the rest that are specific to soulknife have the psi flag | class_automatic together.
Oh wow, you've been busy Note that you shouldn't use stat_wisdom and other python constants in the prereq fields, just substitute the actual number instead. I checked with the help.tab file, apparently True Strike also grants an insight bonus (type 18). Added it to the list, and you may also want to use that. (it won't interfere with True Strike since it's used in a different event) Another thing, you should put the PythonModifier files in data\scr\tpModifiers\ As of 1.0.22 it'll automatically get picked up by the game without the need to edit __init.py. You can grab the latest build frmo GitHub if you want to test it. Likewise the class defs belong in data\rules\char_class\
I'm planning on doing the class modifiers now. Once I get those done I'll need to figure the UI stuff for it to be usable in game and then I can test. Also, on psionic feats, were you able to get a prereq number in so I can check power points, otherwise how can I do that?
Right, just added stat_psi_points_max = 300 and stat_psi_points_cur = 301 to constants.py, and also to temple_enums.h and d20stats.cpp. They'll be using the d20 queries you made to get the stats.
Thank you very much. When you say max, which query are you referring to, since there is base max and modified max.