static int s_GotoNpcOffset = 200;
static int s_StaticRandom = False;
int GetSignedRandom( const int& range ) {
return (rand() % range) - range / 2;
}
HOOK Hook_oCNpc_EV_GotoVob PATCH( &oCNpc::EV_GotoVob, &oCNpc::EV_GotoVob_Union );
zVEC3 CreatePositionOffset( const zVEC3& from, const zVEC3& to ) {
static zVEC3 axisY = zVEC3( 0.0f, 1.0f, 0.0f );
int rndOffset = GetSignedRandom( s_GotoNpcOffset );
zVEC3 direction = to - from;
zMAT4 rotation = Alg_Rotation3D( axisY, 90.0f );
zVEC3 rightVector = (rotation * direction).Normalize() * (float)rndOffset;
return rightVector;
}
int oCNpc::EV_GotoVob_Union( oCMsgMovement* csg ) {
if( csg->targetVob == player )
return THISCALL( Hook_oCNpc_EV_GotoVob )(csg);
StandUp( True, True );
if( !csg->IsInUse() ) {
if( s_StaticRandom )
srand( (int)this );
zVEC3 rightVector = CreatePositionOffset( GetPositionWorld(), csg->targetPos );
csg->targetPos += rightVector;
RbtInit( csg->targetPos, Null );
rbt.standIfTargetReached = True;
rbt.exactPosition = False;
rbt.maxTargetDist = 10000;
csg->SetInUse( True );
}
csg->targetMode = True;
return (EV_RobustTrace( csg ));
}
void Game_Init() {
s_GotoNpcOffset = zoptions->ReadInt( "Convoy", "GotoNpcOffset", s_GotoNpcOffset );
s_StaticRandom = zoptions->ReadInt( "Convoy", "StaticRandom", s_StaticRandom );
}