Welcome, Guest. Please login or register.
Did you miss your activation email?
Feb 19, 2006, 06:16 am

Login with username, password and session length
Search:     Advanced search
13514 Posts in 1169 Topics by 515 Members
Latest Member: cbrewer
*Home Launch Webchat Rethan-Manor Affiliate Sites
Forum Index Help Search Calendar Login Register whose Online
Elder Scrolls Central Forums  |  Emma's TES Forum - Hosted by ESCF  |  Emma's Index  |  WIPs and Beta testing (Moderators: Tim, Emma)  |  Topic: Companion 1.3 in-depth (for the technically inclined)... 0 Members and 1 Guest are viewing this topic.
Pages: [1] Print
Author Topic: Companion 1.3 in-depth (for the technically inclined)...  (Read 732 times)
Grumpy
Grandmaster
*****
Offline Offline

Posts: 1,000


The Community's Fallen Companion.


Companion 1.3 in-depth (for the technically inclined)...
« on: Feb 04, 2005, 08:11 am »

I put this up over at TheLys' site some time ago and it kind of got lost.

Emma asked me to put it up here.

This is a variation of the original warping I and Devlor with great assistance from Reznod developed over two years ago (from the 1.3 companion mod).  This is just intended as kind of a tutorial for those who are intrested in scripting.  Lot of things you can do in script.  This is just one facet of the thing.

This is the simple version used for standard companion "enhanced" following:

-------------------------------------------------------------------------------------

float myx
float myy
float myz
float timer

if ( GetCurrentAIPackage == 3 )
if ( GetWeaponDrawn == 1 )
return
elseif ( GetDistance Player > 800 )
set timer to timer + GetSecondsPassed
if ( timer > 8 )
set timer to 0
set myx to ( Player->GetPos x )
set myy to ( Player->GetPos y )
set myz to ( Player->GetPos z )
SetPos x myx
SetPos y myy
SetPos z myz
endif
endif
endif
endif

-------------------------------------------------------------------------------------

Line for line explanation:

if ( GetCurrentAIPackage == 3 )

This line tells the game engine that this companion has to be in follow mode before the rest of the script processes. You don't want to tell them to wait somewhere just to see them start warping behind you once you walk away from them. Basically, you want them to be in AIFollow mode, and ONLY in AIFollow mode for the warping to work.

if ( GetWeaponDrawn == 1 )

This function defines whether the object that it's attached to (companion in this instance) has their weapon out or not.

"GetWeaponDrawn" is a boolean function, meaning it is either true or false (1=true 0=false). A script (unless defined differently) runs once every frame of the game, and the checks that you use in the script are in-turn made once every frame, so (for example), this script runs at the beginning of the frame (script runs from top to bottom), and the first "check" encountered is (after CurrentAIPackage) "GetWeaponDrawn". If the check returns "1" here, then the next line is processed...

Next line, and subsequently the rest of the script are dependent on this first "check".

return

This line stops further script processing. None of the rest of this script will be processed as long as the "GetWeaponDrawn" function returns true. Reason we do this is to keep a companion from warping while in combat. They only draw their weapons when in combat, so we can assume that if their weapon IS drawn, that combat is occuring.

Side note: When friend Devlor suggested this as an appropriate qualifier to keep companions from warping during combat, we thought we had it whipped at that point. However, there is a game bug that happens on occasion, and they fail to sheathe after combat is over. This presents a problem because as long as they have their weapons drawn, none of the rest of the script processes, and warping is effectively "broken" at that point. Generally why you'll see some kind of mechanisim used in dialog to force a sheathe.

Always bear in mind when scripting that not all is black and white. Other factors can and do interfere sometimes.

elseif ( GetDistance Player > 800 )

If first condition exists (GetWeaponDrawn == 1), do this. elseif first condition does NOT exist we move to the next check; second condition exists (GetDistance Player > 800), do this.

Basically, this is the "trip wire" that activates warping. Companion is too far away. Normal following parameters as defined by the game engine itself are between 180gu near distance ("game units", or the measure of distance used by the game itself (1gu = .57 virtual inches)), and about 480gu far distance. Given that you are on flat terrain with no obstacles, the game engine defines that a companion should always be within this 180gu to 480gu range.

