Aller au contenu

Photo

Companions Randomly Turning Hostile


  • Veuillez vous connecter pour répondre
7 réponses à ce sujet

#1
Darin

Darin
  • Members
  • 282 messages

So, problem with Haunted Halls...2 companions will, inevitably, turn Hostile.  1 is the Last companion, the other is random.  Not sure what could be causing it, but I assume it is a script of mine.  Any insight would be good.



#2
kevL

kevL
  • Members
  • 4 061 messages

I just updated the wiki with the LogRunScript console command.

If you can catch your log at the moment a companion turns hostile, you can have a look through the scripts that just ran



#3
Darin

Darin
  • Members
  • 282 messages

Okay, so....lot more going on than I thought... but, on this run through, had the following:

 

RUNSCRIPT: [ 69752] drl_creature_heart               [13530] Finn Stonehammer co_finn ( 11/29/2014 ) - [ 22:06:31 ]
 
RUNSCRIPT: [ 69752] gb_comp_heart                    [13530] Finn Stonehammer co_finn ( 11/29/2014 ) - [ 22:06:31 ]
 
RUNSCRIPT: [ 69752] gb_assoc_heart                   [13530] Finn Stonehammer co_finn ( 11/29/2014 ) - [ 22:06:31 ]
 
// drl_creature_heart
/*
	Description:
		This script checks variables set on the creature and
		applies various conditions, etc.
		
		Variables:
			nCompanion => uses companion scripts
			nHenchmen => uses hencmen scripts
		
		
	
*/
// Name_Date

#include "drl_include"


void main()
{


//rust monsters prefer to eat rust
if(GetLocalInt(OBJECT_SELF,"nRustMonster")==1)
	{
		object oRust = GetNearestObjectByTag("plc_rusted",OBJECT_SELF);
		if( GetIsObjectValid(oRust) && (GetDistanceBetweenLocations(GetLocation(OBJECT_SELF),GetLocation(oRust)) <= 5.0) )
			{
				ClearAllActions(TRUE);
				//ChangeToStandardFaction(OBJECT_SELF,STANDARD_FACTION_COMMONER);
				MakeNeutral(OBJECT_SELF);
				DoPlaceableObjectAction(oRust,PLACEABLE_ACTION_BASH);
				return;
			}
		else
			ChangeToStandardFaction(OBJECT_SELF,STANDARD_FACTION_HOSTILE);
				
	}
						
	
	if(	GetLocalInt(OBJECT_SELF,"nInstrument")>=1 )
				{	
					int nInstrument = GetLocalInt(OBJECT_SELF,"nInstrument");
					int nAnim;
					string sSound;
					switch (nInstrument)
						{
							case 1:
								nAnim = 25+d3(1);
								sSound = "as_n2_luteriff0"+IntToString(d4(1));
								break;
							case 2:
								nAnim = 25+d3(1);
								sSound = "gui_flutesong0"+IntToString(d4(1));
								break;
							case 3:
								nAnim = 25+d3(1);
								sSound = "gui_drumsong0"+IntToString(d4(1));
								break;						
						}
					PlayAnimation(nAnim,1.0,6.0);
					PlaySound(sSound,FALSE);
					}		
// *** Run the Regular Script ***
//  *** Keep this LAST ***


/*
	This part returns to the regular scripts based on the
	variable that defines the creature... this variable can
	and should be changed when creatures join/leave the party
*/
	string sScript = "nw_c2_default1";
	if(GetStringLength(GetLocalString(OBJECT_SELF,"sFName"))>=1)
		sScript = "npc_leg_oh";
    else if(GetLocalInt(OBJECT_SELF,"nCompanion")==1)
		sScript = "gb_comp_heart";
	else if(GetLocalInt(OBJECT_SELF,"nHenchmen")==1)
		sScript = "gb_assoc_heart";
		
	
	ExecuteScript(sScript,OBJECT_SELF);	
}

Weird that it ran BOTH "gb_comp_heart" & "gb_assoc_heart", since it should only call the one.  Something in this has got to be it, just not sure what.



#4
kevL

kevL
  • Members
  • 4 061 messages

gb_comp_heart calls gb_assoc_heart ... several of those comp/assoc AI scripts go back & forth like that.

( is Finn a rustmonster? )


anyway, i notice that if no valid rust-object is within 5 meters, OBJECT_SELF goes hostile ...



