newnet: Fix power desynch on cancelling production. Make GAME_CHECK_POWER send a float, so it can actually recover from a power desynch.
parent
5c0d6f05ab
commit
6a25603032
|
@ -254,9 +254,9 @@ extern LOBBY_ERROR_TYPES LobbyError; // from src/multiint.c
|
|||
** ie ("trunk", "2.1.3", ...)
|
||||
************************************************************************************
|
||||
**/
|
||||
char VersionString[VersionStringSize] = "trunk, netcode 4.1";
|
||||
char VersionString[VersionStringSize] = "trunk, netcode 4.2";
|
||||
static int NETCODE_VERSION_MAJOR = 4;
|
||||
static int NETCODE_VERSION_MINOR = 1;
|
||||
static int NETCODE_VERSION_MINOR = 2;
|
||||
static int NETCODE_HASH = 0; // unused for now
|
||||
|
||||
static int checkSockets(const SocketSet* set, unsigned int timeout);
|
||||
|
|
33
src/droid.c
33
src/droid.c
|
@ -697,6 +697,21 @@ void droidBurn(DROID *psDroid)
|
|||
orderDroid( psDroid, DORDER_RUNBURN );
|
||||
}
|
||||
|
||||
void _syncDebugDroid(const char *function, DROID *psDroid, char ch)
|
||||
{
|
||||
_syncDebug(function, "%c droid%d = p%d;pos(%d,%d,%d),ord%d(%d,%d),act%d,so%X,bp%d, power = %f", ch,
|
||||
psDroid->id,
|
||||
|
||||
psDroid->player,
|
||||
psDroid->pos.x, psDroid->pos.y, psDroid->pos.z,
|
||||
psDroid->order, psDroid->orderX, psDroid->orderY,
|
||||
psDroid->action,
|
||||
psDroid->secondaryOrder,
|
||||
psDroid->body,
|
||||
|
||||
getPower(psDroid->player));
|
||||
}
|
||||
|
||||
/* The main update routine for all droids */
|
||||
void droidUpdate(DROID *psDroid)
|
||||
{
|
||||
|
@ -723,14 +738,7 @@ void droidUpdate(DROID *psDroid)
|
|||
}
|
||||
#endif
|
||||
|
||||
syncDebug("< droid%d = p%d;pos(%d,%d,%d),ord%d(%d,%d),act%d,so%X,bp%d, power = %f", psDroid->id,
|
||||
psDroid->player,
|
||||
psDroid->pos.x, psDroid->pos.y, psDroid->pos.z,
|
||||
psDroid->order, psDroid->orderX, psDroid->orderY,
|
||||
psDroid->action,
|
||||
psDroid->secondaryOrder,
|
||||
psDroid->body,
|
||||
getPower(psDroid->player));
|
||||
syncDebugDroid(psDroid, '<');
|
||||
|
||||
// Save old droid position, update time.
|
||||
psDroid->prevSpacetime = GET_SPACETIME(psDroid);
|
||||
|
@ -869,14 +877,7 @@ void droidUpdate(DROID *psDroid)
|
|||
}
|
||||
}
|
||||
|
||||
syncDebug("> droid%d = p%d;pos(%d,%d,%d),ord%d(%d,%d),act%d,so%X,bp%d, power = %f", psDroid->id,
|
||||
psDroid->player,
|
||||
psDroid->pos.x, psDroid->pos.y, psDroid->pos.z,
|
||||
psDroid->order, psDroid->orderX, psDroid->orderY,
|
||||
psDroid->action,
|
||||
psDroid->secondaryOrder,
|
||||
psDroid->body,
|
||||
getPower(psDroid->player));
|
||||
syncDebugDroid(psDroid, '>');
|
||||
|
||||
CHECK_DROID(psDroid);
|
||||
}
|
||||
|
|
|
@ -568,6 +568,9 @@ void templateSetParts(const DROID *psDroid, DROID_TEMPLATE *psTemplate);
|
|||
|
||||
void cancelBuild(DROID *psDroid);
|
||||
|
||||
#define syncDebugDroid(psDroid, ch) _syncDebugDroid(__FUNCTION__, psDroid, ch)
|
||||
void _syncDebugDroid(const char *function, DROID *psDroid, char ch);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
|
|
@ -466,6 +466,8 @@ void recvStructureInfo(NETQUEUE queue)
|
|||
return;
|
||||
}
|
||||
|
||||
syncDebugStructure(psStruct, '<');
|
||||
|
||||
turnOffMultiMsg(true);
|
||||
switch (structureInfo)
|
||||
{
|
||||
|
@ -479,4 +481,6 @@ void recvStructureInfo(NETQUEUE queue)
|
|||
debug(LOG_ERROR, "Invalid structureInfo %d", structureInfo);
|
||||
}
|
||||
turnOffMultiMsg(false);
|
||||
|
||||
syncDebugStructure(psStruct, '>');
|
||||
}
|
||||
|
|
|
@ -639,7 +639,7 @@ BOOL recvStructureCheck(NETQUEUE queue)
|
|||
}
|
||||
|
||||
static uint32_t powerCheckLastSent = 0;
|
||||
static uint32_t powerCheckLastPower[MAX_PLAYERS];
|
||||
static float powerCheckLastPower[MAX_PLAYERS];
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
// ////////////////////////////////////////////////////////////////////////
|
||||
|
@ -668,7 +668,7 @@ static BOOL sendPowerCheck()
|
|||
NETbeginEncode(NETgameQueue(selectedPlayer), GAME_CHECK_POWER);
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&gameTime);
|
||||
NETuint32_t(&powerCheckLastPower[player]);
|
||||
NETfloat(&powerCheckLastPower[player]);
|
||||
NETend();
|
||||
}
|
||||
}
|
||||
|
@ -679,12 +679,12 @@ BOOL recvPowerCheck(NETQUEUE queue)
|
|||
{
|
||||
uint8_t player;
|
||||
uint32_t synchTime;
|
||||
uint32_t power;
|
||||
float power;
|
||||
|
||||
NETbeginDecode(queue, GAME_CHECK_POWER);
|
||||
NETuint8_t(&player);
|
||||
NETuint32_t(&synchTime);
|
||||
NETuint32_t(&power);
|
||||
NETfloat(&power);
|
||||
NETend();
|
||||
|
||||
if (powerCheckLastSent != synchTime)
|
||||
|
@ -702,9 +702,9 @@ BOOL recvPowerCheck(NETQUEUE queue)
|
|||
|
||||
if (power != powerCheckLastPower[player])
|
||||
{
|
||||
uint32_t powerFrom = getPower(player);
|
||||
uint32_t powerTo = powerFrom + power - powerCheckLastPower[player];
|
||||
debug(LOG_SYNC, "GAME_CHECK_POWER: Adjusting power for player %d (%s) from %u to %u",
|
||||
float powerFrom = getPower(player);
|
||||
float powerTo = powerFrom + power - powerCheckLastPower[player];
|
||||
debug(LOG_SYNC, "GAME_CHECK_POWER: Adjusting power for player %d (%s) from %f to %f",
|
||||
(int)player, isHumanPlayer(player) ? "Human" : "AI", powerFrom, powerTo);
|
||||
setPower(player, powerTo);
|
||||
}
|
||||
|
|
|
@ -3823,6 +3823,23 @@ static float CalcStructureSmokeInterval(float damage)
|
|||
return (((1. - damage) + 0.1) * 10) * STRUCTURE_DAMAGE_SCALING;
|
||||
}
|
||||
|
||||
void _syncDebugStructure(const char *function, STRUCTURE *psStruct, char ch)
|
||||
{
|
||||
// TODO psBuilding->status == SS_BEING_BUILT test is because structure ids are not synchronised until after they start building...
|
||||
_syncDebug(function, "%c structure%d = p%d;pos(%d,%d,%d),stat%d,type%d,bld%d,pwr%d,bp%d, power = %f", ch,
|
||||
psStruct->status == SS_BEING_BUILT ? -1 : psStruct->id,
|
||||
|
||||
psStruct->player,
|
||||
psStruct->pos.x, psStruct->pos.y, psStruct->pos.z,
|
||||
psStruct->status,
|
||||
psStruct->pStructureType->type,
|
||||
psStruct->currentBuildPts,
|
||||
psStruct->currentPowerAccrued,
|
||||
psStruct->body,
|
||||
|
||||
getPower(psStruct->player));
|
||||
}
|
||||
|
||||
/* The main update routine for all Structures */
|
||||
void structureUpdate(STRUCTURE *psBuilding, bool mission)
|
||||
{
|
||||
|
@ -3831,16 +3848,7 @@ void structureUpdate(STRUCTURE *psBuilding, bool mission)
|
|||
Vector3i dv;
|
||||
int i;
|
||||
|
||||
// TODO psBuilding->status == SS_BEING_BUILT test is because structure ids are not synchronised until after they start building...
|
||||
syncDebug("< structure%d = p%d;pos(%d,%d,%d),stat%d,type%d,bld%d,pwr%d,bp%d, power = %f", psBuilding->status == SS_BEING_BUILT ? -1 : psBuilding->id,
|
||||
psBuilding->player,
|
||||
psBuilding->pos.x, psBuilding->pos.y, psBuilding->pos.z,
|
||||
psBuilding->status,
|
||||
psBuilding->pStructureType->type,
|
||||
psBuilding->currentBuildPts,
|
||||
psBuilding->currentPowerAccrued,
|
||||
psBuilding->body,
|
||||
getPower(psBuilding->player));
|
||||
syncDebugStructure(psBuilding, '<');
|
||||
|
||||
if (psBuilding->pStructureType->type == REF_GATE)
|
||||
{
|
||||
|
@ -4021,16 +4029,7 @@ void structureUpdate(STRUCTURE *psBuilding, bool mission)
|
|||
}
|
||||
}
|
||||
|
||||
// TODO psBuilding->status == SS_BEING_BUILT test is because structure ids are not synchronised until after they start building...
|
||||
syncDebug("> structure%d = p%d;pos(%d,%d,%d),stat%d,type%d,bld%d,pwr%d,bp%d, power = %f", psBuilding->status == SS_BEING_BUILT ? -1 : psBuilding->id,
|
||||
psBuilding->player,
|
||||
psBuilding->pos.x, psBuilding->pos.y, psBuilding->pos.z,
|
||||
psBuilding->status,
|
||||
psBuilding->pStructureType->type,
|
||||
psBuilding->currentBuildPts,
|
||||
psBuilding->currentPowerAccrued,
|
||||
psBuilding->body,
|
||||
getPower(psBuilding->player));
|
||||
syncDebugStructure(psBuilding, '>');
|
||||
|
||||
CHECK_STRUCTURE(psBuilding);
|
||||
}
|
||||
|
@ -6936,16 +6935,23 @@ void cancelProduction(STRUCTURE *psBuilding)
|
|||
|
||||
ASSERT_OR_RETURN( , StructIsFactory(psBuilding), "structure not a factory");
|
||||
|
||||
psFactory = &psBuilding->pFunctionality->factory;
|
||||
|
||||
if (bMultiMessages)
|
||||
{
|
||||
if (psBuilding->player == productionPlayer)
|
||||
{
|
||||
//clear the production run for this factory
|
||||
memset(asProductionRun[psFactory->psAssemblyPoint->factoryType][psFactory->psAssemblyPoint->factoryInc], 0, sizeof(PRODUCTION_RUN) * MAX_PROD_RUN);
|
||||
psFactory->productionLoops = 0;
|
||||
}
|
||||
|
||||
sendStructureInfo(psBuilding, STRUCTUREINFO_CANCELPRODUCTION, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
psFactory = &psBuilding->pFunctionality->factory;
|
||||
|
||||
//check its the correct factory
|
||||
if (psBuilding->player == productionPlayer && psFactory->psSubject)
|
||||
if (psFactory->psSubject)
|
||||
{
|
||||
// give the power back that was used until now
|
||||
int secondsToBuild = ((DROID_TEMPLATE*)psFactory->psSubject)->buildPoints/psFactory->productionOutput;
|
||||
|
@ -6961,15 +6967,13 @@ void cancelProduction(STRUCTURE *psBuilding)
|
|||
}
|
||||
addPower(psBuilding->player, powerUsed);
|
||||
|
||||
//clear the production run for this factory
|
||||
memset(asProductionRun[psFactory->psAssemblyPoint->factoryType][
|
||||
psFactory->psAssemblyPoint->factoryInc], 0, sizeof(PRODUCTION_RUN) *
|
||||
MAX_PROD_RUN);
|
||||
//clear the factories subject and quantity
|
||||
//clear the factory's subject
|
||||
psFactory->psSubject = NULL;
|
||||
psFactory->productionLoops = 0;
|
||||
//tell the interface
|
||||
intManufactureFinished(psBuilding);
|
||||
if (psBuilding->player == productionPlayer)
|
||||
{
|
||||
//tell the interface
|
||||
intManufactureFinished(psBuilding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -470,6 +470,9 @@ void checkStructure(const STRUCTURE* psStructure, const char * const location_de
|
|||
|
||||
extern void structureInitVars(void);
|
||||
|
||||
#define syncDebugStructure(psStruct, ch) _syncDebugStructure(__FUNCTION__, psStruct, ch)
|
||||
void _syncDebugStructure(const char *function, STRUCTURE *psStruct, char ch);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
|
Loading…
Reference in New Issue