What we are doing with this line of code is making an assumption that if they are beyond this outside distance (480gu), that they are probably stuck.

Now the reason I used 800gu here, is that on occasion, the AI works and they (companions) will figure it out on their own. By using 800gu, we minimize warping to some degree to make it more asthetically pleasing. This is, however, a relatively arbitrary number, and I've seen it set shorter, so it's pretty much "user taste".

set timer to timer + GetSecondsPassed
if ( timer > 8 )
set timer to 0

OK... Companion is STILL outside of normal parameters (480gu), and is presumed "stuck" at this point (remember that this script is processing 30 times per second on a computer that runs the game at 30fps).

This section actually serves two purposes. One reason is, again, as the 800gu distance above, used for reasons of asthetics, and allows the companion an additional 8 seconds (another arbitrary number BTW) to get back within normal following distance without warping. The second is a bit more complicated, but easy enough to understand if you consider that "GetWeaponDrawn" acts as a dynamic timer in the sense that as long as the companion has their weapon out, none of the rest of the script processes. So we actually have two different timers working here: "GetWeaponDrawn" acts as the first, but only during combat, in that it keeps the companion from warping during combat. It covers the amount of time from the onset of combat through the end of combat. Now once combat is over, if we didn't have a timer running, companion would instantly warp back to the player. The "real" timer, and the second purpose of it, is just to allow them enough time to return to the player without warping... IF THEY DON'T GET STUCK. If they do get stuck, and the 8 seconds elapses, then we move to the next area of the script.

lines defined:

set timer to timer + GetSecondsPassed

-this initiates the timer

if ( timer > 8 )

-defines the length of time, so if the timer is greater than (>) 8 seconds...

Remember? If condition exists, do this...

set timer to 0

-resets the timer to 0 for the next go-round

(Script is processing 30 times per second from top to bottom. Defined conditions HAVE to be met for the script to contine processing. Distance is now exceeded, and time has run out. The two conditions we have defined for warping to occur are now true.)

set myx to ( Player->GetPos x )

-we use our variables here (floats in this case because these numbers are not simple as in 1.2,3 (short variables), but coordinates as in -167.312)

-set variable myx to the player's "x" coordinate

set myy to ( Player->GetPos y )
set myz to ( Player->GetPos z )

-same with these two, except that one is for the player's "y" coordinate, and the other is for the player's "z" coordinate

All objects in the game are mapped, and have coordinates that are in relation to the 0,0 coordinate. I'll probably screw this up, but I think "x" is east/west, "y" is north/south, and "z" is up/down (height).

SetPos x myx

-we now have the player's coordinates, so to complete the sequence, we mearly move the object (our companion) from his/her current location to the player's location

-set companion's x position (SetPos x) to myx (myx being the player's current x coordinate)

SetPos y myy
SetPos z myz

-same with these two, except that one is for the player's "y" coordinate, and the other is for the player's "z" coordinate


...and the "endif" lines to terminate the sequence...


A rub: What if the player levitates? Obviously without some kind of qualifier, once the distance is reached, and the timer times out, the companion will warp. Not good...  

