Companion Teleportation Problem

Post » Fri May 27, 2011 1:08 am

I'm having a problem reliably teleporting companions. The companion teleports but then randomly becomes unresponsive to AIFollow and AIWander commands. Here's the script:

begin HB_companion_teleport; uses global short HB_noVoicefloat teleTimerfloat resetTimershort part1short part2short part3; Part 1: cast spellif ( part1 == 0 )	if ( teleTimer == 0 )		cast "Recall" player		set teleTimer to 1	elseif ( teleTimer < 4 )		set teleTimer to ( teleTimer + GetSecondsPassed )	else		set teleTimer to 0		set part1 to 1		set part2 to 1	endifendif; Part 2: teleportif ( part2 == 1 )	if ( MCA_Location == 1 )		PositionCell 666 -1110 -497 0 "Ald-Ruhn, Ald Skar Inn"	elseif ( MCA_Location == 2 )		PositionCell 226 738 -244 0 "Balmora, Eight Plates"	elseif ( MCA_Location == 3 )		PositionCell 474 -424 396 0 "Caldera, Shenk's Shovel"	elseif ( MCA_Location == 4 )		PositionCell -470 -3 399 0 "Dagon Fel, The End of the World"	elseif ( MCA_Location == 5 )		PositionCell -30 -67 12 0 "Ebonheart, Six Fishes"	elseif ( MCA_Location == 6 )		PositionCell -86 125 -122 0 "Fort Frostmoth, General Quarters"	elseif ( MCA_Location == 7 )		PositionCell -22 256 -144 0 "Gnisis, Madach Tradehouse"	elseif ( MCA_Location == 8 )		PositionCell 4158 4377 13730 0 "Khuul, Thongar's Tradehouse"	elseif ( MCA_Location == 9 )		PositionCell -22 198 9 0 "Maar Gan, Andus Tradehouse"	elseif ( MCA_Location == 10 )		PositionCell -553 -349 14 0 "Molag Mar, The Pilgrim's Rest"	elseif ( MCA_Location == 11 )		PositionCell -723 152 36 0 "Mournhold, Great Bazaar"	elseif ( MCA_Location == 12 )		PositionCell 353 98 17 0 "Pelagiad, Halfway Tavern"	elseif ( MCA_Location == 13 )		PositionCell 131 73 385 0 "Sadrith Mora, Fara's Hole in the Wall"	elseif ( MCA_Location == 14 )		PositionCell -381 -227 396 0 "Seyda Neen, Arrille's Tradehouse"	elseif ( MCA_Location == 15 )		PositionCell 84 -101 -249 0 "Skaal Village, The Greathall"	elseif ( MCA_Location == 16 )		PositionCell 242 -238 11 0 "Suran, Desele's House of Earthly  Delights"	elseif ( MCA_Location == 17 )		PositionCell 1094 -188 137 0 "Tel Branora, Sethan's Tradehouse"	elseif ( MCA_Location == 18 )		PositionCell 1333 -326 619 0 "Tel Mora, The Covenant"	elseif ( MCA_Location == 19 )		PositionCell 503 241 233 0 "Vivec, Foreign Quarter Plaza"	endif	disable	enable	set part2 to 0	set part3 to 1endif; Part 3: reset NPCif ( part3 == 1 )	if ( resetTimer < 1 )		set resetTimer to ( resetTimer + GetSecondsPassed )	else		disable		enable		set HB_noVoice to 1		StartCombat player		StopCombat		set HB_noVoice to 0		set resetTimer to 0		set part1 to 0		set part3 to 0		StopScript HB_companion_teleport	endifendifend

This script works over 95% of the time. Any suggestions to make it 100% reliable?
User avatar
priscillaaa
 
Posts: 3309
Joined: Sat Dec 30, 2006 8:22 pm

Post » Fri May 27, 2011 3:39 pm

Moving companions to a cell that isn't active (which seems to be what you're doing) usually doesn't cause AI glitches... Usually doesn't need disable/enable either... Are you putting them in wander mode first? Best not to teleport them while they're still in follow mode.

Otherwise, it might be easier to give the companion a general fix in the local script - check AI package against what it should be, wait in case it sorts itself out (it will be -1 for a short time when the player enters the cell for example), do a combat fix then check again. I'm assuming they're NPCs here, btw: if they're creatures then startcombat will cause a bit of chaos in towns (guards will attack them).
User avatar
celebrity
 
Posts: 3522
Joined: Mon Jul 02, 2007 12:53 pm

Post » Fri May 27, 2011 12:57 pm

Moving companions to a cell that isn't active (which seems to be what you're doing) usually doesn't cause AI glitches... Usually doesn't need disable/enable either... Are you putting them in wander mode first? Best not to teleport them while they're still in follow mode.

Otherwise, it might be easier to give the companion a general fix in the local script - check AI package against what it should be, wait in case it sorts itself out (it will be -1 for a short time when the player enters the cell for example), do a combat fix then check again. I'm assuming they're NPCs here, btw: if they're creatures then startcombat will cause a bit of chaos in towns (guards will attack them).

Yes, they are NPCs. This is part of the http://www.gamesas.com/index.php?/topic/1077437-wipz-mca-companions-enhanced/ mod that I am working on. The script is based on work done by Grumpy and Neoptolemus.

I agree that moving a single NPC isn't a problem when a targeted script is initiated through dialog. I'm trying to move a group of NPCs by "talking" to one NPC and telling them all to teleport to the selected destination.

