[ACS] Making ACS movement code work smoothly online?
Posted: Tue Jun 02, 2020 3:05 am
Is it at all possible to override movement with ACS and have clientside prediction behave mostly correctly online? Right now, this makes prediction go nuts and more often than not the camera will skip forward a lot. When turning, there's also this strange jitter where the character will switch between two angles rapidly, and it can last for a while (moving in any direction will always cancel it, though).
Code: Select all
//note: requires ACSUtils 1.8.2 or newer
#library "PAY_MOVE"
#include "zcommon.acs"
#include "acsutils.acs"
bool Camera_Mode[MAX_PLAYERS];
int PlayerState[MAX_PLAYERS];
#define CAMERA_ACTOR "SecurityCamera" //any non solid actor should work, better if it's +CLIENTSIDEONLY
function bool Puffy_CanMove (void)
{
int p_num = PlayerNumber();
int ret1 = ((PlayerState[p_num] == STATE_ATTACK) && (CheckInventory("Puffy_IASA")));
return ret1 || (PlayerState[p_num] == STATE_NORMAL);
}
int TDRR_Functions_WarpActor[3];
Script "TDRR_Functions_WarpActor" (int tid, int tid2, int angle, int flags)
{
SetActivator(tid);
SetResultValue( Warp(tid2,
TDRR_Functions_WarpActor[0],
TDRR_Functions_WarpActor[1],
TDRR_Functions_WarpActor[2], angle, flags) );
}
function int WarpActor (int tid, int tid2, int xoff, int yoff, int zoff, int angle, int flags)
{
TDRR_Functions_WarpActor[0] = xoff;
TDRR_Functions_WarpActor[1] = yoff;
TDRR_Functions_WarpActor[2] = zoff;
return ACS_NamedExecuteWithResult("TDRR_Functions_WarpActor", tid, tid2, angle, flags);
}
function void SetActorVelX (int tid, int velx, int add)
{
int velz;
int angle = GetActorAngle(0);
if(!add) {velz = GetActorVelZ(0);}
SetActorVelocity(tid, FixedMul(cos(angle),velx), FixedMul(sin(angle),velx), velz, add, FALSE);
}
Script "HHPAY_Camera_Enable" ENTER
{
int pnum = PlayerNumber();
Camera_Mode[pnum] = TRUE;
ACS_NamedExecuteAlways("HHPAY_Camera_Loop", 0, pnum, FALSE);
}
Script "HHPAY_Camera_Loop" (int p_num)
{
ConsoleCommand("cl_identifytarget 0");
//Input variables.
int yawinput, fwinput, sideinput;
int moveangle;
//Camera-related variables.
int a,p,x,y,z,xyr;
int r = MAX_R;
int angle = GetActorAngle(0); //Camera angle, not player angle!
//Other things.
int speed = 8.0;
int velx, vely, velz;
bool OnGround;
while (Camera_Mode[p_num] == TRUE)
{
a = GetActorAngle (0);
p = GetActorPitch (0);
x = GetActorX (0);
y = GetActorY (0);
z = GetActorZ (0) + VIEW_HEIGHT;
xyr = r * cos (p) >> 16;
velx = GetActorVelX(0);
vely = GetActorVelY(0);
velz = GetActorVelZ(0);
yawinput = GetPlayerInput(-1, INPUT_YAW);
fwinput = GetPlayerInput(-1, INPUT_FORWARDMOVE);
sideinput = GetPlayerInput(-1, INPUT_SIDEMOVE);
angle += yawinput;
SetActorAngle(0,a-yawinput);
SetActorSpeed(0, 0);
//If player is on ground, execute all grounded movement related stuff.
if( (GetActorFloorZ(0) >= z) && (GetActorVelZ(0) == 0) )
{
if(Puffy_CanMove())
{
//Movement code. This thing doesn't work smoothly online, help me pls.
if( (fwinput != 0) || (sideinput != 0) )
{
moveangle = VectorAngle(fwinput,-sideinput);
SetActorAngle(0,angle+moveangle);
SetActorVelX(0, speed, FALSE);
}
//Just here for increased friction, might make this less slippery later.
else if(PlayerState[p_num] == STATE_NORMAL)
{
SetActorVelocity(0, FixedMul(velx,0.9), FixedMul(vely,0.9), 0, FALSE, TRUE);
}
}
}
//Camera doesn't exist? Something's probably wrong, try to fix it!
if(!ThingCountName (CAMERA_ACTOR, C_TID+p_num))
{
SpawnForced(CAMERA_ACTOR, x-cos(angle)*xyr, y-sin(angle)*xyr, z+sin(p)*r, C_TID+p_num, a >> 8);
SpawnForced(CAMERA_ACTOR, x-cos(angle)*xyr, y-sin(angle)*xyr, z+sin(p)*r, I_TID+p_num, a >> 8);
if(ThingCountName(CAMERA_ACTOR, C_TID + p_num))
{ChangeCamera (C_TID + p_num, 0, 0);}
else
{
Camera_Mode[p_num] = FALSE;
Log(s:CAMERA_FAIL_MSG);
}
}
//Camera is alright, let's just update the position, pitch and angle.
while(!SetActorPosition(I_TID+p_num, x-cos(angle)*xyr, y-sin(angle)*xyr, z+sin(p)*r, 0) && r > 0)
{
r -= ADJUST_R;
xyr = cos (p) * r >> 16;
}
SetActorAngle (I_TID + p_num, angle);
SetActorPitch (C_TID + p_num, p);
if(WarpActor(C_TID+p_num, I_TID+p_num, 0.0, 0.0, 0.0, 0, WARPF_NOCHECKPOSITION) == FALSE)
{Print(s:"ERROR");}
if(r < MAX_R)
r += ADJUST_R;
delay(1);
if(Camera_Mode[p_num] == TRUE)
ChangeCamera (C_TID + p_num, 0, 0);
}
}