mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +00:00
Merge pull request #635 from heinrich5991/pr_dummy_input_demo_filter
Refactor dummy input and demo filtering
This commit is contained in:
commit
4c1053c6c4
|
@ -8,7 +8,6 @@
|
|||
#include <engine/friends.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <versionsrv/versionsrv.h>
|
||||
#include <game/generated/protocol.h>
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -18,6 +17,8 @@ enum
|
|||
RECORDER_MAX=3,
|
||||
};
|
||||
|
||||
typedef bool (*CLIENTFUNC_FILTER)(const void *pData, int DataSize, void *pUser);
|
||||
|
||||
class IClient : public IInterface
|
||||
{
|
||||
MACRO_INTERFACE("client", 0)
|
||||
|
@ -39,14 +40,9 @@ protected:
|
|||
|
||||
int m_GameTickSpeed;
|
||||
public:
|
||||
int m_LocalIDs[2];
|
||||
char m_aNews[NEWS_SIZE];
|
||||
int64 m_ReconnectTime;
|
||||
|
||||
CNetObj_PlayerInput m_DummyInput;
|
||||
|
||||
bool m_DummySendConnInfo;
|
||||
|
||||
class CSnapItem
|
||||
{
|
||||
public:
|
||||
|
@ -190,7 +186,7 @@ public:
|
|||
|
||||
virtual void DemoSliceBegin() = 0;
|
||||
virtual void DemoSliceEnd() = 0;
|
||||
virtual void DemoSlice(const char *pDstPath, bool RemoveChat) = 0;
|
||||
virtual void DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void *pUser) = 0;
|
||||
|
||||
virtual void RequestDDNetSrvList() = 0;
|
||||
virtual bool EditorHasUnsavedData() = 0;
|
||||
|
@ -220,10 +216,9 @@ public:
|
|||
virtual void OnPredict() = 0;
|
||||
virtual void OnActivateEditor() = 0;
|
||||
|
||||
virtual int OnSnapInput(int *pData) = 0;
|
||||
virtual int OnSnapInput(int *pData, bool Dummy, bool Force) = 0;
|
||||
virtual void OnDummySwap() = 0;
|
||||
virtual void SendDummyInfo(bool Start) = 0;
|
||||
virtual void ResetDummyInput() = 0;
|
||||
virtual const CNetObj_PlayerInput &getPlayerInput(int dummy) = 0;
|
||||
|
||||
virtual const char *GetItemName(int Type) = 0;
|
||||
virtual const char *Version() = 0;
|
||||
|
|
|
@ -324,14 +324,8 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta)
|
|||
m_CurrentInput[1] = 0;
|
||||
m_LastDummy = 0;
|
||||
m_LastDummy2 = 0;
|
||||
m_LocalIDs[0] = 0;
|
||||
m_LocalIDs[1] = 0;
|
||||
m_Fire = 0;
|
||||
|
||||
mem_zero(&m_aInputs, sizeof(m_aInputs));
|
||||
mem_zero(&m_DummyInput, sizeof(m_DummyInput));
|
||||
mem_zero(&HammerInput, sizeof(HammerInput));
|
||||
HammerInput.m_Fire = 0;
|
||||
|
||||
m_State = IClient::STATE_OFFLINE;
|
||||
m_aServerAddressStr[0] = 0;
|
||||
|
@ -481,106 +475,44 @@ void CClient::SendInput()
|
|||
if(m_PredTick[g_Config.m_ClDummy] <= 0)
|
||||
return;
|
||||
|
||||
// fetch input
|
||||
int Size = GameClient()->OnSnapInput(m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_aData);
|
||||
|
||||
if(Size)
|
||||
if(m_LastDummy != g_Config.m_ClDummy)
|
||||
{
|
||||
// pack input
|
||||
CMsgPacker Msg(NETMSG_INPUT);
|
||||
Msg.AddInt(m_AckGameTick[g_Config.m_ClDummy]);
|
||||
Msg.AddInt(m_PredTick[g_Config.m_ClDummy]);
|
||||
Msg.AddInt(Size);
|
||||
|
||||
m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_Tick = m_PredTick[g_Config.m_ClDummy];
|
||||
m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_PredictedTime = m_PredictedTime.Get(Now);
|
||||
m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_Time = Now;
|
||||
|
||||
// pack it
|
||||
for(int i = 0; i < Size/4; i++)
|
||||
Msg.AddInt(m_aInputs[g_Config.m_ClDummy][m_CurrentInput[g_Config.m_ClDummy]].m_aData[i]);
|
||||
|
||||
m_CurrentInput[g_Config.m_ClDummy]++;
|
||||
m_CurrentInput[g_Config.m_ClDummy]%=200;
|
||||
|
||||
SendMsgEx(&Msg, MSGFLAG_FLUSH);
|
||||
}
|
||||
|
||||
if(m_LastDummy != (bool)g_Config.m_ClDummy)
|
||||
{
|
||||
m_DummyInput = GameClient()->getPlayerInput(!g_Config.m_ClDummy);
|
||||
m_LastDummy = g_Config.m_ClDummy;
|
||||
|
||||
if (g_Config.m_ClDummyResetOnSwitch)
|
||||
{
|
||||
m_DummyInput.m_Jump = 0;
|
||||
m_DummyInput.m_Hook = 0;
|
||||
if(m_DummyInput.m_Fire & 1)
|
||||
m_DummyInput.m_Fire++;
|
||||
m_DummyInput.m_Direction = 0;
|
||||
GameClient()->ResetDummyInput();
|
||||
}
|
||||
GameClient()->OnDummySwap();
|
||||
}
|
||||
|
||||
if(!g_Config.m_ClDummy)
|
||||
m_LocalIDs[0] = ((CGameClient *)GameClient())->m_Snap.m_LocalClientID;
|
||||
else
|
||||
m_LocalIDs[1] = ((CGameClient *)GameClient())->m_Snap.m_LocalClientID;
|
||||
|
||||
if(m_DummyConnected)
|
||||
bool Force = false;
|
||||
// fetch input
|
||||
for(int Dummy = 0; Dummy < 2; Dummy++)
|
||||
{
|
||||
if(!g_Config.m_ClDummyHammer)
|
||||
if(!m_DummyConnected && Dummy != 0)
|
||||
{
|
||||
if(m_Fire != 0)
|
||||
{
|
||||
m_DummyInput.m_Fire = HammerInput.m_Fire;
|
||||
m_Fire = 0;
|
||||
}
|
||||
|
||||
if(!Size && (!m_DummyInput.m_Direction && !m_DummyInput.m_Jump && !m_DummyInput.m_Hook))
|
||||
return;
|
||||
|
||||
// pack input
|
||||
CMsgPacker Msg(NETMSG_INPUT);
|
||||
Msg.AddInt(m_AckGameTick[!g_Config.m_ClDummy]);
|
||||
Msg.AddInt(m_PredTick[!g_Config.m_ClDummy]);
|
||||
Msg.AddInt(sizeof(m_DummyInput));
|
||||
|
||||
// pack it
|
||||
for(unsigned int i = 0; i < sizeof(m_DummyInput)/4; i++)
|
||||
Msg.AddInt(((int*) &m_DummyInput)[i]);
|
||||
|
||||
SendMsgExY(&Msg, MSGFLAG_FLUSH, true, !g_Config.m_ClDummy);
|
||||
break;
|
||||
}
|
||||
else
|
||||
int i = g_Config.m_ClDummy ^ Dummy;
|
||||
int Size = GameClient()->OnSnapInput(m_aInputs[i][m_CurrentInput[i]].m_aData, Dummy, Force);
|
||||
|
||||
if(Size)
|
||||
{
|
||||
if ((((float) m_Fire / 12.5) - (int ((float) m_Fire / 12.5))) > 0.01)
|
||||
{
|
||||
m_Fire++;
|
||||
return;
|
||||
}
|
||||
m_Fire++;
|
||||
|
||||
HammerInput.m_Fire+=2;
|
||||
HammerInput.m_WantedWeapon = 1;
|
||||
|
||||
vec2 Main = ((CGameClient *)GameClient())->m_LocalCharacterPos;
|
||||
vec2 Dummy = ((CGameClient *)GameClient())->m_aClients[m_LocalIDs[!g_Config.m_ClDummy]].m_Predicted.m_Pos;
|
||||
vec2 Dir = Main - Dummy;
|
||||
HammerInput.m_TargetX = Dir.x;
|
||||
HammerInput.m_TargetY = Dir.y;
|
||||
|
||||
// pack input
|
||||
CMsgPacker Msg(NETMSG_INPUT);
|
||||
Msg.AddInt(m_AckGameTick[!g_Config.m_ClDummy]);
|
||||
Msg.AddInt(m_PredTick[!g_Config.m_ClDummy]);
|
||||
Msg.AddInt(sizeof(HammerInput));
|
||||
Msg.AddInt(m_AckGameTick[i]);
|
||||
Msg.AddInt(m_PredTick[i]);
|
||||
Msg.AddInt(Size);
|
||||
|
||||
m_aInputs[i][m_CurrentInput[i]].m_Tick = m_PredTick[i];
|
||||
m_aInputs[i][m_CurrentInput[i]].m_PredictedTime = m_PredictedTime.Get(Now);
|
||||
m_aInputs[i][m_CurrentInput[i]].m_Time = Now;
|
||||
|
||||
// pack it
|
||||
for(unsigned int i = 0; i < sizeof(HammerInput)/4; i++)
|
||||
Msg.AddInt(((int*) &HammerInput)[i]);
|
||||
for(int k = 0; k < Size/4; k++)
|
||||
Msg.AddInt(m_aInputs[i][m_CurrentInput[i]].m_aData[k]);
|
||||
|
||||
SendMsgExY(&Msg, MSGFLAG_FLUSH, true, !g_Config.m_ClDummy);
|
||||
m_CurrentInput[i]++;
|
||||
m_CurrentInput[i] %= 200;
|
||||
|
||||
SendMsgExY(&Msg, MSGFLAG_FLUSH, true, i);
|
||||
Force = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -887,21 +819,6 @@ int CClient::SendMsgExY(CMsgPacker *pMsg, int Flags, bool System, int NetClient)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void CClient::DummyInfo()
|
||||
{
|
||||
CNetMsg_Cl_ChangeInfo Msg;
|
||||
Msg.m_pName = g_Config.m_ClDummyName;
|
||||
Msg.m_pClan = g_Config.m_ClDummyClan;
|
||||
Msg.m_Country = g_Config.m_ClDummyCountry;
|
||||
Msg.m_pSkin = g_Config.m_ClDummySkin;
|
||||
Msg.m_UseCustomColor = g_Config.m_ClDummyUseCustomColor;
|
||||
Msg.m_ColorBody = g_Config.m_ClDummyColorBody;
|
||||
Msg.m_ColorFeet = g_Config.m_ClDummyColorFeet;
|
||||
CMsgPacker Packer(Msg.MsgID());
|
||||
Msg.Pack(&Packer);
|
||||
SendMsgExY(&Packer, MSGFLAG_VITAL);
|
||||
}
|
||||
|
||||
void CClient::GetServerInfo(CServerInfo *pServerInfo)
|
||||
{
|
||||
mem_copy(pServerInfo, &m_CurrentServerInfo, sizeof(m_CurrentServerInfo));
|
||||
|
@ -1259,11 +1176,11 @@ void CClient::ProcessConnlessPacket(CNetChunk *pPacket)
|
|||
|
||||
mem_copy(m_aNews, (char*)pPacket->m_pData + sizeof(VERSIONSRV_NEWS), NEWS_SIZE);
|
||||
|
||||
IOHANDLE newsFile = m_pStorage->OpenFile("ddnet-news.txt", IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||
if (newsFile)
|
||||
IOHANDLE NewsFile = m_pStorage->OpenFile("ddnet-news.txt", IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||
if (NewsFile)
|
||||
{
|
||||
io_write(newsFile, m_aNews, sizeof(m_aNews));
|
||||
io_close(newsFile);
|
||||
io_write(NewsFile, m_aNews, sizeof(m_aNews));
|
||||
io_close(NewsFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3080,12 +2997,12 @@ void CClient::Con_DemoSliceEnd(IConsole::IResult *pResult, void *pUserData)
|
|||
pSelf->DemoSliceEnd();
|
||||
}
|
||||
|
||||
void CClient::DemoSlice(const char *pDstPath, bool RemoveChat)
|
||||
void CClient::DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void *pUser)
|
||||
{
|
||||
if (m_DemoPlayer.IsPlaying())
|
||||
{
|
||||
const char *pDemoFileName = m_DemoPlayer.GetDemoFileName();
|
||||
m_DemoEditor.Slice(pDemoFileName, pDstPath, g_Config.m_ClDemoSliceBegin, g_Config.m_ClDemoSliceEnd, RemoveChat);
|
||||
m_DemoEditor.Slice(pDemoFileName, pDstPath, g_Config.m_ClDemoSliceBegin, g_Config.m_ClDemoSliceEnd, pfnFilter, pUser);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ class CClient : public IClient, public CDemoPlayer::IListener
|
|||
int m_CurrentInput[2];
|
||||
bool m_LastDummy;
|
||||
bool m_LastDummy2;
|
||||
CNetObj_PlayerInput HammerInput;
|
||||
bool m_DummySendConnInfo;
|
||||
|
||||
// graphs
|
||||
CGraph m_InputtimeMarginGraph;
|
||||
|
@ -261,10 +261,8 @@ public:
|
|||
virtual void DummyConnect();
|
||||
virtual bool DummyConnected();
|
||||
virtual bool DummyConnecting();
|
||||
void DummyInfo();
|
||||
int m_DummyConnected;
|
||||
int m_LastDummyConnectTime;
|
||||
int m_Fire;
|
||||
|
||||
virtual void GetServerInfo(CServerInfo *pServerInfo);
|
||||
void ServerInfoRequest();
|
||||
|
@ -386,7 +384,7 @@ public:
|
|||
|
||||
virtual void DemoSliceBegin();
|
||||
virtual void DemoSliceEnd();
|
||||
virtual void DemoSlice(const char *pDstPath, bool RemoveChat);
|
||||
virtual void DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void *pUser);
|
||||
|
||||
void RequestDDNetSrvList();
|
||||
bool EditorHasUnsavedData() { return m_pEditor->HasUnsavedData(); }
|
||||
|
|
|
@ -12,6 +12,8 @@ enum
|
|||
|
||||
const double g_aSpeeds[] = {0.1, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 4.0, 8.0};
|
||||
|
||||
typedef bool (*DEMOFUNC_FILTER)(const void *pData, int DataSize, void *pUser);
|
||||
|
||||
struct CDemoHeader
|
||||
{
|
||||
unsigned char m_aMarker[7];
|
||||
|
@ -84,7 +86,7 @@ class IDemoEditor : public IInterface
|
|||
MACRO_INTERFACE("demoeditor", 0)
|
||||
public:
|
||||
|
||||
virtual void Slice(const char *pDemo, const char *pDst, int StartTick, int EndTick, bool RemoveChat) = 0;
|
||||
virtual void Slice(const char *pDemo, const char *pDst, int StartTick, int EndTick, DEMOFUNC_FILTER pfnFilter, void *pUser) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <engine/storage.h>
|
||||
|
||||
#include <engine/shared/config.h>
|
||||
#include <game/generated/protocol.h>
|
||||
|
||||
#include "compression.h"
|
||||
#include "demo.h"
|
||||
|
@ -26,17 +25,21 @@ static const int gs_NumMarkersOffset = 176;
|
|||
CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta, bool DelayedMapData)
|
||||
{
|
||||
m_File = 0;
|
||||
m_pfnFilter = 0;
|
||||
m_pUser = 0;
|
||||
m_LastTickMarker = -1;
|
||||
m_pSnapshotDelta = pSnapshotDelta;
|
||||
m_DelayedMapData = DelayedMapData;
|
||||
}
|
||||
|
||||
// Record
|
||||
int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetVersion, const char *pMap, unsigned Crc, const char *pType, unsigned int MapSize, unsigned char *pMapData, bool RemoveChat)
|
||||
int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetVersion, const char *pMap, unsigned Crc, const char *pType, unsigned int MapSize, unsigned char *pMapData, DEMOFUNC_FILTER pfnFilter, void *pUser)
|
||||
{
|
||||
m_pfnFilter = pfnFilter;
|
||||
m_pUser = pUser;
|
||||
|
||||
m_MapSize = MapSize;
|
||||
m_pMapData = pMapData;
|
||||
m_RemoveChat = RemoveChat;
|
||||
|
||||
IOHANDLE DemoFile = pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
|
||||
if(!DemoFile)
|
||||
|
@ -278,23 +281,13 @@ void CDemoRecorder::RecordSnapshot(int Tick, const void *pData, int Size)
|
|||
|
||||
void CDemoRecorder::RecordMessage(const void *pData, int Size)
|
||||
{
|
||||
if (m_RemoveChat)
|
||||
if(m_pfnFilter)
|
||||
{
|
||||
CUnpacker Unpacker;
|
||||
Unpacker.Reset(pData, Size);
|
||||
|
||||
// unpack msgid and system flag
|
||||
int Msg = Unpacker.GetInt();
|
||||
int Sys = Msg&1;
|
||||
Msg >>= 1;
|
||||
|
||||
if(Unpacker.Error())
|
||||
return;
|
||||
|
||||
if(!Sys && Msg == NETMSGTYPE_SV_CHAT)
|
||||
if(m_pfnFilter(pData, Size, m_pUser))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Write(CHUNKTYPE_MESSAGE, pData, Size);
|
||||
}
|
||||
|
||||
|
@ -948,7 +941,7 @@ void CDemoEditor::Init(const char *pNetVersion, class CSnapshotDelta *pSnapshotD
|
|||
m_pStorage = pStorage;
|
||||
}
|
||||
|
||||
void CDemoEditor::Slice(const char *pDemo, const char *pDst, int StartTick, int EndTick, bool RemoveChat)
|
||||
void CDemoEditor::Slice(const char *pDemo, const char *pDst, int StartTick, int EndTick, DEMOFUNC_FILTER pfnFilter, void *pUser)
|
||||
{
|
||||
class CDemoPlayer DemoPlayer(m_pSnapshotDelta);
|
||||
class CDemoRecorder DemoRecorder(m_pSnapshotDelta);
|
||||
|
@ -966,7 +959,7 @@ void CDemoEditor::Slice(const char *pDemo, const char *pDst, int StartTick, int
|
|||
return;
|
||||
|
||||
const CDemoPlayer::CMapInfo *pMapInfo = m_pDemoPlayer->GetMapInfo();
|
||||
if (m_pDemoRecorder->Start(m_pStorage, m_pConsole, pDst, m_pNetVersion, pMapInfo->m_aName, pMapInfo->m_Crc, "client", 0, 0, RemoveChat) == -1)
|
||||
if (m_pDemoRecorder->Start(m_pStorage, m_pConsole, pDst, m_pNetVersion, pMapInfo->m_aName, pMapInfo->m_Crc, "client", 0, 0, pfnFilter, pUser) == -1)
|
||||
return;
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@ class CDemoRecorder : public IDemoRecorder
|
|||
bool m_DelayedMapData;
|
||||
unsigned int m_MapSize;
|
||||
unsigned char *m_pMapData;
|
||||
bool m_RemoveChat;
|
||||
|
||||
DEMOFUNC_FILTER m_pfnFilter;
|
||||
void *m_pUser;
|
||||
|
||||
void WriteTickMarker(int Tick, int Keyframe);
|
||||
void Write(int Type, const void *pData, int Size);
|
||||
|
@ -30,7 +32,7 @@ public:
|
|||
CDemoRecorder(class CSnapshotDelta *pSnapshotDelta, bool DelayedMapData = false);
|
||||
CDemoRecorder() {}
|
||||
|
||||
int Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetversion, const char *pMap, unsigned MapCrc, const char *pType, unsigned int MapSize = 0, unsigned char *pMapData = 0, bool RemoveChat = false);
|
||||
int Start(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, const char *pNetversion, const char *pMap, unsigned MapCrc, const char *pType, unsigned int MapSize = 0, unsigned char *pMapData = 0, DEMOFUNC_FILTER pfnFilter = 0, void *pUser = 0);
|
||||
int Stop(bool Finalize = false);
|
||||
void AddDemoMarker();
|
||||
|
||||
|
@ -156,7 +158,7 @@ class CDemoEditor : public IDemoEditor, public CDemoPlayer::IListener
|
|||
|
||||
public:
|
||||
virtual void Init(const char *pNetVersion, class CSnapshotDelta *pSnapshotDelta, class IConsole *pConsole, class IStorage *pStorage);
|
||||
virtual void Slice(const char *pDemo, const char *pDst, int StartTick, int EndTick, bool RemoveChat);
|
||||
virtual void Slice(const char *pDemo, const char *pDst, int StartTick, int EndTick, DEMOFUNC_FILTER pfnFilter, void *pUser);
|
||||
|
||||
virtual void OnDemoPlayerSnapshot(void *pData, int Size);
|
||||
virtual void OnDemoPlayerMessage(void *pData, int Size);
|
||||
|
|
|
@ -483,13 +483,13 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
|
|||
// check for highlighted name
|
||||
if (Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
if(ClientID != m_pClient->Client()->m_LocalIDs[0])
|
||||
if(ClientID != m_pClient->m_LocalIDs[0])
|
||||
{
|
||||
// main character
|
||||
if (LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->Client()->m_LocalIDs[0]].m_aName))
|
||||
if (LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->m_LocalIDs[0]].m_aName))
|
||||
Highlighted = true;
|
||||
// dummy
|
||||
if(m_pClient->Client()->DummyConnected() && LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->Client()->m_LocalIDs[1]].m_aName))
|
||||
if(m_pClient->Client()->DummyConnected() && LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->m_LocalIDs[1]].m_aName))
|
||||
Highlighted = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,19 +74,19 @@ void CControls::OnReset()
|
|||
m_OldMouseX = m_OldMouseY = 0.0f;
|
||||
}
|
||||
|
||||
void CControls::ResetInput(int dummy)
|
||||
void CControls::ResetInput(int Dummy)
|
||||
{
|
||||
m_LastData[dummy].m_Direction = 0;
|
||||
m_LastData[Dummy].m_Direction = 0;
|
||||
//m_LastData.m_Hook = 0;
|
||||
// simulate releasing the fire button
|
||||
if((m_LastData[dummy].m_Fire&1) != 0)
|
||||
m_LastData[dummy].m_Fire++;
|
||||
m_LastData[dummy].m_Fire &= INPUT_STATE_MASK;
|
||||
m_LastData[dummy].m_Jump = 0;
|
||||
m_InputData[dummy] = m_LastData[dummy];
|
||||
if((m_LastData[Dummy].m_Fire&1) != 0)
|
||||
m_LastData[Dummy].m_Fire++;
|
||||
m_LastData[Dummy].m_Fire &= INPUT_STATE_MASK;
|
||||
m_LastData[Dummy].m_Jump = 0;
|
||||
m_InputData[Dummy] = m_LastData[Dummy];
|
||||
|
||||
m_InputDirectionLeft[dummy] = 0;
|
||||
m_InputDirectionRight[dummy] = 0;
|
||||
m_InputDirectionLeft[Dummy] = 0;
|
||||
m_InputDirectionRight[Dummy] = 0;
|
||||
}
|
||||
|
||||
void CControls::OnRelease()
|
||||
|
@ -264,22 +264,20 @@ int CControls::SnapInput(int *pData)
|
|||
// dummy copy moves
|
||||
if(g_Config.m_ClDummyCopyMoves)
|
||||
{
|
||||
CNetObj_PlayerInput *DummyInput = &Client()->m_DummyInput;
|
||||
DummyInput->m_Direction = m_InputData[g_Config.m_ClDummy].m_Direction;
|
||||
DummyInput->m_Hook = m_InputData[g_Config.m_ClDummy].m_Hook;
|
||||
DummyInput->m_Jump = m_InputData[g_Config.m_ClDummy].m_Jump;
|
||||
DummyInput->m_PlayerFlags = m_InputData[g_Config.m_ClDummy].m_PlayerFlags;
|
||||
DummyInput->m_TargetX = m_InputData[g_Config.m_ClDummy].m_TargetX;
|
||||
DummyInput->m_TargetY = m_InputData[g_Config.m_ClDummy].m_TargetY;
|
||||
DummyInput->m_WantedWeapon = m_InputData[g_Config.m_ClDummy].m_WantedWeapon;
|
||||
CNetObj_PlayerInput *pDummyInput = &m_pClient->m_DummyInput;
|
||||
pDummyInput->m_Direction = m_InputData[g_Config.m_ClDummy].m_Direction;
|
||||
pDummyInput->m_Hook = m_InputData[g_Config.m_ClDummy].m_Hook;
|
||||
pDummyInput->m_Jump = m_InputData[g_Config.m_ClDummy].m_Jump;
|
||||
pDummyInput->m_PlayerFlags = m_InputData[g_Config.m_ClDummy].m_PlayerFlags;
|
||||
pDummyInput->m_TargetX = m_InputData[g_Config.m_ClDummy].m_TargetX;
|
||||
pDummyInput->m_TargetY = m_InputData[g_Config.m_ClDummy].m_TargetY;
|
||||
pDummyInput->m_WantedWeapon = m_InputData[g_Config.m_ClDummy].m_WantedWeapon;
|
||||
|
||||
pDummyInput->m_Fire += m_InputData[g_Config.m_ClDummy].m_Fire - m_LastData[g_Config.m_ClDummy].m_Fire;
|
||||
pDummyInput->m_NextWeapon += m_InputData[g_Config.m_ClDummy].m_NextWeapon - m_LastData[g_Config.m_ClDummy].m_NextWeapon;
|
||||
pDummyInput->m_PrevWeapon += m_InputData[g_Config.m_ClDummy].m_PrevWeapon - m_LastData[g_Config.m_ClDummy].m_PrevWeapon;
|
||||
|
||||
|
||||
DummyInput->m_Fire += m_InputData[g_Config.m_ClDummy].m_Fire - m_LastData[g_Config.m_ClDummy].m_Fire;
|
||||
DummyInput->m_NextWeapon += m_InputData[g_Config.m_ClDummy].m_NextWeapon - m_LastData[g_Config.m_ClDummy].m_NextWeapon;
|
||||
DummyInput->m_PrevWeapon += m_InputData[g_Config.m_ClDummy].m_PrevWeapon - m_LastData[g_Config.m_ClDummy].m_PrevWeapon;
|
||||
|
||||
m_InputData[!g_Config.m_ClDummy] = *DummyInput;
|
||||
m_InputData[!g_Config.m_ClDummy] = *pDummyInput;
|
||||
}
|
||||
|
||||
// stress testing
|
||||
|
|
|
@ -151,9 +151,9 @@ void CEmoticon::OnRender()
|
|||
|
||||
CTeeRenderInfo *pTeeInfo;
|
||||
if(g_Config.m_ClDummy)
|
||||
pTeeInfo = &m_pClient->m_aClients[m_pClient->Client()->m_LocalIDs[1]].m_RenderInfo;
|
||||
pTeeInfo = &m_pClient->m_aClients[m_pClient->m_LocalIDs[1]].m_RenderInfo;
|
||||
else
|
||||
pTeeInfo = &m_pClient->m_aClients[m_pClient->Client()->m_LocalIDs[0]].m_RenderInfo;
|
||||
pTeeInfo = &m_pClient->m_aClients[m_pClient->m_LocalIDs[0]].m_RenderInfo;
|
||||
|
||||
Graphics()->TextureSet(pTeeInfo->m_Texture);
|
||||
|
||||
|
|
|
@ -245,6 +245,7 @@ class CMenus : public CComponent
|
|||
void RenderNews(CUIRect MainView);
|
||||
|
||||
// found in menus_demo.cpp
|
||||
static bool DemoFilterChat(const void *pData, int Size, void *pUser);
|
||||
void RenderDemoPlayer(CUIRect MainView);
|
||||
void RenderDemoList(CUIRect MainView);
|
||||
|
||||
|
|
|
@ -44,6 +44,24 @@ int CMenus::DoButton_Sprite(const void *pID, int ImageID, int SpriteID, int Chec
|
|||
return UI()->DoButtonLogic(pID, "", Checked, pRect);
|
||||
}
|
||||
|
||||
bool CMenus::DemoFilterChat(const void *pData, int Size, void *pUser)
|
||||
{
|
||||
bool DoFilterChat = *(bool *)pUser;
|
||||
if(!DoFilterChat)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CUnpacker Unpacker;
|
||||
Unpacker.Reset(pData, Size);
|
||||
|
||||
int Msg = Unpacker.GetInt();
|
||||
int Sys = Msg&1;
|
||||
Msg >>= 1;
|
||||
|
||||
return !Unpacker.Error() && !Sys && Msg == NETMSGTYPE_SV_CHAT;
|
||||
}
|
||||
|
||||
void CMenus::RenderDemoPlayer(CUIRect MainView)
|
||||
{
|
||||
const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
|
||||
|
@ -116,7 +134,7 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
|
|||
|
||||
char aPath[512];
|
||||
str_format(aPath, sizeof(aPath), "%s/%s", m_aCurrentDemoFolder, m_aCurrentDemoFile);
|
||||
Client()->DemoSlice(aPath, s_RemoveChat);
|
||||
Client()->DemoSlice(aPath, CMenus::DemoFilterChat, &s_RemoveChat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,16 +110,6 @@ const char *CGameClient::Version() { return GAME_VERSION; }
|
|||
const char *CGameClient::NetVersion() { return GAME_NETVERSION; }
|
||||
const char *CGameClient::GetItemName(int Type) { return m_NetObjHandler.GetObjName(Type); }
|
||||
|
||||
const CNetObj_PlayerInput &CGameClient::getPlayerInput(int dummy)
|
||||
{
|
||||
return m_pControls->m_InputData[dummy];
|
||||
}
|
||||
|
||||
void CGameClient::ResetDummyInput()
|
||||
{
|
||||
m_pControls->ResetInput(!g_Config.m_ClDummy);
|
||||
}
|
||||
|
||||
void CGameClient::OnConsoleInit()
|
||||
{
|
||||
m_pEngine = Kernel()->RequestInterface<IEngine>();
|
||||
|
@ -397,10 +387,61 @@ void CGameClient::OnUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int CGameClient::OnSnapInput(int *pData)
|
||||
void CGameClient::OnDummySwap()
|
||||
{
|
||||
return m_pControls->SnapInput(pData);
|
||||
if (g_Config.m_ClDummyResetOnSwitch)
|
||||
{
|
||||
m_pControls->ResetInput(!g_Config.m_ClDummy);
|
||||
}
|
||||
m_DummyInput = m_pControls->m_InputData[!g_Config.m_ClDummy];
|
||||
}
|
||||
|
||||
int CGameClient::OnSnapInput(int *pData, bool Dummy, bool Force)
|
||||
{
|
||||
m_LocalIDs[g_Config.m_ClDummy] = m_Snap.m_LocalClientID;
|
||||
|
||||
if (!Dummy)
|
||||
{
|
||||
return m_pControls->SnapInput(pData);
|
||||
}
|
||||
|
||||
if(!g_Config.m_ClDummyHammer)
|
||||
{
|
||||
if(m_DummyFire != 0)
|
||||
{
|
||||
m_DummyInput.m_Fire = m_HammerInput.m_Fire;
|
||||
m_DummyFire = 0;
|
||||
}
|
||||
|
||||
if(!Force && (!m_DummyInput.m_Direction && !m_DummyInput.m_Jump && !m_DummyInput.m_Hook))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem_copy(pData, &m_DummyInput, sizeof(m_DummyInput));
|
||||
return sizeof(m_DummyInput);
|
||||
}
|
||||
else
|
||||
{
|
||||
if((m_DummyFire / 12.5) - (int)(m_DummyFire / 12.5) > 0.01)
|
||||
{
|
||||
m_DummyFire++;
|
||||
return 0;
|
||||
}
|
||||
m_DummyFire++;
|
||||
|
||||
m_HammerInput.m_Fire += 2;
|
||||
m_HammerInput.m_WantedWeapon = 1;
|
||||
|
||||
vec2 Main = m_LocalCharacterPos;
|
||||
vec2 Dummy = m_aClients[m_LocalIDs[!g_Config.m_ClDummy]].m_Predicted.m_Pos;
|
||||
vec2 Dir = Main - Dummy;
|
||||
m_HammerInput.m_TargetX = Dir.x;
|
||||
m_HammerInput.m_TargetY = Dir.y;
|
||||
|
||||
mem_copy(pData, &m_HammerInput, sizeof(m_HammerInput));
|
||||
return sizeof(m_HammerInput);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameClient::OnConnected()
|
||||
|
@ -576,13 +617,13 @@ void CGameClient::OnRender()
|
|||
if(Client()->State() == IClient::STATE_ONLINE && !m_pMenus->IsActive()) {
|
||||
if(m_CheckInfo[0] == 0) {
|
||||
if(
|
||||
str_comp(m_aClients[Client()->m_LocalIDs[0]].m_aName, g_Config.m_PlayerName) ||
|
||||
str_comp(m_aClients[Client()->m_LocalIDs[0]].m_aClan, g_Config.m_PlayerClan) ||
|
||||
m_aClients[Client()->m_LocalIDs[0]].m_Country != g_Config.m_PlayerCountry ||
|
||||
str_comp(m_aClients[Client()->m_LocalIDs[0]].m_aSkinName, g_Config.m_ClPlayerSkin) ||
|
||||
m_aClients[Client()->m_LocalIDs[0]].m_UseCustomColor != g_Config.m_ClPlayerUseCustomColor ||
|
||||
m_aClients[Client()->m_LocalIDs[0]].m_ColorBody != g_Config.m_ClPlayerColorBody ||
|
||||
m_aClients[Client()->m_LocalIDs[0]].m_ColorFeet != g_Config.m_ClPlayerColorFeet
|
||||
str_comp(m_aClients[m_LocalIDs[0]].m_aName, g_Config.m_PlayerName) ||
|
||||
str_comp(m_aClients[m_LocalIDs[0]].m_aClan, g_Config.m_PlayerClan) ||
|
||||
m_aClients[m_LocalIDs[0]].m_Country != g_Config.m_PlayerCountry ||
|
||||
str_comp(m_aClients[m_LocalIDs[0]].m_aSkinName, g_Config.m_ClPlayerSkin) ||
|
||||
m_aClients[m_LocalIDs[0]].m_UseCustomColor != g_Config.m_ClPlayerUseCustomColor ||
|
||||
m_aClients[m_LocalIDs[0]].m_ColorBody != g_Config.m_ClPlayerColorBody ||
|
||||
m_aClients[m_LocalIDs[0]].m_ColorFeet != g_Config.m_ClPlayerColorFeet
|
||||
)
|
||||
SendInfo(false);
|
||||
else
|
||||
|
@ -595,13 +636,13 @@ void CGameClient::OnRender()
|
|||
if(Client()->DummyConnected()) {
|
||||
if(m_CheckInfo[1] == 0) {
|
||||
if(
|
||||
str_comp(m_aClients[Client()->m_LocalIDs[1]].m_aName, g_Config.m_ClDummyName) ||
|
||||
str_comp(m_aClients[Client()->m_LocalIDs[1]].m_aClan, g_Config.m_ClDummyClan) ||
|
||||
m_aClients[Client()->m_LocalIDs[1]].m_Country != g_Config.m_ClDummyCountry ||
|
||||
str_comp(m_aClients[Client()->m_LocalIDs[1]].m_aSkinName, g_Config.m_ClDummySkin) ||
|
||||
m_aClients[Client()->m_LocalIDs[1]].m_UseCustomColor != g_Config.m_ClDummyUseCustomColor ||
|
||||
m_aClients[Client()->m_LocalIDs[1]].m_ColorBody != g_Config.m_ClDummyColorBody ||
|
||||
m_aClients[Client()->m_LocalIDs[1]].m_ColorFeet != g_Config.m_ClDummyColorFeet
|
||||
str_comp(m_aClients[m_LocalIDs[1]].m_aName, g_Config.m_ClDummyName) ||
|
||||
str_comp(m_aClients[m_LocalIDs[1]].m_aClan, g_Config.m_ClDummyClan) ||
|
||||
m_aClients[m_LocalIDs[1]].m_Country != g_Config.m_ClDummyCountry ||
|
||||
str_comp(m_aClients[m_LocalIDs[1]].m_aSkinName, g_Config.m_ClDummySkin) ||
|
||||
m_aClients[m_LocalIDs[1]].m_UseCustomColor != g_Config.m_ClDummyUseCustomColor ||
|
||||
m_aClients[m_LocalIDs[1]].m_ColorBody != g_Config.m_ClDummyColorBody ||
|
||||
m_aClients[m_LocalIDs[1]].m_ColorFeet != g_Config.m_ClDummyColorFeet
|
||||
)
|
||||
SendDummyInfo(false);
|
||||
else
|
||||
|
@ -713,14 +754,14 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy)
|
|||
if(IsDummy)
|
||||
{
|
||||
if(MsgId == NETMSGTYPE_SV_CHAT
|
||||
&& Client()->m_LocalIDs[0] >= 0
|
||||
&& Client()->m_LocalIDs[1] >= 0)
|
||||
&& m_LocalIDs[0] >= 0
|
||||
&& m_LocalIDs[1] >= 0)
|
||||
{
|
||||
CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg;
|
||||
|
||||
if((pMsg->m_Team == 1
|
||||
&& (m_aClients[Client()->m_LocalIDs[0]].m_Team != m_aClients[Client()->m_LocalIDs[1]].m_Team
|
||||
|| m_Teams.Team(Client()->m_LocalIDs[0]) != m_Teams.Team(Client()->m_LocalIDs[1])))
|
||||
&& (m_aClients[m_LocalIDs[0]].m_Team != m_aClients[m_LocalIDs[1]].m_Team
|
||||
|| m_Teams.Team(m_LocalIDs[0]) != m_Teams.Team(m_LocalIDs[1])))
|
||||
|| pMsg->m_Team > 1)
|
||||
{
|
||||
m_pChat->OnMessage(MsgId, pRawMsg);
|
||||
|
|
|
@ -307,7 +307,8 @@ public:
|
|||
virtual void OnNewSnapshot();
|
||||
virtual void OnPredict();
|
||||
virtual void OnActivateEditor();
|
||||
virtual int OnSnapInput(int *pData);
|
||||
virtual void OnDummySwap();
|
||||
virtual int OnSnapInput(int *pData, bool Dummy, bool Force);
|
||||
virtual void OnShutdown();
|
||||
virtual void OnEnterGame();
|
||||
virtual void OnRconLine(const char *pLine);
|
||||
|
@ -315,14 +316,10 @@ public:
|
|||
virtual void OnStartGame();
|
||||
virtual void OnFlagGrab(int TeamID);
|
||||
|
||||
virtual void ResetDummyInput();
|
||||
virtual const char *GetItemName(int Type);
|
||||
virtual const char *Version();
|
||||
virtual const char *NetVersion();
|
||||
|
||||
virtual const CNetObj_PlayerInput &getPlayerInput(int dummy);
|
||||
|
||||
|
||||
// actions
|
||||
// TODO: move these
|
||||
void SendSwitchTeam(int Team);
|
||||
|
@ -358,6 +355,11 @@ public:
|
|||
|
||||
// DDRace
|
||||
|
||||
int m_LocalIDs[2];
|
||||
CNetObj_PlayerInput m_DummyInput;
|
||||
CNetObj_PlayerInput m_HammerInput;
|
||||
int m_DummyFire;
|
||||
|
||||
class CRaceDemo *m_pRaceDemo;
|
||||
class CGhost *m_pGhost;
|
||||
class CTeamsCore m_Teams;
|
||||
|
|
|
@ -67,13 +67,13 @@ void BuildPackets()
|
|||
|
||||
void ReadNews()
|
||||
{
|
||||
IOHANDLE newsFile = io_open("news", IOFLAG_READ);
|
||||
if (!newsFile)
|
||||
IOHANDLE NewsFile = io_open("news", IOFLAG_READ);
|
||||
if (!NewsFile)
|
||||
return;
|
||||
|
||||
io_read(newsFile, m_aNews, NEWS_SIZE);
|
||||
io_read(NewsFile, m_aNews, NEWS_SIZE);
|
||||
|
||||
io_close(newsFile);
|
||||
io_close(NewsFile);
|
||||
}
|
||||
|
||||
void ReadServerList()
|
||||
|
|
Loading…
Reference in a new issue