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-861f7616d084
master
Per Inge Mathisen 2010-01-30 16:31:51 +00:00 committed by Git SVN Gateway
parent 3a800c09a3
commit 6f052e0ed9
3 changed files with 43 additions and 116 deletions

View File

@ -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;

View File

@ -189,8 +189,6 @@ typedef struct DROID
// secondary order data
UDWORD secondaryOrder;
UDWORD lastSync; ///< multiplayer synchronization value.
/* Action data */
SDWORD action;
UDWORD actionX, actionY;

View File

@ -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);