Jump to content

How difficult is it to make a separate Find Familiar spell for a kit?


Recommended Posts

I was thinking of making a mod for the Beastmaster kit and one of the things I'm considering is changing the Find Familiar spell it gets. For example, lets say I want to make it so that the Beastmaster always gets a ferret companion, how would I do that?

I know FAMILIAR.2DA is what the game checks to see what familiar to give but changing it affects anyone who uses the spell. Is it possible to make a different list and have it check that one instead?

I know that find familiar is its own opcode, but I can find other Find Familiar mods. How extensive is it change? And is it possible to to do only for a single kit?

Or else is it possible to just do a standard summoning ability but it gives the creature the same effects a familiar can do (hiding in your pack, etc)? 

Edited by gamemaster76
Link to comment

It would be a big pain in the nuts. 

My familiar mod replaces the usual system in its entirety, giving you a choice from among six different familiars instead of forcing one on you based on its alignment. With such a replacement system in place, it would be possible to adjust the group of choices on a case-by-case basis. (It would still be limited to nine possible familiars overall, though, without some serious chicanery).

But squeezing that into the normal system? Not easy.

EDIT - now I think about it, I suppose you could exploit the fact that the vanilla game only has eight familiars. Add conditional effects to the spell: if your alignment is NG and you kit is not the custom kit, do a zero-second alignment change to LG. If your kit IS the custom kit, do a zero-second change to NG. Then make a new familiar and assign it to NG. Your kit should get that new familiar, and everyone else who is LG or NG should get the pseudodragon as usual. 

That could only be done once though (NG is the only available slot), and of course would be incompatible with any other mods that alter familiars. 

Edited by subtledoctor
Link to comment
26 minutes ago, subtledoctor said:

EDIT - now I think about it, I suppose you could exploit the fact that the vanilla game only has eight familiars. Add conditional effects to the spell: if your alignment is NG and you kit is not the custom kit, do a zero-second alignment change to LG. If your kit IS the custom kit, do a zero-second change to NG. Then make a new familiar and assign it to NG. Your kit should get that new familiar, and everyone else who is LG or NG should get the pseudodragon as usual. 

That could only be done once though (NG is the only available slot), and of course would be incompatible with any other mods that alter familiars. 

Ooooh that's interesting. Is this doable in Weidu?

If so how would a zero second change work?

 

Link to comment
2 hours ago, gamemaster76 said:

Ooooh that's interesting. Is this doable in Weidu?

Sure. Well, you would probably want to manually create the creature. There are different variants for different games, and if cast at different level, etc. Familiars are complicated. Probably best to copy and adapt one of the existing ones, and then set it for NG.

Quote

If so how would a zero second change work?

Just adding an opcode 57 effect with timing = 0, duration = 0. The result will change your alignment instantaneously, for the purpose of that spell's effects only; but will have no lasting effect in-game. (It won't cause a ranger to fall, for example.) This is tested and works reliably - it's how I do my familiar choice mod. You choose from the various familiars, and the resulting spell  changes your alignment for 0 seconds and then casts the normal Find Familiar spell within the window of that zeroth of a second that your alignment is different.

Edited by subtledoctor
Link to comment
7 hours ago, subtledoctor said:

Just adding an opcode 57 effect with timing = 0, duration = 0. The result will change your alignment instantaneously, for the purpose of that spell's effects only; but will have no lasting effect in-game. (It won't cause a ranger to fall, for example.) This is tested and works reliably - it's how I do my familiar choice mod. You choose from the various familiars, and the resulting spell  changes your alignment for 0 seconds and then casts the normal Find Familiar spell within the window of that zeroth of a second that your alignment is different.

Ah! That's perfect!.... but how do I make it so that Find Familiar checks both your alignment and your kit before casting?

