Hello visitor, this page is WIP
A "TAP" is basically an animated node, which leads the animal to a certain location. The game uses TAPs to make animals climb trees and rocks, but the possibilities are basically endless.
There are several elements that make up the TAP coding. In this tutorial I'll explain how to create new TAPs and code them properly.
TSK
We'll start with the TSK coding, which is the easiest. Below there's a template tsk you can use.
In this example "Codename" is the object you want to make functional. I highlighted 3 other important things in this code.
-First of all reserveTag="TAP", this comes back later when we look at the xml code, so keep this in mind.
-Second is "UniqueID", as the word says, this one has to be unique. So if you have multiple tasks concerning the same object (e.g. a climb and perch task), make sure you edit it so each task has a truly unique name.
-Third is b_ClimbsCodename, which I chose as the subject of my task. This means the task will work for every animal with b_ClimbsCodename="true" in its xml. Creating a boolean likes this, specific to your foliage/scenery item, is the most "clean" way to code it, but the disadvantage is that you'll have to manually edit other mods, otherwise nothing will use it. Another option is to choose a category like "Aves" as a subject, which will work for most birds, or "Primata" which will work for most monkeys.The disadvantage of this method is that because it's much broader you can get users that don't have the correct animation set or miss certain .beh coding.
- Optional: You can edit the Subject Qualifiers and BFAICompletionData to better suit your own object. In this example only animals that have satisfied their hunger and thirst need can interact with the object, and once they have finished the task their rest and privacy needs go down.
<BFAITaskTemplateList>
<BFAITaskTemplate Name="ClimbCodename" reserveTag="TAP" UniqueID="Codename:ClimbCodename">
<BFAICreateData>
<Subjects>
<b_ClimbsCodename/>
<Qualifiers_AND thirst="LE 60" hunger="LE 60"/>
</Subjects>
<Targets>
<Codename/>
<Qualifiers_AND inHabitat="true" inSight="15"/>
</Targets>
<Objects/>
</BFAICreateData>
<BFAIEvalData fixedScore=".005"/>
<BFBehExecTask>
<BFBehEnter/>
<ZTBehViewEvent viewKey="Pos_7">
<ZTFeedbackData>
<ZTThoughtInfo locID="guestthoughts:AnimalUseShelterGood" priority="1" timeout="60" global="false" useTargetTarget="true" useTargetName="true"/>
</ZTFeedbackData>
</ZTBehViewEvent>
<BFBehPlaySet behSet="useContainer"/>
</BFBehExecTask>
<BFAICompletionData>
<BFAISubjectData rest="-15" privacy="-15" />
</BFAICompletionData>
<BFAIFailureData>
<BFBehExecTask>
<BFBehPlaySet behSet="FailureSet"/>
</BFBehExecTask>
</BFAIFailureData>
</BFAITaskTemplate>
</BFAITaskTemplateList>
XML
In the xml (of the object, not the animal) we'll have to add a reference to the TAP bfm and a binder.
The bfm reference is part of the mainObj and looks like this:
<BFNamedBinder binderName="mainObj">
<instance>
<BFPhysObj>
<BFSimpleLODComponent isBFR="true" modelfile="entities\objects\foliage\Codename\Codename.nif" scale="1" />
<BFTravAnimPathComponent actorfile="entities\objects\foliage\Codename\Codename_TAP.bfm" scale="1" />
<BFGroundFitComponent heightOffset="0.0" />
</BFPhysObj>
</instance>
</BFNamedBinder>
The binder should be placed somewhere between <binder> and </binder> and looks like this:
<BFNamedBinder binderName="TAP" repopulateMethod="byName">
<instance>
<BFGEntityContainer>
<slots>
<BFGEntityContainerSlot enterBehSet="EnterPerch1" useBehSet="Perch" exitBehSet="ExitPerch1" targetNode="Peafowl_EnterA" capacity="1" exclusiveID="Codename_Perch1"/>
<BFGEntityContainerSlot enterBehSet="EnterPerch2" useBehSet="Perch" exitBehSet="ExitPerch2" targetNode="Peafowl_EnterB" capacity="1" exclusiveID="Codename_Perch2"/>
</slots>
</BFGEntityContainer>
</instance>
</BFNamedBinder>
This binder has two slots, which means this object has 2 seperate points which the animal can interact with.
The highlighted TAP should match the reserveTag="TAP" from the tsk. There are a couple of other things I highlighted.
-The enterBehSet, useBehSet and exitBehSet refer to the beh code the animals use when they interact with the object. This means animals that don't have this beh code won't be able to use your object.
You can create your own custom behsets or you could stick to the original ones. Check the trees, rocks and foliage of the original game to see which behsets already exist.
- It's important to note that each slot uses it's own enterBehSet, useBehSet and exitBehSet, because these behsets contain references to a specific targetNode.
-The targetNode determines which node the animal should dock to. Each slot uses it's own docking node. The targetNode used has to match with the one used in the behset of that slot.
-Similar to the tsk, each line here needs to have a unique name, but instead of UniqueID its called exclusiveID here.
BEH
This step is optional, because you can also use the behset of the original game.
The behsets determine which animations animals play while they are interacting with the object, and how long they interact with the object.
If you want to create your own behset they should similar to this. You can find many more examples in the behsets of original game animals.
<EnterPerch1>
<subjects>
<animal/>
</subjects>
<behaviors>
<ZTBehFeedback>
<ZTFeedbackData>
<ZTActionInfo locID="animalactions:GoingToUse" useTargetName="true"/>
</ZTFeedbackData>
</ZTBehFeedback>
<BFBehHeadLook/>
<BFBehDockTAP targetAnim="Walk_2Perch" subjectNode="Floor" targetTAP="Peafowl_EnterA"/>
<BFBehHeadLook disengage="true"/>
<BFBehAnimateTAP subjectNode="Floor" targetTAP="Peafowl_EnterA" exitTAP="false"/>
</behaviors>
</EnterPerch1>
<Perch>
<subjects>
<animal/>
</subjects>
<behaviors>
<ZTBehFeedback>
<ZTFeedbackData>
<ZTActionInfo locID="animalactions:Perching"/>
</ZTFeedbackData>
</ZTBehFeedback>
<BFBehRandomSet minPlays="12" maxPlays="18">
<randomSets>
<Perch_Idle weight="80"/>
<Perch_Groom weight="20"/>
</randomSets>
</BFBehRandomSet>
</behaviors>
</Perch>
<ExitPerch1>
<subjects>
<animal/>
</subjects>
<behaviors>
<ZTBehFeedback>
<ZTFeedbackData>
<ZTActionInfo locID="animalactions:ClimbingDown" useTargetName="true"/>
</ZTFeedbackData>
</ZTBehFeedback>
<BFBehAnimateTAP subjectNode="Floor" targetTAP="Peafowl_ExitA" exitTAP="true"/>
</behaviors>
</ExitPerch1>
It's important that the targetTAP Peafowl_EnterA of the enter behset matches with the one in the XML binder and the one in the BFM. The targetTAP Peafowl_ExitA of the exit behset also has to match with the one mentioned in the bfm.
BFM
The bfm of a TAP looks like this:
<BFM modelname="entities\objects\foliage\Codename\Codename.nif">
<animation anim="entities\objects\foliage\Codename\Codename_ExitA.bf" animName="Peafowl_ExitA" debug="false" animSpeed="1.000000" explicitUseOnly="false" resolveUnitCollisions="true" load="true" />
<animation anim="entities\objects\foliage\Codename\Codename_EnterA.bf" animName="Peafowl_EnterA" debug="false" animSpeed="1.000000" explicitUseOnly="false" resolveUnitCollisions="true" load="true" />
<animation anim="entities\objects\foliage\Codename\Codename_ExitB.bf" animName="Peafowl_ExitB" debug="false" animSpeed="1.000000" explicitUseOnly="false" resolveUnitCollisions="true" load="true" />
<animation anim="entities\objects\foliage\Codename\Codename_EnterB.bf" animName="Peafowl_EnterB" debug="false" animSpeed="1.000000" explicitUseOnly="false" resolveUnitCollisions="true" load="true" />
</BFM>
<Graph name="Codename" version="1">
<node name="Peafowl">
<table>
<Peafowl_EnterA />
<Peafowl_ExitA />
<Peafowl_EnterB />
<Peafowl_ExitB />
</table>
</node>
</Graph>
The first line contains a reference to the model of your object. The next 4 lines are references to your TAP animations. You can choose your own animName, and this has to match with the targetNodes we used earlier in the XML and BEH. All of the animNames are listed in the node table. Don't make any typo's here.
BF
TXTKEY