Skip to content

Commit e7f4cb2

Browse files
authored
Merge pull request #40 from TeeMidnight/pr-netobjex-game-prediction
Implement `CNetObject_GameDataPrediction`
2 parents 84733b3 + 72bc691 commit e7f4cb2

5 files changed

Lines changed: 38 additions & 14 deletions

File tree

datasrc/network.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
"GAME_PAUSED"]) # todo 0.8: sort (1 para)
2222

23+
GamePredictionFlags = Flags("GAMEPREDICTIONFLAG", ["EVENT", "INPUT"])
2324

2425
RawHeader = '''
2526
@@ -82,6 +83,7 @@
8283
GameStateFlags,
8384
CoreEventFlags,
8485
RaceFlags,
86+
GamePredictionFlags,
8587
]
8688

8789
Objects = [
@@ -269,6 +271,10 @@
269271
NetIntRange("m_Precision", 0, 3),
270272
NetFlag("m_RaceFlags", RaceFlags),
271273
]),
274+
275+
NetObjectEx("GameDataPrediction", "game-data-prediction@netobj.teeworlds.wiki", [
276+
NetFlag("m_PredictionFlags", GamePredictionFlags),
277+
])
272278
]
273279

274280
Messages = [

src/engine/shared/snapshot.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ int CSnapshotBuilder::GetExtendedItemTypeIndex(int TypeID)
707707
}
708708
dbg_assert(m_NumExtendedItemTypes < MAX_EXTENDED_ITEM_TYPES, "too many extended item types");
709709
int Index = m_NumExtendedItemTypes;
710+
m_NumExtendedItemTypes++;
710711
m_aExtendedItemTypes[Index] = TypeID;
711712
if(AddExtendedItemType(Index))
712713
{

src/game/client/gameclient.cpp

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,6 @@ void CGameClient::OnNewSnapshot()
12951295

12961296
// limit evolving to 3 seconds
12971297
int EvolvePrevTick = minimum(pCharInfo->m_Prev.m_Tick + Client()->GameTickSpeed() * 3, Client()->PrevGameTick());
1298-
int EvolveCurTick = minimum(pCharInfo->m_Cur.m_Tick + Client()->GameTickSpeed() * 3, Client()->GameTick());
12991298

13001299
// reuse the evolved char
13011300
if(m_aClients[Item.m_ID].m_Evolved.m_Tick == EvolvePrevTick)
@@ -1304,17 +1303,7 @@ void CGameClient::OnNewSnapshot()
13041303
if(mem_comp(pData, pOld, sizeof(CNetObj_Character)) == 0)
13051304
pCharInfo->m_Cur = m_aClients[Item.m_ID].m_Evolved;
13061305
}
1307-
1308-
if(pCharInfo->m_Prev.m_Tick)
1309-
EvolveCharacter(&pCharInfo->m_Prev, EvolvePrevTick);
1310-
if(pCharInfo->m_Cur.m_Tick)
1311-
EvolveCharacter(&pCharInfo->m_Cur, EvolveCurTick);
1312-
1313-
m_aClients[Item.m_ID].m_Evolved = m_Snap.m_aCharacters[Item.m_ID].m_Cur;
13141306
}
1315-
1316-
if(Item.m_ID != m_LocalClientID || !Config()->m_ClPredict || Client()->State() == IClient::STATE_DEMOPLAYBACK)
1317-
ProcessTriggeredEvents(pCharInfo->m_Cur.m_TriggeredEvents, vec2(pCharInfo->m_Cur.m_X, pCharInfo->m_Cur.m_Y));
13181307
}
13191308
}
13201309
else if(Item.m_Type == NETOBJTYPE_SPECTATORINFO)
@@ -1370,6 +1359,10 @@ void CGameClient::OnNewSnapshot()
13701359
{
13711360
m_Snap.m_pGameDataRace = (const CNetObj_GameDataRace *) pData;
13721361
}
1362+
else if(Item.m_Type == NETOBJTYPE_GAMEDATAPREDICTION)
1363+
{
1364+
m_Snap.m_pGameDataPrediction = (const CNetObj_GameDataPrediction *) pData;
1365+
}
13731366
else if(Item.m_Type == NETOBJTYPE_FLAG)
13741367
{
13751368
m_Snap.m_apFlags[Item.m_ID % 2] = (const CNetObj_Flag *) pData;
@@ -1437,9 +1430,23 @@ void CGameClient::OnNewSnapshot()
14371430
}
14381431
}
14391432

1440-
// calc some player stats
1433+
// calc some player stats, also trigger events
14411434
for(int i = 0; i < MAX_CLIENTS; ++i)
14421435
{
1436+
if(m_Snap.m_aCharacters[i].m_Active)
1437+
{
1438+
int EvolvePrevTick = minimum(m_Snap.m_aCharacters[i].m_Prev.m_Tick + Client()->GameTickSpeed() * 3, Client()->PrevGameTick());
1439+
int EvolveCurTick = minimum(m_Snap.m_aCharacters[i].m_Cur.m_Tick + Client()->GameTickSpeed() * 3, Client()->GameTick());
1440+
if(m_Snap.m_aCharacters[i].m_Prev.m_Tick)
1441+
EvolveCharacter(&m_Snap.m_aCharacters[i].m_Prev, EvolvePrevTick);
1442+
if(m_Snap.m_aCharacters[i].m_Cur.m_Tick)
1443+
EvolveCharacter(&m_Snap.m_aCharacters[i].m_Cur, EvolveCurTick);
1444+
1445+
m_aClients[i].m_Evolved = m_Snap.m_aCharacters[i].m_Cur;
1446+
if(i != m_LocalClientID || !Config()->m_ClPredict || Client()->State() == IClient::STATE_DEMOPLAYBACK || !GameDataPredictInput() || !GameDataPredictEvent())
1447+
ProcessTriggeredEvents(m_Snap.m_aCharacters[i].m_Cur.m_TriggeredEvents, vec2(m_Snap.m_aCharacters[i].m_Cur.m_X, m_Snap.m_aCharacters[i].m_Cur.m_Y));
1448+
}
1449+
14431450
if(!m_Snap.m_apPlayerInfos[i])
14441451
continue;
14451452

@@ -1581,7 +1588,7 @@ void CGameClient::OnPredict()
15811588

15821589
mem_zero(&World.m_apCharacters[c]->m_Input, sizeof(World.m_apCharacters[c]->m_Input));
15831590

1584-
if(m_LocalClientID == c)
1591+
if(m_LocalClientID == c && GameDataPredictInput())
15851592
{
15861593
// apply player input
15871594
const int *pInput = Client()->GetInput(Tick);
@@ -1620,7 +1627,7 @@ void CGameClient::OnPredict()
16201627
// necessary to trigger events for them here. Also, our predictions
16211628
// for other players will often be wrong, so it's safer not to
16221629
// trigger events here.
1623-
if(m_LocalClientID != -1 && World.m_apCharacters[m_LocalClientID] && Config()->m_ClPredict)
1630+
if(m_LocalClientID != -1 && World.m_apCharacters[m_LocalClientID] && Config()->m_ClPredict && GameDataPredictInput() && GameDataPredictEvent())
16241631
{
16251632
ProcessTriggeredEvents(
16261633
World.m_apCharacters[m_LocalClientID]->m_TriggeredEvents,

src/game/client/gameclient.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ class CGameClient : public IGameClient
159159
const CNetObj_GameDataTeam *m_pGameDataTeam;
160160
const CNetObj_GameDataFlag *m_pGameDataFlag;
161161
const CNetObj_GameDataRace *m_pGameDataRace;
162+
const CNetObj_GameDataPrediction *m_pGameDataPrediction;
162163
int m_GameDataFlagSnapID;
163164

164165
int m_NotReadyCount;
@@ -309,6 +310,10 @@ class CGameClient : public IGameClient
309310

310311
int GetClientID(const char *pName);
311312

313+
// ----- gamedata prediction helper -----
314+
bool GameDataPredictInput() { return !m_Snap.m_pGameDataPrediction || m_Snap.m_pGameDataPrediction->m_PredictionFlags & GAMEPREDICTIONFLAG_INPUT; }
315+
bool GameDataPredictEvent() { return !m_Snap.m_pGameDataPrediction || m_Snap.m_pGameDataPrediction->m_PredictionFlags & GAMEPREDICTIONFLAG_EVENT; }
316+
312317
// ----- send functions -----
313318
// TODO: move these
314319
void SendSwitchTeam(int Team);

src/game/server/gamecontroller.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,11 @@ void IGameController::Snap(int SnappingClient)
744744
pGameDataTeam->m_TeamscoreBlue = m_aTeamscore[TEAM_BLUE];
745745
}
746746

747+
CNetObj_GameDataPrediction *pGameDataPrediction = static_cast<CNetObj_GameDataPrediction *>(Server()->SnapNewItem(NETOBJTYPE_GAMEDATAPREDICTION, 0, sizeof(CNetObj_GameDataPrediction)));
748+
if(!pGameDataPrediction)
749+
return;
750+
751+
pGameDataPrediction->m_PredictionFlags = GAMEPREDICTIONFLAG_EVENT | GAMEPREDICTIONFLAG_INPUT;
747752
// demo recording
748753
if(SnappingClient == -1)
749754
{

0 commit comments

Comments
 (0)