So far I have this but no idea how to implement the check:

    COPY_EXISTING ~spcl342.SPL~ ~override/spcl342.SPL~ 


        LAUNCH_PATCH_FUNCTION ~ADD_SPELL_EFFECT~ // Find Familiar changes alignment to NG if a beast master.
            INT_VAR
                opcode = 57                                                                  
                target = 1                                                                     
                timing = 0
                duration = 0                                                              
                parameter2 = 33                                                               
                probability1 = 100                                                             
                insert_point = 0      
        END
        
        LAUNCH_PATCH_FUNCTION ~ADD_SPELL_EFFECT~ // Find Familiar changes alignment to LG if you are a NG non-beast master.
            INT_VAR
                opcode = 57                                                                  
                target = 1                                                                     
                timing = 0
                duration = 0                                                              
                parameter2 = 17                                                               
                probability1 = 100                                                             
                insert_point = 0      
        END

Link to comment

Now we are in the realm of the theoretical, because you need to cast subspells. First add a kit check to SPLPROT.2da (I happened to have just added this to something I'm working on, so here is code):

APPEND ~splprot.2da~ ~KIT_EQUALS%TAB%152%TAB%-1%TAB%1~ UNLESS ~KIT_EQUAL~
APPEND ~splprot.2da~ ~KIT_EQUALS%TAB%152%TAB%-1%TAB%5~ UNLESS ~KIT_NOT~

COPY_EXISTING ~splprot.2da~ ~override~
  COUNT_2DA_COLS cols
  READ_2DA_ENTRIES_NOW rows cols
  FOR (row = 1; row < rows; ++row) BEGIN
    READ_2DA_ENTRY_FORMER rows row 0 ~stat~
    PATCH_IF ~%stat%~ STRING_EQUAL_CASE ~KIT_EQUAL~ BEGIN
      SET kit_is_row = %row%
    END
    PATCH_IF ~%stat%~ STRING_EQUAL_CASE ~KIT_NOT~ BEGIN
      SET kit_not_row = %row%
    END
  END
BUT_ONLY

You need the IDS value of your kit, which I think involves something like

COPY_EXISTING ~kit.ids~ ~override~
  READ_2DA_ENTRIES_NOW rows 2
  FOR (row = 1; row < rows; ++row) BEGIN
    READ_2DA_ENTRY_FORMER rows row 1 ~kit_name~
    READ_2DA_ENTRY_FORMER rows row 0 ~kit_num~
    PATCH_IF ~%kit_name%~ STRING_EQUAL_CASE ~BEASTMASTER~ BEGIN
      SET kit_number = %kit_num%
    END
  END
BUT_ONLY

Now add a 177 effect at the beginning of the FF spell (insert_point=0) with parameter2=8 (filter by ALIGN.IDS) and parameter1=0x21 (NG). This points to an .EFF you create. The .EFF uses opcode 326 with parameter2=%kit_not_row% and parameter1=%kit_number%:

CREATE EFF ~*****~
	WRITE_LONG 0x10 326
	WRITE_LONG 0x14 1
	WRITE_LONG 0x1c %kit_number%
	WRITE_LONG 0x20 %kit_not_row%
	WRITE_LONG 0x24 1
	WRITE_SHORT 0x2c 100
	WRITE_ASCII 0x30 ~*****~ #8

The first "*****" should be the name of the .EFF file, the same that is in the resource field of the 177 effect; the second "*****" should be the name of a new .SPL file. This new spell will have the opcode 57 LG alignment change, the second one you wrote above.

That takes care of everyone else. Now, add another 177 effect with insert_point=0, parameter2=9 and parameter1=%kit_number%. This points to another .EFF file that you will  create, this one will have the other opcode 57 effect:

CREATE EFF ~*****~
	WRITE_LONG 0x10 57
	WRITE_LONG 0x14 1
	WRITE_LONG 0x20 33
	WRITE_LONG 0x24 0
	WRITE_LONG 0x28 0
	WRITE_SHORT 0x2c 100

Now, I'm fairly certain those .EFF files will trigger before the end of the FF spell, so the 0-second alignment change will work. I'm moderately certain the subspell of the 326 .EFF will also trigger before the end of the FF spell. The double-conditional ins necessary, so this is the only way to achieve this.

Link to comment

Seeing that you're talking about Beastmasters, I can guess where you are probably going with this. If you want to get really clever, you could have your Beastmaster-only NG familiar be some kind of spirit-looking thing, with an override script that triggers a dialogue with the caster and asks "what kind of animal companion do you summon?" And the answers could be bear, wolf, lion, moose, etc. And depending on the answer, it could trigger a spell that does a permanent polymorph to the familiar to change it into that creature. This is one (slightly hacky) way to overcome the 9-familiar limit; it's what I was planning to do to allow wizards to summon a mephit and then choose which elemental variety it is. Could be cool for Beastmasters. In fact that would be an interesting thing to add for Beastmasters in my mod; my familiars give passive bonuses to their summoner, so with a Beastmaster you could set it to have a bonus to STR, or HP, or AC or temperature resistance, etc. depending on which animal companion they choose.  That would be cool.

Shoot, now you've got me wanting to add mephits and Beastmaster companions to my familiar mod...

Link to comment
2 minutes ago, subtledoctor said:

Seeing that you're talking about Beastmasters, I can guess where you are probably going with this. If you want to get really clever, you could have your Beastmaster-only NG familiar be some kind of spirit-looking thing, with an override script that triggers a dialogue with the caster and asks "what kind of animal companion do you summon?" And the answers could be bear, wolf, lion, moose, etc. And depending on the answer, it could trigger a spell that does a permanent polymorph to the familiar to change it into that creature. This is one (slightly hacky) way to overcome the 9-familiar limit; it's what I was planning to do to allow wizards to summon a mephit and then choose which elemental variety it is. Could be cool for Beastmasters. In fact that would be an interesting thing to add for Beastmasters in my mod; my familiars give passive bonuses to their summoner, so with a Beastmaster you could set it to have a bonus to STR, or HP, or AC or temperature resistance, etc. depending on which animal companion they choose.  That would be cool.

Shoot, now you've got me wanting to add mephits and Beastmaster companions to my familiar mod...

😂 

I was thinking of adding a permanent companion but I had no idea how to do it.

My plan was just to make it a ferret with 75% in thief skills that doesn't lower you constitution score if it dies.

Although I just ran into another wall, the opcode for find familiar uses FAMILIAR.2DA to see what to give you, but it only exists in BGEE, IWDEE and BG2EE don't seem to have it, and I cant find equivalents in them. I'm assuming theres 2 of them in BG2 since the familiars have higher stats in ToB.

Link to comment

I think FAMILIAR.2DA is a useless file; the familiar chosen is completely hard-coded. You just have to hijack an existing creature file like FAMRAB.CRE, etc.

Oh, except, I guess that means you can't use the NG slot, since both LG and NG must be hard-coded to give FAMPSD.CRE.  Oops, sorry. Well, you could do it with basically the same technique laid out above, but you would have to take the place of one of the existing familiars.  My choice would be either Faerie Dragon (why do we need two mini-dragon familiars??) or the mephit (why have mephits if you can only get access to one of the dozen or so different elemental varieties??).
Here's how I change the Quasit into a rat:

Spoiler



COPY_EXISTING ~famquas.cre~ ~override~
  SAY 0x08 @8031
  SAY 0x0c @8031
  WRITE_BYTE 0x272 151
  WRITE_LONG 0x28 49920																// rat animation
// set to low level
  WRITE_SHORT 0x24 9		//	hp
  WRITE_SHORT 0x26 9
  WRITE_SHORT 0x46 4		//	AC
  WRITE_SHORT 0x48 4
  WRITE_BYTE  0x52 17		//	thac0
  WRITE_BYTE  0x53 1		//	apr
  WRITE_BYTE  0x54 16		//	saves
  WRITE_BYTE  0x55 16
  WRITE_BYTE  0x56 16
  WRITE_BYTE  0x57 16
  WRITE_BYTE  0x58 16
// set override script
  WRITE_ASCII 0x248 ~D5FAMV0~ #8
// set skills & resists
  WRITE_BYTE 0x59 25
  WRITE_BYTE 0x5a 25
  WRITE_BYTE 0x5b 25
  WRITE_BYTE 0x5c 25
  WRITE_BYTE 0x5d 25
  WRITE_BYTE 0x5e 25
  WRITE_BYTE 0x5f 25
  WRITE_BYTE 0x60 25
  WRITE_BYTE 0x61 25
  WRITE_BYTE 0x62 25
  WRITE_BYTE 0x63 25
  WRITE_SHORT 0x46 2
  WRITE_ASCII 0x2cc ~famil3~ #8
  REMOVE_MEMORIZED_SPELLS
  REMOVE_KNOWN_SPELLS
  LPF ADD_CRE_EFFECT INT_VAR opcode = 22 target = 1 parameter1 = 1 timing = 9 END
// add disease it to quasclaw.itm, and remove DEX penalty
// give quasclaw.itm
  LPF ADD_CRE_EFFECT INT_VAR opcode = 0 target = 1 parameter1 = 4 parameter2 = 2 timing = 9 END 	// missile AC bonus
  LPF ADD_CRE_EFFECT INT_VAR opcode = 232 target = 1 parameter1 = 0 parameter2 = 20 timing = 9 special = 102 STR_VAR resource = ~d5famrt0~ END
  ADD_CRE_ITEM ~quasclaw~ #0 #0 #0 ~IDENTIFIED~ ~WEAPON1~ EQUIP
IF_EXISTS

ACTION_IF (FILE_EXISTS_IN_GAME ~quasclaw.itm~) BEGIN
 COPY_EXISTING ~quasclaw.itm~ ~override~
  LPF DELETE_EFFECT INT_VAR silent = 1 match_opcode = 15 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 44 target = 2 parameter1 = 5 parameter2 = 1 timing = 0 duration = 18 savingthrow = 4 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 60 target = 2 parameter1 = 25 parameter2 = 0 timing = 0 duration = 18 savingthrow = 4 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 60 target = 2 parameter1 = 25 parameter2 = 1 timing = 0 duration = 18 savingthrow = 4 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 60 target = 2 parameter1 = 25 parameter2 = 2 timing = 0 duration = 18 savingthrow = 4 END
 BUT_ONLY
END
ACTION_IF !(FILE_EXISTS_IN_GAME ~quasclaw.itm~) BEGIN
 COPY ~tomeandblood/data/familiars/quasclaw.itm~ ~override~
  LPF DELETE_EFFECT INT_VAR silent = 1 match_opcode = 15 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 44 target = 2 parameter1 = 5 parameter2 = 1 timing = 0 duration = 18 savingthrow = 4 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 60 target = 2 parameter1 = 25 parameter2 = 0 timing = 0 duration = 18 savingthrow = 4 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 60 target = 2 parameter1 = 25 parameter2 = 1 timing = 0 duration = 18 savingthrow = 4 END
  LPF ADD_ITEM_EFFECT INT_VAR opcode = 60 target = 2 parameter1 = 25 parameter2 = 2 timing = 0 duration = 18 savingthrow = 4 END
 BUT_ONLY
END

COPY_EXISTING ~famqua25.cre~ ~override~
  SAY 0x08 @8031
  SAY 0x0c @8031
  WRITE_BYTE 0x272 151
  WRITE_LONG 0x28 49920																// rat animation
// set to low level
  WRITE_SHORT 0x24 9		//	hp
  WRITE_SHORT 0x26 9
  WRITE_SHORT 0x46 4		//	AC
  WRITE_SHORT 0x48 4
  WRITE_BYTE  0x52 17		//	thac0
  WRITE_BYTE  0x53 1		//	apr
  WRITE_BYTE  0x54 16		//	saves
  WRITE_BYTE  0x55 16
  WRITE_BYTE  0x56 16
  WRITE_BYTE  0x57 16
  WRITE_BYTE  0x58 16
// set override script
  WRITE_ASCII 0x248 ~D5FAMV0~ #8
// set skills & resists
  WRITE_BYTE 0x59 25
  WRITE_BYTE 0x5a 25
  WRITE_BYTE 0x5b 25
  WRITE_BYTE 0x5c 25
  WRITE_BYTE 0x5d 25
  WRITE_BYTE 0x5e 25
  WRITE_BYTE 0x5f 25
  WRITE_BYTE 0x60 25
  WRITE_BYTE 0x61 25
  WRITE_BYTE 0x62 25
  WRITE_BYTE 0x63 25
  WRITE_SHORT 0x46 2
  WRITE_ASCII 0x2cc ~famil325~ #8
  LPF ADD_CRE_EFFECT INT_VAR opcode = 22 target = 1 parameter1 = 1 timing = 9 END
  REMOVE_MEMORIZED_SPELLS
  REMOVE_KNOWN_SPELLS
  LPF ADD_CRE_EFFECT INT_VAR opcode = 0 target = 1 parameter1 = 4 parameter2 = 2 timing = 9 END 	// missile AC bonus
  LPF ADD_CRE_EFFECT INT_VAR opcode = 232 target = 1 parameter1 = 0 parameter2 = 20 timing = 9 special = 102 STR_VAR resource = ~d5famrt0~ END
IF_EXISTS

COPY_EXISTING ~famquas.itm~ ~override~
  SAY UNIDENTIFIED_DESC @8032
  SAY IDENTIFIED_DESC @8032
  WRITE_ASCII 0x3a ~famfer~ #8
  WRITE_ASCII 0x58 ~cfamfer~ #8
  LPF ALTER_ITEM_HEADER STR_VAR icon = ~famfer~ END
IF_EXISTS
  
COPY_EXISTING ~famqua25.itm~ ~override~
  SAY UNIDENTIFIED_DESC @8032
  SAY IDENTIFIED_DESC @8032
  WRITE_ASCII 0x3a ~famfer~ #8
  WRITE_ASCII 0x58 ~cfamfer~ #8
  LPF ALTER_ITEM_HEADER STR_VAR icon = ~famfer~ END
IF_EXISTS


 

I know there's a lot going on there, but if you look at it with Near Infinity open to a .CRE file, you can see I am just changing lots of characteristics of the Quasit, including the animation, so that it becomes for all intents and purposes a rat.

You could adapt the techniques discussed earlier to force NE wizards to get a quasit, or a cat, and then change the mephit into a grizzly bear, and force Beastmasters to get the NE familiar. Boom - a grizzly bear animal companion for Beastmasters.

Link to comment
49 minutes ago, subtledoctor said:

I think FAMILIAR.2DA is a useless file; the familiar chosen is completely hard-coded. You just have to hijack an existing creature file like FAMRAB.CRE, etc.

It's not hardcoded, but it is locked in (based on FAMILIAR.2DA) as soon as a new game begins.

However, BG2EE and IWDEE already have familiar data stored in the BALDUR.GAM file by default, so you would have to either delete or modify that structure from the GAM file before starting a new game.

Link to comment
8 hours ago, kjeron said:

It's not hardcoded, but it is locked in (based on FAMILIAR.2DA) as soon as a new game begins.

However, BG2EE and IWDEE already have familiar data stored in the BALDUR.GAM file by default, so you would have to either delete or modify that structure from the GAM file before starting a new game.

well poop...

3 hours ago, subtledoctor said:

Well that’s unfortunate and weird. More Beamdog sloppiness...

yep... I guess that idea is out, maybe go the permanent companion route? Add a polymorph to the companion to turn it into something else?  Then the companion needs to become stronger as you level up so I need to make a bunch of scaled up versions....
But there are mods that do that already.

So I might have to scrap this idea then...

Edited by gamemaster76
Link to comment

Like I say, all of the above will still work if you are willing to cannibalize one of the existing familiars.

As for leveling up, there's ways to do it. It  can be something in the familiar's script... there are several way to skin that mephit.

And as to permanent companions... I have no idea how that is done.

Link to comment
9 minutes ago, subtledoctor said:

Like I say, all of the above will still work if you are willing to cannibalize one of the existing familiars.

As for leveling up, there's ways to do it. It  can be something in the familiar's script... there are several way to skin that mephit.

And as to permanent companions... I have no idea how that is done.

Problem is that is messes up find familiar for other classes. Unless there's a way so that if its a beast master, it will THEN alter an existing familiar but wont if its anything else. Or you uninstall the mod before a different playthrough to get the regular familiar. I just wanted it to be more useful aside from just granting an HP buff and then being in the bag forever.

Besides, aside from the familiar I'm also moving the summon animal spells the kit gets to lower levels and it will get access to the IWD version of Conjure Animals. So there will be plenty of beasts around.

Also the Charm Animal will give enemies a penalty, so those beasts in the wild are more likely to fail. Also weapon proficiencies will be restored. 

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...