A simple qualification (I'm not going to get into companion levitation abilities here, the following addition simply keeps them from warping if the player does levitate, and is one of the simplest fixes):

-------------------------------------------------------------------------------------

float myx
float myy
float myz
float timer

if ( GetCurrentAIPackage == 3 )
if ( Player->GetEffect sEffectLevitate == 1 )
AIWander 0 0 0 0
endif

if ( GetWeaponDrawn == 1 )
return
elseif ( GetDistance Player > 800 )
set timer to timer + GetSecondsPassed
if ( timer > 8 )
set timer to 0
set myx to ( Player->GetPos x )
set myy to ( Player->GetPos y )
set myz to ( Player->GetPos z )
SetPos x myx
SetPos y myy
SetPos z myz
endif
endif
endif
endif

-------------------------------------------------------------------------------------

if ( Player->GetEffect sEffectLevitate == 1 )
AIWander 0 0 0 0
endif

Tells the game engine that if the player is levitating, then companion is to stop right where they are. Once the player has ended the levitation sequence, then he/she will need to return to the companion and initiate follow mode again.

Remember that this script is running once every frame. First check is made; if player IS levitating, AIPackage gets changed to something other than 3 (-1 maybe (not sure)), so the next frame, the script processes again; the first line is checked, and AIPackage is NOT 3, so none of the rest of the script gets processed. No warping.


Critters:

-------------------------------------------------------------------------------------

float myx
float myy
float myz
float timer

if ( GetCurrentAIPackage == 3 )
if ( Player->GetEffect sEffectLevitate == 1 )
AIWander 0 0 0 0
endif

if ( GetDistance Player > 800 )
set timer to timer + GetSecondsPassed
if ( timer > 8 )
set timer to 0
set myx to ( Player->GetPos x )
set myy to ( Player->GetPos y )
set myz to ( Player->GetPos z )
SetPos x myx
SetPos y myy
SetPos z myz
endif
endif
endif
endif

-------------------------------------------------------------------------------------


Rub with a critter is that they don't use weapons, so we can't use "GetWeponDrawn" here. In this case, the best that can be done is to just eliminate that line altogether and just use a timer.
Report to moderator   Logged

GRUMPY - IN LOVING MEMORY

Given on March 18, 1950
Taken on June 17, 2005

Please Post in Grumpy's Memorial Guestbook
Link To Memorial-thread At The Elder Scrolls Forum
Regan
Eternally Helpful
Adventurer
*
Offline Offline

Posts: 188



WWW
Companion 1.3 in-depth (for the technically inclined)...
« Reply #1 on: Feb 04, 2005, 10:32 am »

Well you lost me just after the first 'float'  :?

It's good to have it explained, I think I understand how it works now, my scripting knowledge is pushed to its limits making a messagebox pop up when you activate something. I can see how the basic 'follow' part is so efficient, being such a short piece of code.

Will you be explaining the more advanced 3.1 script as well?

I'm off to adjust my companion's follow distance and warp delay . . . . . .

Thanks Grumpy  BigGrin
Report to moderator   Logged

Grumpy
Grandmaster
*****
Offline Offline

Posts: 1,000


The Community's Fallen Companion.


Companion 1.3 in-depth (for the technically inclined)...
« Reply #2 on: Feb 04, 2005, 10:51 am »

I have fits with message boxes myself... :oops: Reason I got away from them after the Cally/Gabran mods.  I'll bet it took me a month to get that one working (no scripter me...).

Anywho...  When me and Emma talked about putting this up here, she PROMISED that she would do a short tutorial for the dialog end of this.  (poster makes his get-away...)  esbolt

What you would need in dialog to get a companion to follow/wait/etc...

So as soon as she can take time away from her most busy schedule, we can hope to see that up here as well. BigGrin
Report to moderator   Logged

GRUMPY - IN LOVING MEMORY

Given on March 18, 1950
Taken on June 17, 2005

Please Post in Grumpy's Memorial Guestbook
Link To Memorial-thread At The Elder Scrolls Forum
Emma
Moderator
___________________
*****
Online Online

Posts: 2,779


Lady of Lokken


WWW
Companion 1.3 in-depth (for the technically inclined)...
« Reply #3 on: Feb 04, 2005, 04:15 pm »

Quote from: Grumpy
I have fits with message boxes myself... :oops: Reason I got away from them after the Cally/Gabran mods.  I'll bet it took me a month to get that one working (no scripter me...).

Anywho...  When me and Emma talked about putting this up here, she PROMISED that she would do a short tutorial for the dialog end of this.  (poster makes his get-away...)  esbolt

What you would need in dialog to get a companion to follow/wait/etc...

So as soon as she can take time away from her most busy schedule, we can hope to see that up here as well. BigGrin



Hmmm... this sounds a tad bit like blackmailing to me  cirant
Oh yes... I WILL attend to it... later. Until then, have a  cicheer  :hello2:
Report to moderator   Logged

Emma's Elder Scrolls Site
Memorial book and Memorial thread for Grumpy (March 18th 1950 - June 17th 2005)
joetheimperial
Balmora Beggar
**
Offline Offline

Posts: 28



Companion 1.3 in-depth (for the technically inclined)...
« Reply #4 on: Feb 04, 2005, 10:34 pm »

That would be a wonderful read! BigGrin

All that I can ever seem to accomplish with scripting is to add a topic to a companion, or add companion share to a slave (great way to make a speaking, moving model or dancer; rather than just a maniquin).

Dialog scripting is SO much friendlier. GUIs are our friends!

I'll sit patiently..........keep my whistle wet.............and await your wise words!
Report to moderator   Logged
FofA
Balmora Beggar
**
Offline Offline

Posts: 32


Companion 1.3 in-depth (for the technically inclined)...
« Reply #5 on: Feb 06, 2005, 03:28 pm »

Reminds me of my C++ days.

Thanks, that was actually very easy to read and informative to boot.
Report to moderator   Logged

Amanda > ES forums

edwardsmd
ThankYou
Adventurer
**
Offline Offline

Posts: 379



Companion 1.3 in-depth (for the technically inclined)...
« Reply #6 on: Feb 07, 2005, 08:08 am »

Quote from: joetheimperial
...Dialog scripting is SO much friendlier. GUIs are our friends!...

There must be something wrong with me then. Scripting seems easy to follow, Dialog makes my head hurt. :(
Report to moderator   Logged

Get the updated TESCS Manual I put together. Get it at Emma's site! Available in doc and pdf flavor!

Proud to be a Roamer!
mercurybard
Balmora Beggar
**
Offline Offline

Posts: 47



Companion 1.3 in-depth (for the technically inclined)...
« Reply #7 on: Feb 08, 2005, 09:07 pm »

Nice explanation, Grumpy, really easy to understand.
Report to moderator   Logged

MistyMoon
ThankYou
Legend
**
Offline Offline

Posts: 546



WWW
Companion 1.3 in-depth (for the technically inclined)...
« Reply #8 on: Feb 11, 2005, 04:43 am »

Love Grumpy's comp v3.1 and when i added the AlmDivScript from version v2.2 it is just to good.   :wink:
Report to moderator   Logged

Find my latest updates and mod's at

Proud member of Elder Scrolls Central
Emma
Moderator
___________________
*****
Online Online

Posts: 2,779


Lady of Lokken


WWW
Re: Companion 1.3 in-depth (for the technically inclined)...
« Reply #9 on: Dec 30, 2005, 07:25 am »

Quuote from Grumpy
Quote
Anywho...  When me and Emma talked about putting this up here, she PROMISED that she would do a short tutorial for the dialog end of this.  (poster makes his get-away...)  esbolt

What you would need in dialog to get a companion to follow/wait/etc...

So as soon as she can take time away from her most busy schedule, we can hope to see that up here as well.


Better late than never... although it breaks my heart that you won't be here to read it (and tease me for my veeeery late reply...), dearest Grumpy.



If you use Grumpy's Companion project, there is already dialog included - some greetings, and the basic topics: follow, combat etc.

The most important thing to know when using the companion project as a base for your mod:

YOU HAVE TO RE-WRITE THE DIALOG!!!!

There's no way around this.

You see. If you just re-filter the existing dialog lines for your companion, the original companion will lose her dialog!!

Instead, just make one new dialog entry for each original entry. The text and the name of the topic can be the same, that doesn't matter. The important thing is that you make a brandnew dialog line. And make sure that you copy the text in the result-boxes! This text is was makes the companion react in the right way (follow you, stay, change fighting technique etc).

Same goes for the greetings. You need new greetings for your companion.

As for greetings, never put them at the very top of the greetings section! If other modders do the same thing with their mods, it may corrupt things ingame. Instead, stick your new greetings somewhere in the middle of the greetings section.

If you are making a guard companion, you will have to put the greetings in section 0, else other guard greetings will override those by you if you for instance commit a crime.


I'll leave it like this for the moment, feel free to post questions or comments...
Report to moderator   Logged

Emma's Elder Scrolls Site
Memorial book and Memorial thread for Grumpy (March 18th 1950 - June 17th 2005)
Emma
Moderator
___________________
*****
Online Online

Posts: 2,779


Lady of Lokken


WWW
Re: Companion 1.3 in-depth (for the technically inclined)...
« Reply #10 on: Jan 27, 2006, 07:19 am »

Adding new topics

If you want to add a new topic for your companion, there are several ways to do it.

In some of Grumpy's templates, there is an addtopic function in the script, and if you haven't started to use your companion yet, you can just add your topic there:

addtopic "my topic"

If the script isn't prepared for AddTopic, or if you are already using the companion,  the easiest way to do this is to put a command in a dialog result box (the block below where the actual dialog is)
Put it for instance int the topic -follow, approx like this:

Quote
Text in text-block:
Do you want me to follow you, %PCName?

Text in resultbox below text-block:

AddTopic "my topic"                                            <--this line is obviously what you add
choice "Yes, come with me" 1 "No, stay" 2


Please note that you naturally have to USE this topic in order to add the new topic!


Please note that a topic that doesn't beging with - or * or any of the other things companion mods often use, will be hyperlinked and added automatically if someone use the topic in their dialog
Report to moderator   Logged

Emma's Elder Scrolls Site
Memorial book and Memorial thread for Grumpy (March 18th 1950 - June 17th 2005)
Emma
Moderator
___________________
*****
Online Online

Posts: 2,779


Lady of Lokken


WWW
Re: Companion 1.3 in-depth (for the technically inclined)...
« Reply #11 on: Jan 27, 2006, 08:05 am »

How to make a companion dance

Assing an animation file to the companion. You do this in the npc-informationbox that you use to change heads and hairs on your companion. Right below the heads and hairs option, you'll fnd a box for animation. The most common dancing animation is the one by Bethesda, called anim_dancinggirl.nif . It's located on your TESCS-harddrive.

RX31 has made some very interesting dancing animations, too, and they are available for download at Planet Elder Scrolls.

------------------------------

Now, make a new topic for dancing (see previous post here regarding how to add topics).

In the resultbox you'll write

When you want companion to dance:
AiWander 0 0 0 0 0 0 0 0 0 0 0 100

When you want companion to stop dancing and follow you:
AiFollow player 0 0 0 0

When you want companioin to stop dancing and stand still:
AiWander 0 0 0 0




Report to moderator   Logged

Emma's Elder Scrolls Site
Memorial book and Memorial thread for Grumpy (March 18th 1950 - June 17th 2005)
Neko
Eternally Helpful
Commoner
*
Offline Offline

Posts: 84


Over there. That's new.


WWW
Re: Companion 1.3 in-depth (for the technically inclined)...
« Reply #12 on: Jan 27, 2006, 07:14 pm »

How to make a companion cast spells (through a dialogue choice)

Set up the spell you want them to use in Spellmaking, I typically make my own custom ones for fear of other mods but it's not necessary,
in your dialogue, write something like:

Quote from: companion
text:
I hate you!

results:
Cast "fireball" Player
Goodbye

the Goodbye is generally a good idea, they can only do one thing after you leave the conversation with them and this avoids a lot of different actions stacking up. If you want them to cast a spell on themselves, for example, healing themselves, there's a trick- you always need to give a target in the Cast function. But Player works equally well in this case, even if your chosen spell is "On Self":-

Quote from: companion
text:
I could really use some healing.. hold on a moment..

results:
Cast "hearth heal" Player
Goodbye

in this case, even though we need the Player to target, "hearth heal" is an "On Self" spell, so it works OK and our companion can heal themself.

Note: These spells are manaless and always suceed. If you want to develop a chance of failure or a magicka drain + inability to cast if not enough magicka, you need to implement it yourself. Useful example functions are

Code:
Set mana to ( GetCurrentMagicka )
and
Code:
ModCurrentMagicka, -20

-Neko
Report to moderator   Logged
Pages: [1] Print 
Elder Scrolls Central Forums  |  Emma's TES Forum - Hosted by ESCF  |  Emma's Index  |  WIPs and Beta testing (Moderators: Tim, Emma)  |  Topic: Companion 1.3 in-depth (for the technically inclined)...
Jump to:  

Powered by MySQL Powered by PHP Elder Scrolls Central Forums | Powered by SMF 1.0.6.
© 2001-2005, Lewis Media. All Rights Reserved.
Valid XHTML 1.0! Valid CSS!