Fix offscreen updates, they were only setting droid pos.x and pos.y for most orders, and those are
promptly overwritten next frame by sMove.fx and sMove.fy which are not updated. So I rewrote the code a bit to only use the floating point values. I also made it issue move command for onscreen changes when in guard order. Not sure why we do not do this for all orders, but at least guard should also be safe. git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@9578 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
3a800c09a3
commit
6f052e0ed9
|
@ -2446,8 +2446,6 @@ DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player,
|
|||
memset(psDroid->asOrderList, 0, sizeof(ORDER_LIST)*ORDER_LIST_MAX);
|
||||
|
||||
psDroid->iAudioID = NO_SOUND;
|
||||
psDroid->lastSync = 0;
|
||||
|
||||
psDroid->psCurAnim = NULL;
|
||||
psDroid->group = UBYTE_MAX;
|
||||
psDroid->psBaseStruct = NULL;
|
||||
|
|
|
@ -189,8 +189,6 @@ typedef struct DROID
|
|||
// secondary order data
|
||||
UDWORD secondaryOrder;
|
||||
|
||||
UDWORD lastSync; ///< multiplayer synchronization value.
|
||||
|
||||
/* Action data */
|
||||
SDWORD action;
|
||||
UDWORD actionX, actionY;
|
||||
|
|
155
src/multisync.c
155
src/multisync.c
|
@ -60,8 +60,8 @@ static void packageCheck (const DROID* pD);
|
|||
static BOOL sendDroidCheck (void); //droids
|
||||
|
||||
static void highLevelDroidUpdate(DROID *psDroid,
|
||||
UDWORD x,
|
||||
UDWORD y,
|
||||
float fx,
|
||||
float fy,
|
||||
UDWORD state,
|
||||
UDWORD order,
|
||||
BASE_OBJECT *psTarget,
|
||||
|
@ -69,13 +69,10 @@ static void highLevelDroidUpdate(DROID *psDroid,
|
|||
|
||||
|
||||
static void onscreenUpdate (DROID *pDroid,UDWORD dam, // the droid and its damage
|
||||
UDWORD x, UDWORD y, // the ideal position
|
||||
float fx,float fy, // the ideal fractional position
|
||||
UWORD dir, // direction it should facing
|
||||
DROID_ORDER order); // what it should be doing
|
||||
|
||||
static void offscreenUpdate (DROID *pDroid,UDWORD dam,
|
||||
UDWORD x, UDWORD y,
|
||||
float fx,float fy,
|
||||
UWORD dir,
|
||||
DROID_ORDER order);
|
||||
|
@ -230,6 +227,7 @@ BOOL ForceDroidSync(const DROID* droidToSend)
|
|||
packageCheck(droidToSend);
|
||||
return NETend();
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
// send a droid info packet.
|
||||
static BOOL sendDroidCheck(void)
|
||||
|
@ -250,8 +248,6 @@ static BOOL sendDroidCheck(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
debug(LOG_SYNC, "sent droid check at tick %u, isMPDirtyBit = %d", (unsigned int)gameTime, isMPDirtyBit );
|
||||
|
||||
lastSent = gameTime;
|
||||
|
||||
NETbeginEncode(NET_CHECK_DROID, NET_ALL_PLAYERS);
|
||||
|
@ -300,6 +296,8 @@ static void packageCheck(const DROID* pD)
|
|||
uint32_t body = pD->body;
|
||||
float direction = pD->direction;
|
||||
float experience = pD->experience;
|
||||
float sMoveX = pD->sMove.fx;
|
||||
float sMoveY = pD->sMove.fy;
|
||||
|
||||
// Send the player to which the droid belongs
|
||||
NETuint8_t(&player);
|
||||
|
@ -319,28 +317,8 @@ static void packageCheck(const DROID* pD)
|
|||
// Direction it is going in
|
||||
NETfloat(&direction);
|
||||
|
||||
// Fractional move
|
||||
if (pD->order == DORDER_ATTACK
|
||||
|| pD->order == DORDER_MOVE
|
||||
|| pD->order == DORDER_RTB
|
||||
|| pD->order == DORDER_RTR)
|
||||
{
|
||||
float sMoveX = pD->sMove.fx;
|
||||
float sMoveY = pD->sMove.fy;
|
||||
|
||||
NETfloat(&sMoveX);
|
||||
NETfloat(&sMoveY);
|
||||
}
|
||||
// Non-fractional move, send regular coords
|
||||
else
|
||||
{
|
||||
uint16_t posX = pD->pos.x;
|
||||
uint16_t posY = pD->pos.y;
|
||||
|
||||
NETuint16_t(&posX);
|
||||
NETuint16_t(&posY);
|
||||
}
|
||||
|
||||
NETfloat(&sMoveX);
|
||||
NETfloat(&sMoveY);
|
||||
|
||||
if (pD->order == DORDER_ATTACK)
|
||||
{
|
||||
|
@ -369,8 +347,6 @@ BOOL recvDroidCheck()
|
|||
uint8_t count;
|
||||
int i;
|
||||
|
||||
debug(LOG_SYNC, "recvDroidCheck");
|
||||
|
||||
NETbeginDecode(NET_CHECK_DROID);
|
||||
|
||||
// Get the number of droids to expect
|
||||
|
@ -385,12 +361,14 @@ BOOL recvDroidCheck()
|
|||
BOOL onscreen;
|
||||
uint8_t player;
|
||||
float direction, experience;
|
||||
uint16_t x = 0, y = 0, tx, ty;
|
||||
uint16_t tx, ty;
|
||||
uint32_t ref, body, target = 0, secondaryOrder;
|
||||
|
||||
// Fetch the player
|
||||
NETuint8_t(&player);
|
||||
|
||||
ASSERT(!myResponsibility(player), "updating our own droids");
|
||||
|
||||
// Fetch the droid being checked
|
||||
NETuint32_t(&ref);
|
||||
|
||||
|
@ -407,20 +385,8 @@ BOOL recvDroidCheck()
|
|||
NETfloat(&direction);
|
||||
|
||||
// Fractional move
|
||||
if (order == DORDER_ATTACK
|
||||
|| order == DORDER_MOVE
|
||||
|| order == DORDER_RTB
|
||||
|| order == DORDER_RTR)
|
||||
{
|
||||
NETfloat(&fx);
|
||||
NETfloat(&fy);
|
||||
}
|
||||
// Regular move
|
||||
else
|
||||
{
|
||||
NETuint16_t(&x);
|
||||
NETuint16_t(&y);
|
||||
}
|
||||
NETfloat(&fx);
|
||||
NETfloat(&fy);
|
||||
|
||||
// Find out what the droid is aiming at
|
||||
if (order == DORDER_ATTACK)
|
||||
|
@ -473,28 +439,20 @@ BOOL recvDroidCheck()
|
|||
// Update the droid
|
||||
if (onscreen || isVtolDroid(pD))
|
||||
{
|
||||
onscreenUpdate(pD, body, x, y, fx, fy, direction, order);
|
||||
onscreenUpdate(pD, body, direction, order);
|
||||
}
|
||||
else
|
||||
{
|
||||
offscreenUpdate(pD, body, x, y, fx, fy, direction, order);
|
||||
offscreenUpdate(pD, body, fx, fy, direction, order);
|
||||
}
|
||||
|
||||
debug(LOG_SYNC, "difference in position for droid %u; was (%d, %d); did %s update",
|
||||
(unsigned int)pD->id, (int)x - pD->pos.x, (int)y - pD->pos.y,
|
||||
onscreen ? "onscreen" : "offscreen");
|
||||
|
||||
// If our version is similar to the actual one make a note of it
|
||||
if (abs(x - pD->pos.x) < TILE_UNITS * 2
|
||||
|| abs(y - pD->pos.y) < TILE_UNITS * 2)
|
||||
{
|
||||
pD->lastSync = gameTime;
|
||||
}
|
||||
debug(LOG_SYNC, "difference in position for droid %d; was (%g, %g); did %s update", (int)pD->id,
|
||||
fx - pD->sMove.fx, fy - pD->sMove.fy, onscreen ? "onscreen" : "offscreen");
|
||||
|
||||
// Update the higher level stuff
|
||||
if (!isVtolDroid(pD))
|
||||
{
|
||||
highLevelDroidUpdate(pD, x, y, secondaryOrder, order, psTarget, experience);
|
||||
highLevelDroidUpdate(pD, fx, fy, secondaryOrder, order, psTarget, experience);
|
||||
}
|
||||
|
||||
// ...and repeat!
|
||||
|
@ -509,7 +467,7 @@ BOOL recvDroidCheck()
|
|||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// higher order droid updating. Works mainly at the order level. comes after the main sync.
|
||||
static void highLevelDroidUpdate(DROID *psDroid,UDWORD x, UDWORD y,
|
||||
static void highLevelDroidUpdate(DROID *psDroid, float fx, float fy,
|
||||
UDWORD state, UDWORD order,
|
||||
BASE_OBJECT *psTarget,float experience)
|
||||
{
|
||||
|
@ -532,13 +490,15 @@ static void highLevelDroidUpdate(DROID *psDroid,UDWORD x, UDWORD y,
|
|||
|
||||
// see how well the sync worked, optionally update.
|
||||
// offscreen updates will make this ok each time.
|
||||
if(psDroid->order == DORDER_NONE && order == DORDER_NONE)
|
||||
if ((psDroid->order == DORDER_NONE && order == DORDER_NONE)
|
||||
|| (psDroid->order == DORDER_GUARD && order == DORDER_GUARD))
|
||||
{
|
||||
if( (abs(x- psDroid->pos.x)>(TILE_UNITS*2)) // if more than 2 tiles wrong.
|
||||
||(abs(y- psDroid->pos.y)>(TILE_UNITS*2)) )
|
||||
if( (fabs(fx - psDroid->sMove.fx)>(TILE_UNITS*2)) // if more than 2 tiles wrong.
|
||||
||(fabs(fy - psDroid->sMove.fy)>(TILE_UNITS*2)) )
|
||||
{
|
||||
turnOffMultiMsg(true);
|
||||
orderDroidLoc(psDroid, DORDER_MOVE,x,y);
|
||||
debug(LOG_SYNC, "Move order from %d,%d to %d,%d", (int)psDroid->pos.x, (int)psDroid->pos.y, (int)fx, (int)fy);
|
||||
orderDroidLoc(psDroid, DORDER_MOVE, fx, fy);
|
||||
turnOffMultiMsg(false);
|
||||
}
|
||||
}
|
||||
|
@ -548,14 +508,9 @@ static void highLevelDroidUpdate(DROID *psDroid,UDWORD x, UDWORD y,
|
|||
// droid on screen needs modifying
|
||||
static void onscreenUpdate(DROID *psDroid,
|
||||
UDWORD dam,
|
||||
UDWORD x,
|
||||
UDWORD y,
|
||||
float fx,
|
||||
float fy,
|
||||
UWORD dir,
|
||||
DROID_ORDER order)
|
||||
{
|
||||
|
||||
BASE_OBJECT *psClickedOn;
|
||||
BOOL bMouseOver = false;
|
||||
|
||||
|
@ -585,15 +540,25 @@ static void onscreenUpdate(DROID *psDroid,
|
|||
// droid offscreen needs modyfying.
|
||||
static void offscreenUpdate(DROID *psDroid,
|
||||
UDWORD dam,
|
||||
UDWORD x,
|
||||
UDWORD y,
|
||||
float fx,
|
||||
float fy,
|
||||
UWORD dir,
|
||||
DROID_ORDER order)
|
||||
{
|
||||
PROPULSION_STATS *psPropStats;
|
||||
SDWORD xdiff,ydiff, distSq;
|
||||
|
||||
if (psDroid->pos.x != (UDWORD)fx || psDroid->pos.y != (UDWORD)fy)
|
||||
{
|
||||
debug(LOG_SYNC, "Moving droid %d from (%u,%u) to (%u,%u) (has order %s)",
|
||||
(int)psDroid->id, psDroid->pos.x, psDroid->pos.y, (UDWORD)fx, (UDWORD)fy, getDroidOrderName(order));
|
||||
}
|
||||
|
||||
psDroid->pos.x = fx; // update x
|
||||
psDroid->pos.y = fy; // update y
|
||||
psDroid->sMove.fx = fx;
|
||||
psDroid->sMove.fy = fy;
|
||||
psDroid->direction = dir % 360; // update rotation
|
||||
psDroid->body = dam; // update damage
|
||||
|
||||
// stage one, update the droid's position & info, LOW LEVEL STUFF.
|
||||
if( order == DORDER_ATTACK
|
||||
|
@ -601,43 +566,11 @@ static void offscreenUpdate(DROID *psDroid,
|
|||
|| order == DORDER_RTB
|
||||
|| order == DORDER_RTR) // move order
|
||||
{
|
||||
|
||||
// calculate difference between remote and local
|
||||
xdiff = psDroid->pos.x - (UWORD)fx;
|
||||
ydiff = psDroid->pos.y - (UWORD)fy;
|
||||
distSq = (xdiff*xdiff) + (ydiff*ydiff);
|
||||
|
||||
// if more than 2 squares, jump it.
|
||||
if(distSq > (2*TILE_UNITS)*(2*TILE_UNITS) )
|
||||
{
|
||||
if( ((UDWORD)fx != 0) && ((UDWORD)fy != 0) )
|
||||
{
|
||||
debug(LOG_SYNC, "Jumping droid %d from (%u,%u) to (%u,%u)", (int)psDroid->id, psDroid->pos.x, psDroid->pos.y, (UDWORD)fx, (UDWORD)fy);
|
||||
|
||||
psDroid->sMove.fx = fx; //update x
|
||||
psDroid->sMove.fy = fy; //update y
|
||||
|
||||
psDroid->pos.x = (UWORD) fx; //update move progress
|
||||
psDroid->pos.y = (UWORD) fy;
|
||||
|
||||
psDroid->direction = dir % 360; // update rotation
|
||||
|
||||
// reroute the droid.
|
||||
turnOffMultiMsg(true);
|
||||
moveDroidTo(psDroid, psDroid->sMove.DestinationX,psDroid->sMove.DestinationY);
|
||||
turnOffMultiMsg(false);
|
||||
}
|
||||
}
|
||||
// reroute the droid.
|
||||
turnOffMultiMsg(true);
|
||||
moveDroidTo(psDroid, psDroid->sMove.DestinationX,psDroid->sMove.DestinationY);
|
||||
turnOffMultiMsg(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug(LOG_SYNC, "Moving droid %d from (%u,%u) to (%u,%u)", (int)psDroid->id, psDroid->pos.x, psDroid->pos.y, (UDWORD)fx, (UDWORD)fy);
|
||||
psDroid->pos.x = (UWORD)x; //update x
|
||||
psDroid->pos.y = (UWORD)y; //update y
|
||||
psDroid->direction = dir % 360; // update rotation
|
||||
}
|
||||
|
||||
psDroid->body = dam; // update damage
|
||||
|
||||
// stop droid if remote droid has stopped.
|
||||
if ((order == DORDER_NONE || order == DORDER_GUARD)
|
||||
|
@ -739,8 +672,6 @@ static BOOL sendStructureCheck(void)
|
|||
|
||||
lastSent = gameTime;
|
||||
|
||||
debug(LOG_SYNC, "sent structure check at tick %u, isMPDirtyBit = %d", (unsigned int)gameTime, isMPDirtyBit);
|
||||
|
||||
pS = pickAStructure();
|
||||
// Only send info about complete buildings
|
||||
if (pS && (pS->status == SS_BUILT))
|
||||
|
@ -810,6 +741,8 @@ BOOL recvStructureCheck()
|
|||
return false;
|
||||
}
|
||||
|
||||
ASSERT(!myResponsibility(player), "updating our own structures");
|
||||
|
||||
// If the structure exists our job is easy
|
||||
pS = IdToStruct(ref, player);
|
||||
if (pS)
|
||||
|
@ -970,8 +903,6 @@ static BOOL sendPowerCheck()
|
|||
|
||||
lastsent = gameTime;
|
||||
|
||||
debug(LOG_SYNC, "sent power check at tick %u, isMPDirtyBit = %d", (unsigned int)gameTime, isMPDirtyBit );
|
||||
|
||||
NETbeginEncode(NET_CHECK_POWER, NET_ALL_PLAYERS);
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&power);
|
||||
|
|
Loading…
Reference in New Issue