#5
Darin

Darin
  • Members
  • 282 messages

Yeah, but that should only be running if Finn has the variable "nRustMonster" set to 1.  He does not (nor do any of the other companions, all of whom were running this script with no issues this time).  I may change it to: 

else if (GetLocalInt(OBJECT_SELF,"nRustMonster")==1)
			ChangeToStandardFaction(OBJECT_SELF,STANDARD_FACTION_HOSTILE);

...but that shouldn't matter.  Unless the game skips lines when running too many heartbeats at the same time.

 

I may add a line to the heartbeat to ScriptHidden or not run scripts when the player's not around, could it be an overhead issue?



#6
kevL

kevL
  • Members
  • 4 061 messages
Yeah, but that should only be running if Finn has the variable "nRustMonster" set to 1.

use some debug:

if(GetLocalInt(OBJECT_SELF,"nRustMonster")==1)
{
    SendMessageToPC(GetFirstPC(FALSE), GetName(OBJECT_SELF) + " has rustmonster set TRUE");

    // ... other stuff.
}


 

 

Unless the game skips lines when running too many heartbeats at the same time.
 
I may add a line to the heartbeat to ScriptHidden or not run scripts when the player's not around, could it be an overhead issue?

maybe but i doubt it.

the next place to look is the AI heartbeats .... I've heard of and had this sort of thing happen before, and it's usually just that in some corner of the code the companion is responding to a silent shout to attack, or something hits its perception script, etc etc.


personally i need to use SendMessageToPC() with the tag/name of OBJECT_SELF, to tell me what the variables are and follow what's really happening. But yeh, it's trial error and guesswork to narrow in on it



#7
Darin

Darin
  • Members
  • 282 messages

I think I solved it...

// drl_creature_blocked
/*
	Description:
		This script checks variables set on the creature and
		applies various conditions, etc.
		
		Variables:
			nCompanion => uses companion scripts
			nHenchmen => uses hencmen scripts
		
		
	
*/
// Name_Date

void main()
{
	


// *** Run the Regular Script ***
//  *** Keep this LAST ***

//SetNoticeText(GetFirstPC(),"Blocked Running");
//SendMessageToPC(GetFirstPC(),"Blocked Running");
// *** Open doors *** ...requires hands and intelligence
// if they have an Int above 3, and there is a door, that can open, and their not an animal, open, else bash
if(GetAbilityScore(OBJECT_SELF,ABILITY_INTELLIGENCE,FALSE)>=3)
		{
			object oDoor = GetBlockingDoor();
			
		    if (oDoor != OBJECT_INVALID )
				{
				if (GetIsDoorActionPossible(oDoor, DOOR_ACTION_OPEN)) 
					{
						if(!(( GetLevelByClass(CLASS_TYPE_ANIMAL)+GetLevelByClass(CLASS_TYPE_BEAST)+GetLevelByClass(CLASS_TYPE_MAGICAL_BEAST)+GetLevelByClass(CLASS_TYPE_OOZE)+GetLevelByClass(CLASS_TYPE_ELEMENTAL)+GetLevelByClass(CLASS_TYPE_DRAGON) )>=1) )
			  	  			DoDoorAction(oDoor, DOOR_ACTION_OPEN);
					}
				else
					DoDoorAction(oDoor, DOOR_ACTION_BASH);	
				}
		}

/*
	This part returns to the regular scripts based on the
	variable that defines the creature... this variable can
	and should be changed when creatures join/leave the party
*/
	string sScript = "nw_c2_defaulte";
	if(GetLocalInt(OBJECT_SELF,"nCompanion")==1)
		sScript = "gb_comp_block";
	else if(GetLocalInt(OBJECT_SELF,"nHenchmen")==1)
		sScript = "gb_assoc_block";
	
	ExecuteScript(sScript,OBJECT_SELF);	
}

The line "oDoor != OBJECT_INVALID" I think was making the NPC attack other characters that were blocking them...changed to GetObjectType(oDoor)==OBJECT_TYPE_DOOR, runthrough was fin (at least, I got whooped by the wizard without anyone that wasn't supposed to turn on me turning on me.



#8
kevL

kevL
  • Members
  • 4 061 messages

hm, could be.

This seems to be one of those cases where you'd have to be able to reproduce the bug reliably, before it can be fixed for sure. tinkering with AI's in a game as complicated as this is def. challenging .....