Summon pawns for convo
This script tries to summon all pawns needed for a convo, in case they're not close enough. It goes in a [custom player class](/docs/guides/custom-characters/).
MyPlayerCharacter.uc
function bool StartConversation(
Actor InvokeActor,
EInvokeMethod InvokeMethod,
optional Conversation Con,
optional bool bAvoidState,
optional bool bForcePlay
)
{
local ConEvent Event;
local ConEventSpeech EventSpeech;
local ScriptedPawn aScriptedPawn;
local Rotator HelpRotator;
local int Radius;
// Only try this trick if the player frobbed an NPC
if(InvokeMethod == IM_Frob)
{
if(Con == None)
{
Con = GetActiveConversation(InvokeActor, InvokeMethod);
}
// Set maximum radius and initialize the rotator
Radius = 128;
HelpRotator = Rotation;
// Loop all SpeechEvents in the convo to find their actors
Event = Con.EventList;
while(Event != None)
{
EventSpeech = ConEventSpeech(Event);
if(EventSpeech != None)
{
foreach AllActors(class'ScriptedPawn', aScriptedPawn)
{
if(aScriptedPawn.BindName != EventSpeech.SpeakerName && aScriptedPawn.BindName != EventSpeech.SpeakingToName)
continue;
// We don't need to summon anyone with the same BindName
if(aScriptedPawn.BindName == InvokeActor.BindName)
continue;
// Make sure the next actor is placed somewhere new
HelpRotator.Yaw += 4096;
if(
aScriptedPawn != None &&
aScriptedPawn != Self &&
VSize(aScriptedPawn.Location - Location) > 300
)
{
// Place the actor within a min/max radius of the player
while(Radius > 32 && !aScriptedPawn.SetLocation(Location + Normal(Vector(HelpRotator)) * Radius))
{
HelpRotator.Yaw += 4096;
Radius -= 16;
}
aScriptedPawn.LookAtActor(Self, true, false, true, 0, 0.5);
aScriptedPawn.GoToState('Conversation');
}
}
}
Event = Event.NextEvent;
}
}
return Super.StartConversation(InvokeActor, InvokeMethod, Con, bAvoidState, bForcePlay);
}