Here's the code fragment from the companion's script that initiates the teleport:
; teleportif ( GetCurrentAIPackage == 3 )	if ( HB_global_teleport != 0 )		if ( teleportState != 1 )			if ( ScriptRunning HB_companion_teleport == 0 )				set teleportState to 1				AiWander, 256, 5, 0, 60, 20, 20, 20, 0, 0, 0, 0				set following to 2				set teleported to 1				set companionTeleported to 1				set MCA_Location to HB_global_teleport				StartScript, "HB_companion_teleport"			endif		endif	endifendif


I think the disable/enable commands were used by Grumpy to correct any visual glitches. I added an extra pair due to desparation.

I originally put the PositionCell commands in the companion's script. This caused a 75% or more glitch rate. I then wrote the above code and used Neoptolemus' original teleport script. This lowered the glitch rate to about 25%. I then rewrote the teleport script based on the script in the Companion Beryl mod. This further lowered the glitch rate to 5% or less. There seems to be some improvement when I make the resetTimer wait longer. This has the side effect of increasing the wait between one companion teleporting and the next.
User avatar
saharen beauty
 
Posts: 3456
Joined: Wed Nov 22, 2006 12:54 am

Post » Fri May 27, 2011 4:57 pm

That's kind of odd... Grumpy's script was for teleporting the companion to the player, which does need a lot of fixes etc, but teleporting to an inactive cell is usually fine without them. I just checked how I've been doing it and the only thing I'm doing that you're not is an AIWander command after the positionCell. Basically I just go: positionCell, setPos, AIWander, stopScript and that's it (the setPos is needed because the coords are stored in the local script, to let the companion use Mark & Recall just in exteriors).

If you want to try adding a fix to the local script, here's how I've been doing that - it's run as a targeted script just because there's no space in the local script:
begin mcm_AIScrshort myAI  ;set from local script when script startsshort statefloat timerif ( state == -1 )	set state to 0	set timer to 0	set mcm_NoAttack to 0  ;global variable to filter empty attack voice entry	StopScript mcm_AIScr	returnelseif ( GetHealth < 1 )	set state to -1	returnelseif ( MenuMode )	returnelseif ( state == 0 )	set timer to ( timer + GetSecondsPassed )	if ( timer < 1 )		return	endif	set timer to 0	set state to 1elseif ( state == 1 )	if ( GetCurrentAIPackage == 3 )		set state to -1		return	elseif ( GetCurrentAIPackage != -1 )		if ( myAI != 3 )			set state to -1			return		endif	endif	if ( myAI == 3 )		AIFollow player 0 0 0 0	elseif ( myAI == 2 )		AIWander 512 0 0 20 50 15 5 5 5 0 0 0	elseif ( myAI == 1 )		AIWander 0 0 0 30 35 5 10 5 10 5 0 0	endif	set mcm_NoAttack to 1	set state to 2elseif ( state == 2 )	set timer to ( timer + GetSecondsPassed )	if ( timer < 1 )		return	endif	set timer to 0	if ( GetCurrentAIPackage == 3 )		set state to -1		return	elseif ( GetCurrentAIPackage != -1 )		if ( myAI != 3 )			set state to -1			return		endif	elseif ( ( GetDistance player ) > 9999 )		set state to -1		return	endif	StartCombat player	set state to 3elseif ( state == 3 )	if ( GetWeaponDrawn == 0 )		if ( GetSpellReadied == 0 )			set timer to ( timer + GetSecondsPassed )			if ( timer < 1 )				return			endif		endif	endif	StopCombat	set state to 1	if ( myAI == 3 )		AIFollow player 0 0 0 0	elseif ( myAI == 2 )		AIWander 512 0 0 20 50 15 5 5 5 0 0 0	elseif ( myAI == 1 )		AIWander 0 0 0 30 35 5 10 5 10 5 0 0	endifendifend


The bit in the local script:
if ( doorFix != 0 )  ;fix for teleport doors is activeelseif ( combatTmr >= 0 )  ;in combatelseif ( noFight != 0 )  ;in pacifist mode while others are in combatelseif ( wndrTmr < 500 )  ;wander timer, not supposed to be in follow mode nowelseif ( ScriptRunning "mcm_AIScr" )  ;script is already runningelseif ( GetCurrentAIPackage == -1 )  ;no valid AI package	set mcm_AIScr.myAI to myAI	StartScript mcm_AIScrelseif ( myAI == 3 )  ;myAI stores current AI package, 3=follow	if ( GetCurrentAIPackage != 3 )		set mcm_AIScr.myAI to myAI		StartScript mcm_AIScr	endifendif

User avatar
Miranda Taylor
 
Posts: 3406
Joined: Sat Feb 24, 2007 3:39 pm

Post » Fri May 27, 2011 3:22 pm

That's kind of odd... Grumpy's script was for teleporting the companion to the player, which does need a lot of fixes etc, but teleporting to an inactive cell is usually fine without them. I just checked how I've been doing it and the only thing I'm doing that you're not is an AIWander command after the positionCell. Basically I just go: positionCell, setPos, AIWander, stopScript and that's it (the setPos is needed because the coords are stored in the local script, to let the companion use Mark & Recall just in exteriors).

If you want to try adding a fix to the local script, here's how I've been doing that - it's run as a targeted script just because there's no space in the local script:

Thanks for the input and for reviewing my scripts. I seem to have achieved a 99% or more success rate, i.e. no AI glitches, by adjusting the reset timer. I'm going to release another beta version for testing. If there are still problems, I'll add a version of your fix to the companion script.
User avatar
Connie Thomas
 
Posts: 3362
Joined: Sun Nov 19, 2006 9:58 am


Return to III - Morrowind