mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Add antiping for weapons (by nuborn)
This commit is contained in:
parent
a0bfc5a083
commit
48e66a2ab3
|
@ -104,6 +104,7 @@ enum
|
||||||
VERSION_DDNET_GOODHOOK = 221,
|
VERSION_DDNET_GOODHOOK = 221,
|
||||||
VERSION_DDNET_EXTRATUNES = 302,
|
VERSION_DDNET_EXTRATUNES = 302,
|
||||||
VERSION_DDNET_RCONPROTECT = 408,
|
VERSION_DDNET_RCONPROTECT = 408,
|
||||||
|
VERSION_DDNET_ANTIPING_PROJECTILE = 600
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,8 +49,10 @@ void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID)
|
||||||
if(Ct < 0)
|
if(Ct < 0)
|
||||||
return; // projectile havn't been shot yet
|
return; // projectile havn't been shot yet
|
||||||
|
|
||||||
vec2 StartPos(pCurrent->m_X, pCurrent->m_Y);
|
vec2 StartPos, StartVel;
|
||||||
vec2 StartVel(pCurrent->m_VelX/100.0f, pCurrent->m_VelY/100.0f);
|
ExtractInfo(pCurrent, &StartPos, &StartVel);
|
||||||
|
//vec2 StartPos(pCurrent->m_X, pCurrent->m_Y);
|
||||||
|
//vec2 StartVel(pCurrent->m_VelX/100.00000f, pCurrent->m_VelY/100.00000f);
|
||||||
vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct);
|
vec2 Pos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct);
|
||||||
vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f);
|
vec2 PrevPos = CalcPos(StartPos, StartVel, Curvature, Speed, Ct-0.001f);
|
||||||
|
|
||||||
|
|
|
@ -267,7 +267,7 @@ void CGameClient::OnInit()
|
||||||
m_UI.SetGraphics(Graphics(), TextRender());
|
m_UI.SetGraphics(Graphics(), TextRender());
|
||||||
m_RenderTools.m_pGraphics = Graphics();
|
m_RenderTools.m_pGraphics = Graphics();
|
||||||
m_RenderTools.m_pUI = UI();
|
m_RenderTools.m_pUI = UI();
|
||||||
|
|
||||||
int64 Start = time_get();
|
int64 Start = time_get();
|
||||||
|
|
||||||
// set the language
|
// set the language
|
||||||
|
@ -440,6 +440,9 @@ void CGameClient::OnReset()
|
||||||
m_DDRaceMsgSent[1] = false;
|
m_DDRaceMsgSent[1] = false;
|
||||||
m_ShowOthers[0] = -1;
|
m_ShowOthers[0] = -1;
|
||||||
m_ShowOthers[1] = -1;
|
m_ShowOthers[1] = -1;
|
||||||
|
|
||||||
|
for(int i=0; i<64; i++)
|
||||||
|
m_aLocalProjectiles[i].Deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -474,7 +477,7 @@ void CGameClient::UpdatePositions()
|
||||||
vec2(m_Snap.m_pLocalPrevCharacter->m_X, m_Snap.m_pLocalPrevCharacter->m_Y),
|
vec2(m_Snap.m_pLocalPrevCharacter->m_X, m_Snap.m_pLocalPrevCharacter->m_Y),
|
||||||
vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y), Client()->IntraGameTick());
|
vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y), Client()->IntraGameTick());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_Config.m_ClAntiPing)
|
if (g_Config.m_ClAntiPing)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAX_CLIENTS; i++)
|
for (int i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
@ -646,7 +649,7 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy)
|
||||||
m_Tuning[IsDummy ? !g_Config.m_ClDummy : g_Config.m_ClDummy] = NewTuning;
|
m_Tuning[IsDummy ? !g_Config.m_ClDummy : g_Config.m_ClDummy] = NewTuning;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *pRawMsg = m_NetObjHandler.SecureUnpackMsg(MsgId, pUnpacker);
|
void *pRawMsg = m_NetObjHandler.SecureUnpackMsg(MsgId, pUnpacker);
|
||||||
if(!pRawMsg)
|
if(!pRawMsg)
|
||||||
{
|
{
|
||||||
|
@ -1161,6 +1164,9 @@ void CGameClient::OnNewSnapshot()
|
||||||
|
|
||||||
void CGameClient::OnPredict()
|
void CGameClient::OnPredict()
|
||||||
{
|
{
|
||||||
|
float PhysSize = 28.0f;
|
||||||
|
float ProximityRadius = PhysSize;
|
||||||
|
|
||||||
// store the previous values so we can detect prediction errors
|
// store the previous values so we can detect prediction errors
|
||||||
CCharacterCore BeforePrevChar = m_PredictedPrevChar;
|
CCharacterCore BeforePrevChar = m_PredictedPrevChar;
|
||||||
CCharacterCore BeforeChar = m_PredictedChar;
|
CCharacterCore BeforeChar = m_PredictedChar;
|
||||||
|
@ -1202,6 +1208,41 @@ void CGameClient::OnPredict()
|
||||||
g_GameClient.m_aClients[i].m_Predicted.m_ActiveWeapon = m_Snap.m_aCharacters[i].m_Cur.m_Weapon;
|
g_GameClient.m_aClients[i].m_Predicted.m_ActiveWeapon = m_Snap.m_aCharacters[i].m_Cur.m_Weapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CLocalProjectile TempProjectiles[64];
|
||||||
|
int NumProjectiles = 0;
|
||||||
|
|
||||||
|
if(g_Config.m_ClAntiPingWeapons)
|
||||||
|
{
|
||||||
|
for(int Index=0; Index<64; Index++)
|
||||||
|
TempProjectiles[Index].Deactivate();
|
||||||
|
int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT);
|
||||||
|
for(int Index = 0; Index < Num && NumProjectiles < 64; Index++)
|
||||||
|
{
|
||||||
|
IClient::CSnapItem Item;
|
||||||
|
const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item);
|
||||||
|
if(Item.m_Type == NETOBJTYPE_PROJECTILE)
|
||||||
|
{
|
||||||
|
const CNetObj_Projectile *pInfo = (const CNetObj_Projectile *)pData;
|
||||||
|
|
||||||
|
TempProjectiles[NumProjectiles].Init(this, &World, Collision(), (const CNetObj_Projectile *)pData);
|
||||||
|
|
||||||
|
int Index = TempProjectiles[NumProjectiles].m_StartTick % 64;
|
||||||
|
if(m_aLocalProjectiles[Index].m_Active)
|
||||||
|
if(m_aLocalProjectiles[Index].m_StartTick == TempProjectiles[NumProjectiles].m_StartTick)
|
||||||
|
if(distance(m_aLocalProjectiles[Index].m_Pos, TempProjectiles[NumProjectiles].m_Pos) < 3)
|
||||||
|
TempProjectiles[NumProjectiles] = m_aLocalProjectiles[Index];
|
||||||
|
NumProjectiles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ReloadTimer;
|
||||||
|
if(World.m_apCharacters[m_Snap.m_LocalClientID]->m_ActiveWeapon == WEAPON_HAMMER)
|
||||||
|
ReloadTimer = SERVER_TICK_SPEED / 3 - (Client()->GameTick() - m_Snap.m_aCharacters[m_Snap.m_LocalClientID].m_Cur.m_AttackTick);
|
||||||
|
else
|
||||||
|
ReloadTimer = g_pData->m_Weapons.m_aId[World.m_apCharacters[m_Snap.m_LocalClientID]->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000 - (Client()->GameTick() - m_Snap.m_aCharacters[m_Snap.m_LocalClientID].m_Cur.m_AttackTick);
|
||||||
|
ReloadTimer = max(ReloadTimer, 0);
|
||||||
|
|
||||||
// predict
|
// predict
|
||||||
for(int Tick = Client()->GameTick()+1; Tick <= Client()->PredGameTick(); Tick++)
|
for(int Tick = Client()->GameTick()+1; Tick <= Client()->PredGameTick(); Tick++)
|
||||||
{
|
{
|
||||||
|
@ -1209,27 +1250,157 @@ void CGameClient::OnPredict()
|
||||||
if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_Snap.m_LocalClientID])
|
if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_Snap.m_LocalClientID])
|
||||||
m_PredictedPrevChar = *World.m_apCharacters[m_Snap.m_LocalClientID];
|
m_PredictedPrevChar = *World.m_apCharacters[m_Snap.m_LocalClientID];
|
||||||
|
|
||||||
// first calculate where everyone should move
|
|
||||||
for(int c = 0; c < MAX_CLIENTS; c++)
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
{
|
{
|
||||||
if(!World.m_apCharacters[c])
|
if(!World.m_apCharacters[c])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(g_Config.m_ClAntiPing && Tick == Client()->PredGameTick())
|
if(g_Config.m_ClAntiPing && Tick == Client()->PredGameTick())
|
||||||
g_GameClient.m_aClients[c].m_PrevPredicted = *World.m_apCharacters[c];
|
g_GameClient.m_aClients[c].m_PrevPredicted = *World.m_apCharacters[c];
|
||||||
|
}
|
||||||
|
|
||||||
|
// input
|
||||||
|
CNetObj_PlayerInput Input;
|
||||||
|
CNetObj_PlayerInput PrevInput;
|
||||||
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
|
{
|
||||||
|
if(!World.m_apCharacters[c])
|
||||||
|
continue;
|
||||||
|
|
||||||
mem_zero(&World.m_apCharacters[c]->m_Input, sizeof(World.m_apCharacters[c]->m_Input));
|
mem_zero(&World.m_apCharacters[c]->m_Input, sizeof(World.m_apCharacters[c]->m_Input));
|
||||||
if(m_Snap.m_LocalClientID == c)
|
if(m_Snap.m_LocalClientID == c)
|
||||||
{
|
{
|
||||||
// apply player input
|
// apply player input
|
||||||
|
mem_zero(&Input, sizeof(Input));
|
||||||
|
mem_zero(&PrevInput, sizeof(PrevInput));
|
||||||
int *pInput = Client()->GetInput(Tick);
|
int *pInput = Client()->GetInput(Tick);
|
||||||
if(pInput)
|
if(pInput)
|
||||||
|
{
|
||||||
World.m_apCharacters[c]->m_Input = *((CNetObj_PlayerInput*)pInput);
|
World.m_apCharacters[c]->m_Input = *((CNetObj_PlayerInput*)pInput);
|
||||||
|
Input = *((CNetObj_PlayerInput*)pInput);
|
||||||
|
}
|
||||||
|
int *pPrevInput = Client()->GetInput(Tick-1);
|
||||||
|
if(pPrevInput)
|
||||||
|
PrevInput = *((CNetObj_PlayerInput*)pPrevInput);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle weapons
|
||||||
|
{
|
||||||
|
if(!g_Config.m_ClAntiPingWeapons)
|
||||||
|
break;
|
||||||
|
if(ReloadTimer)
|
||||||
|
break;
|
||||||
|
if(!World.m_apCharacters[m_Snap.m_LocalClientID])
|
||||||
|
break;
|
||||||
|
CCharacterCore *Local = World.m_apCharacters[m_Snap.m_LocalClientID];
|
||||||
|
|
||||||
|
//DoWeaponSwitch();
|
||||||
|
|
||||||
|
bool FullAuto = false;
|
||||||
|
if(Local->m_ActiveWeapon == WEAPON_GRENADE || Local->m_ActiveWeapon == WEAPON_SHOTGUN || Local->m_ActiveWeapon == WEAPON_RIFLE)
|
||||||
|
FullAuto = true;
|
||||||
|
|
||||||
|
bool WillFire = false;
|
||||||
|
|
||||||
|
if(CountInput(PrevInput.m_Fire, Input.m_Fire).m_Presses)
|
||||||
|
WillFire = true;
|
||||||
|
if(FullAuto && (Input.m_Fire&1))
|
||||||
|
WillFire = true;
|
||||||
|
if(!WillFire)
|
||||||
|
break;
|
||||||
|
//if(!m_pControls->m_AmmoCount[Local->m_ActiveWeapon%NUM_WEAPONS]) break;
|
||||||
|
vec2 Direction = normalize(vec2(Input.m_TargetX, Input.m_TargetY));
|
||||||
|
vec2 Pos = Local->m_Pos;
|
||||||
|
vec2 ProjStartPos = Pos + Direction * ProximityRadius * 0.75f;
|
||||||
|
|
||||||
|
ReloadTimer = g_pData->m_Weapons.m_aId[Local->m_ActiveWeapon].m_Firedelay * SERVER_TICK_SPEED / 1000;
|
||||||
|
switch(Local->m_ActiveWeapon)
|
||||||
|
{
|
||||||
|
case WEAPON_GRENADE:
|
||||||
|
{
|
||||||
|
TempProjectiles[NumProjectiles].Init(
|
||||||
|
this, &World, Collision(),
|
||||||
|
Direction, //StartDir
|
||||||
|
ProjStartPos, //StartPos
|
||||||
|
Tick-1, //StartTick
|
||||||
|
WEAPON_GRENADE, //Type
|
||||||
|
m_Snap.m_LocalClientID, //Owner
|
||||||
|
WEAPON_GRENADE, //Weapon
|
||||||
|
1000, //LifeSpan
|
||||||
|
1, 0, 0, 1); //Explosive, Bouncing, Freeze, ExtraInfo
|
||||||
|
m_aLocalProjectiles[(Tick-1)%64] = TempProjectiles[NumProjectiles];
|
||||||
|
NumProjectiles++;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WEAPON_HAMMER:
|
||||||
|
{
|
||||||
|
vec2 ProjPos = ProjStartPos;
|
||||||
|
float Radius = ProximityRadius*0.5f;
|
||||||
|
|
||||||
|
int Hits = 0;
|
||||||
|
bool OwnerCanProbablyHitOthers = (m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_Tuning[g_Config.m_ClDummy].m_PlayerHooking);
|
||||||
|
if(!OwnerCanProbablyHitOthers)
|
||||||
|
break;
|
||||||
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||||
|
{
|
||||||
|
if(!World.m_apCharacters[i])
|
||||||
|
continue;
|
||||||
|
if(i == m_Snap.m_LocalClientID)
|
||||||
|
continue;
|
||||||
|
if(!(distance(World.m_apCharacters[i]->m_Pos, ProjPos) < Radius+ProximityRadius))
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
CCharacterCore *pTarget = World.m_apCharacters[i];
|
||||||
|
|
||||||
|
if(m_aClients[i].m_Active && !m_Teams.CanCollide(i, m_Snap.m_LocalClientID))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vec2 Dir;
|
||||||
|
if (length(pTarget->m_Pos - Pos) > 0.0f)
|
||||||
|
Dir = normalize(pTarget->m_Pos - Pos);
|
||||||
|
else
|
||||||
|
Dir = vec2(0.f, -1.f);
|
||||||
|
|
||||||
|
float Strength;
|
||||||
|
Strength = World.m_Tuning[g_Config.m_ClDummy].m_HammerStrength;
|
||||||
|
|
||||||
|
vec2 Temp = pTarget->m_Vel + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f;
|
||||||
|
|
||||||
|
Temp -= pTarget->m_Vel;
|
||||||
|
pTarget->TakeDamage((vec2(0.f, -1.0f) + Temp) * Strength);
|
||||||
|
Hits++;
|
||||||
|
}
|
||||||
|
// if we Hit anything, we have to wait for the reload
|
||||||
|
//if(Hits)
|
||||||
|
//ReloadTimer = SERVER_TICK_SPEED/3;
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ReloadTimer)
|
||||||
|
ReloadTimer--;
|
||||||
|
|
||||||
|
// projectiles
|
||||||
|
if(g_Config.m_ClAntiPingWeapons)
|
||||||
|
for(int g = 0; g < 64; g++)
|
||||||
|
if(TempProjectiles[g].m_Active)
|
||||||
|
TempProjectiles[g].Tick(Tick, Client()->GameTickSpeed(), m_Snap.m_LocalClientID);
|
||||||
|
|
||||||
|
// first calculate where everyone should move
|
||||||
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
|
{
|
||||||
|
if(!World.m_apCharacters[c])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(m_Snap.m_LocalClientID == c)
|
||||||
|
{
|
||||||
World.m_apCharacters[c]->Tick(true, true);
|
World.m_apCharacters[c]->Tick(true, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
World.m_apCharacters[c]->Tick(false, true);
|
World.m_apCharacters[c]->Tick(false, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move all players and quantize their data
|
// move all players and quantize their data
|
||||||
|
@ -1268,6 +1439,7 @@ void CGameClient::OnPredict()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_Snap.m_LocalClientID])
|
if(Tick == Client()->PredGameTick() && World.m_apCharacters[m_Snap.m_LocalClientID])
|
||||||
{
|
{
|
||||||
m_PredictedChar = *World.m_apCharacters[m_Snap.m_LocalClientID];
|
m_PredictedChar = *World.m_apCharacters[m_Snap.m_LocalClientID];
|
||||||
|
@ -1285,6 +1457,7 @@ void CGameClient::OnPredict()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(g_Config.m_Debug && g_Config.m_ClPredict && m_PredictedTick == Client()->PredGameTick())
|
if(g_Config.m_Debug && g_Config.m_ClPredict && m_PredictedTick == Client()->PredGameTick())
|
||||||
{
|
{
|
||||||
CNetObj_CharacterCore Before = {0}, Now = {0}, BeforePrev = {0}, NowPrev = {0};
|
CNetObj_CharacterCore Before = {0}, Now = {0}, BeforePrev = {0}, NowPrev = {0};
|
||||||
|
@ -1479,6 +1652,7 @@ IGameClient *CreateGameClient()
|
||||||
return &g_GameClient;
|
return &g_GameClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CGameClient::IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2& NewPos2, int ownID)
|
int CGameClient::IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2& NewPos2, int ownID)
|
||||||
{
|
{
|
||||||
float PhysSize = 28.0f;
|
float PhysSize = 28.0f;
|
||||||
|
@ -1510,6 +1684,214 @@ int CGameClient::IntersectCharacter(vec2 HookPos, vec2 NewPos, vec2& NewPos2, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClosestID;
|
return ClosestID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CGameClient::IntersectCharacter(vec2 OldPos, vec2 NewPos, float Radius, vec2 *NewPos2, int ownID, CWorldCore *World)
|
||||||
|
{
|
||||||
|
|
||||||
|
float PhysSize = 28.0f;
|
||||||
|
float Distance = 0.0f;
|
||||||
|
int ClosestID = -1;
|
||||||
|
|
||||||
|
if(!World)
|
||||||
|
return ClosestID;
|
||||||
|
|
||||||
|
for (int i=0; i<MAX_CLIENTS; i++)
|
||||||
|
{
|
||||||
|
if(!World->m_apCharacters[i])
|
||||||
|
continue;
|
||||||
|
CClientData cData = m_aClients[i];
|
||||||
|
|
||||||
|
if(!cData.m_Active || i == ownID || !m_Teams.CanCollide(i, ownID))
|
||||||
|
continue;
|
||||||
|
vec2 Position = World->m_apCharacters[i]->m_Pos;
|
||||||
|
vec2 ClosestPoint = closest_point_on_line(OldPos, NewPos, Position);
|
||||||
|
if(distance(Position, ClosestPoint) < PhysSize+Radius)
|
||||||
|
{
|
||||||
|
if(ClosestID == -1 || distance(OldPos, Position) < Distance)
|
||||||
|
{
|
||||||
|
*NewPos2 = ClosestPoint;
|
||||||
|
ClosestID = i;
|
||||||
|
Distance = distance(OldPos, Position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ClosestID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLocalProjectile::Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, const CNetObj_Projectile *pProj)
|
||||||
|
{
|
||||||
|
m_Active = 1;
|
||||||
|
m_pGameClient = pGameClient;
|
||||||
|
m_pWorld = pWorld;
|
||||||
|
m_pCollision = pCollision;
|
||||||
|
m_StartTick = pProj->m_StartTick;
|
||||||
|
m_Type = pProj->m_Type;
|
||||||
|
m_Weapon = m_Type;
|
||||||
|
|
||||||
|
ExtractInfo(pProj, &m_Pos, &m_Direction);
|
||||||
|
|
||||||
|
if(HasExtraInfo(pProj))
|
||||||
|
{
|
||||||
|
ExtractExtraInfo(pProj, &m_Owner, &m_LifeSpan, &m_Explosive, &m_Bouncing, &m_Freeze);
|
||||||
|
m_ExtraInfo = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Owner = -1;
|
||||||
|
m_Explosive = (m_Type == WEAPON_GRENADE ? true : false);
|
||||||
|
m_Bouncing = 0;
|
||||||
|
m_Freeze = 0;
|
||||||
|
m_LifeSpan = -2;
|
||||||
|
m_ExtraInfo = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLocalProjectile::Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, vec2 Direction, vec2 Pos, int StartTick, int Type, int Owner, int Weapon, int LifeSpan, bool Explosive, int Bouncing, bool Freeze, bool ExtraInfo)
|
||||||
|
{
|
||||||
|
m_Active = 1;
|
||||||
|
m_pGameClient = pGameClient;
|
||||||
|
m_pWorld = pWorld;
|
||||||
|
m_pCollision = pCollision;
|
||||||
|
m_Direction = Direction;
|
||||||
|
m_Pos = Pos;
|
||||||
|
m_StartTick = StartTick;
|
||||||
|
m_Type = Type;
|
||||||
|
m_Weapon = Weapon;
|
||||||
|
m_LifeSpan = LifeSpan;
|
||||||
|
m_Owner = Owner;
|
||||||
|
m_Explosive = Explosive;
|
||||||
|
m_Bouncing = Bouncing;
|
||||||
|
m_Freeze = Freeze;
|
||||||
|
m_ExtraInfo = ExtraInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 CLocalProjectile::GetPos(float Time)
|
||||||
|
{
|
||||||
|
float Curvature = 0;
|
||||||
|
float Speed = 0;
|
||||||
|
|
||||||
|
switch(m_Type)
|
||||||
|
{
|
||||||
|
case WEAPON_GRENADE:
|
||||||
|
Curvature = m_pWorld->m_Tuning[g_Config.m_ClDummy].m_GrenadeCurvature;
|
||||||
|
Speed = m_pWorld->m_Tuning[g_Config.m_ClDummy].m_GrenadeSpeed;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WEAPON_SHOTGUN:
|
||||||
|
Curvature = m_pWorld->m_Tuning[g_Config.m_ClDummy].m_ShotgunCurvature;
|
||||||
|
Speed = m_pWorld->m_Tuning[g_Config.m_ClDummy].m_ShotgunSpeed;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WEAPON_GUN:
|
||||||
|
Curvature = m_pWorld->m_Tuning[g_Config.m_ClDummy].m_GunCurvature;
|
||||||
|
Speed = m_pWorld->m_Tuning[g_Config.m_ClDummy].m_GunSpeed;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CalcPos(m_Pos, m_Direction, Curvature, Speed, Time);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CLocalProjectile::GameLayerClipped(vec2 CheckPos)
|
||||||
|
{
|
||||||
|
return round_to_int(CheckPos.x)/32 < -200 || round_to_int(CheckPos.x)/32 > m_pCollision->GetWidth()+200 ||
|
||||||
|
round_to_int(CheckPos.y)/32 < -200 || round_to_int(CheckPos.y)/32 > m_pCollision->GetHeight()+200 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CLocalProjectile::Tick(int CurrentTick, int GameTickSpeed, int LocalClientID)
|
||||||
|
{
|
||||||
|
if(!m_pWorld)
|
||||||
|
return;
|
||||||
|
float Pt = (CurrentTick-m_StartTick-1)/(float)GameTickSpeed;
|
||||||
|
float Ct = (CurrentTick-m_StartTick)/(float)GameTickSpeed;
|
||||||
|
|
||||||
|
vec2 PrevPos = GetPos(Pt);
|
||||||
|
vec2 CurPos = GetPos(Ct);
|
||||||
|
vec2 ColPos;
|
||||||
|
vec2 NewPos;
|
||||||
|
int Collide = 0;
|
||||||
|
if(m_pCollision)
|
||||||
|
Collide = m_pCollision->IntersectLine(PrevPos, CurPos, &ColPos, &NewPos, false);
|
||||||
|
int Target = m_pGameClient->IntersectCharacter(PrevPos, ColPos, m_Freeze ? 1.0f : 6.0f, &ColPos, m_Owner, m_pWorld);
|
||||||
|
|
||||||
|
if(m_LifeSpan > -1)
|
||||||
|
m_LifeSpan--;
|
||||||
|
|
||||||
|
bool isWeaponCollide = false;
|
||||||
|
if
|
||||||
|
(
|
||||||
|
m_Owner >= 0 &&
|
||||||
|
Target >= 0 &&
|
||||||
|
m_pGameClient->m_aClients[m_Owner].m_Active &&
|
||||||
|
m_pGameClient->m_aClients[Target].m_Active &&
|
||||||
|
!m_pGameClient->m_Teams.CanCollide(m_Owner, Target)
|
||||||
|
)
|
||||||
|
isWeaponCollide = true;
|
||||||
|
|
||||||
|
bool OwnerCanProbablyHitOthers = (m_pWorld->m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_pWorld->m_Tuning[g_Config.m_ClDummy].m_PlayerHooking);
|
||||||
|
|
||||||
|
if(((Target >= 0 && (m_Owner >= 0 ? OwnerCanProbablyHitOthers : 1 || Target == m_Owner)) || Collide || GameLayerClipped(CurPos)) && !isWeaponCollide)
|
||||||
|
{
|
||||||
|
if(m_Explosive && (Target < 0 || (Target >= 0 && (!m_Freeze || (m_Weapon == WEAPON_SHOTGUN && Collide)))))
|
||||||
|
CreateExplosion(ColPos, m_Owner);
|
||||||
|
if(Collide && m_Bouncing != 0)
|
||||||
|
{
|
||||||
|
m_StartTick = CurrentTick;
|
||||||
|
m_Pos = NewPos+(-(m_Direction*4));
|
||||||
|
if (m_Bouncing == 1)
|
||||||
|
m_Direction.x = -m_Direction.x;
|
||||||
|
else if(m_Bouncing == 2)
|
||||||
|
m_Direction.y =- m_Direction.y;
|
||||||
|
if (fabs(m_Direction.x) < 1e-6)
|
||||||
|
m_Direction.x = 0;
|
||||||
|
if (fabs(m_Direction.y) < 1e-6)
|
||||||
|
m_Direction.y = 0;
|
||||||
|
m_Pos += m_Direction;
|
||||||
|
}
|
||||||
|
else if(!m_Bouncing)
|
||||||
|
Deactivate();
|
||||||
|
}
|
||||||
|
//if(m_LifeSpan == -1)
|
||||||
|
//{
|
||||||
|
//if(m_Explosive)
|
||||||
|
//{
|
||||||
|
//CreateExplosion(ColPos, LocalClientID);
|
||||||
|
//}
|
||||||
|
//Deactivate();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLocalProjectile::CreateExplosion(vec2 Pos, int LocalClientID)
|
||||||
|
{
|
||||||
|
if(!m_pWorld)
|
||||||
|
return;
|
||||||
|
float Radius = 135.0f;
|
||||||
|
float InnerRadius = 48.0f;
|
||||||
|
|
||||||
|
bool OwnerCanProbablyHitOthers = (m_pWorld->m_Tuning[g_Config.m_ClDummy].m_PlayerCollision || m_pWorld->m_Tuning[g_Config.m_ClDummy].m_PlayerHooking);
|
||||||
|
|
||||||
|
for(int c = 0; c < MAX_CLIENTS; c++)
|
||||||
|
{
|
||||||
|
if(!m_pWorld->m_apCharacters[c])
|
||||||
|
continue;
|
||||||
|
if(m_Owner >= 0 && c >= 0)
|
||||||
|
if(m_pGameClient->m_aClients[c].m_Active && !m_pGameClient->m_Teams.CanCollide(c, m_Owner))
|
||||||
|
continue;
|
||||||
|
if(c != LocalClientID && !OwnerCanProbablyHitOthers)
|
||||||
|
continue;
|
||||||
|
vec2 Diff = m_pWorld->m_apCharacters[c]->m_Pos - Pos;
|
||||||
|
vec2 ForceDir(0,1);
|
||||||
|
float l = length(Diff);
|
||||||
|
if(l)
|
||||||
|
ForceDir = normalize(Diff);
|
||||||
|
l = 1-clamp((l-InnerRadius)/(Radius-InnerRadius), 0.0f, 1.0f);
|
||||||
|
|
||||||
|
float Strength = m_pWorld->m_Tuning[g_Config.m_ClDummy].m_ExplosionStrength;
|
||||||
|
float Dmg = Strength * l;
|
||||||
|
|
||||||
|
if((int)Dmg)
|
||||||
|
m_pWorld->m_apCharacters[c]->TakeDamage(ForceDir*Dmg*2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,39 @@
|
||||||
: \
|
: \
|
||||||
((x) >= (z) ? (x) : (z)))
|
((x) >= (z) ? (x) : (z)))
|
||||||
|
|
||||||
|
class CGameClient;
|
||||||
|
|
||||||
|
class CLocalProjectile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int m_Active;
|
||||||
|
CGameClient *m_pGameClient;
|
||||||
|
CWorldCore *m_pWorld;
|
||||||
|
CCollision *m_pCollision;
|
||||||
|
|
||||||
|
vec2 m_Direction;
|
||||||
|
vec2 m_Pos;
|
||||||
|
int m_StartTick;
|
||||||
|
int m_Type;
|
||||||
|
|
||||||
|
int m_Owner;
|
||||||
|
int m_Weapon;
|
||||||
|
int m_LifeSpan;
|
||||||
|
bool m_Explosive;
|
||||||
|
int m_Bouncing;
|
||||||
|
bool m_Freeze;
|
||||||
|
bool m_ExtraInfo;
|
||||||
|
|
||||||
|
vec2 GetPos(float Time);
|
||||||
|
void CreateExplosion(vec2 Pos, int LocalClientID);
|
||||||
|
void Tick(int CurrentTick, int GameTickSpeed, int LocalClientID);
|
||||||
|
void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, const CNetObj_Projectile *pProj);
|
||||||
|
void Init(CGameClient *pGameClient, CWorldCore *pWorld, CCollision *pCollision, vec2 Direction, vec2 Pos, int StartTick, int Type, int Owner, int Weapon, int LifeSpan, bool Explosive, int Bouncing, bool Freeze, bool ExtraInfo);
|
||||||
|
|
||||||
|
bool GameLayerClipped(vec2 CheckPos);
|
||||||
|
void Deactivate() { m_Active = 0; }
|
||||||
|
};
|
||||||
|
|
||||||
class CGameClient : public IGameClient
|
class CGameClient : public IGameClient
|
||||||
{
|
{
|
||||||
class CStack
|
class CStack
|
||||||
|
@ -283,6 +316,9 @@ public:
|
||||||
class CTeamsCore m_Teams;
|
class CTeamsCore m_Teams;
|
||||||
|
|
||||||
int IntersectCharacter(vec2 Pos0, vec2 Pos1, vec2& NewPos, int ownID);
|
int IntersectCharacter(vec2 Pos0, vec2 Pos1, vec2& NewPos, int ownID);
|
||||||
|
int IntersectCharacter(vec2 OldPos, vec2 NewPos, float Radius, vec2* NewPos2, int ownID, CWorldCore *World);
|
||||||
|
|
||||||
|
class CLocalProjectile m_aLocalProjectiles[64];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -697,6 +697,61 @@ void CCharacterCore::Quantize()
|
||||||
|
|
||||||
// DDRace
|
// DDRace
|
||||||
|
|
||||||
|
bool HasExtraInfo(const CNetObj_Projectile *pProj)
|
||||||
|
{
|
||||||
|
return ((abs(pProj->m_VelY) & (1<<9)) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtractInfo(const CNetObj_Projectile *pProj, vec2 *StartPos, vec2 *StartVel)
|
||||||
|
{
|
||||||
|
if(!StartPos || !StartVel)
|
||||||
|
return;
|
||||||
|
if(!HasExtraInfo(pProj))
|
||||||
|
{
|
||||||
|
StartPos->x = pProj->m_X + 0.5f * sign(pProj->m_X);
|
||||||
|
StartPos->y = pProj->m_Y + 0.5f * sign(pProj->m_Y);
|
||||||
|
StartVel->x = pProj->m_VelX + 0.5f *sign(pProj->m_VelX);
|
||||||
|
StartVel->y = pProj->m_VelY + 0.5f *sign(pProj->m_VelY);
|
||||||
|
//StartVel->x = pProj->m_VelX/100.0f;
|
||||||
|
//StartVel->y = pProj->m_VelY/100.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StartPos->x = (pProj->m_X + 0.5f * sign(pProj->m_X))/1000.0f;
|
||||||
|
StartPos->y = (pProj->m_Y + 0.5f * sign(pProj->m_Y))/1000.0f;
|
||||||
|
float Angle = (pProj->m_VelX + 0.5f * sign(pProj->m_VelX))/1000000.0f;
|
||||||
|
StartVel->x = sin(-Angle);
|
||||||
|
StartVel->y = cos(-Angle);
|
||||||
|
}
|
||||||
|
*StartVel = normalize(*StartVel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExtractExtraInfo(const CNetObj_Projectile *pProj, int *Owner, int *LifeSpan, bool *Explosive, int *Bouncing = 0, bool *Freeze = 0)
|
||||||
|
{
|
||||||
|
if(!HasExtraInfo(pProj))
|
||||||
|
return;
|
||||||
|
int Data = pProj->m_VelY;
|
||||||
|
if(Owner)
|
||||||
|
{
|
||||||
|
*Owner = Data & 255;
|
||||||
|
if((Data>>8) & 1)
|
||||||
|
*Owner = -(*Owner);
|
||||||
|
}
|
||||||
|
// HasExtraInfo = ((Data>>9) & 1);
|
||||||
|
if(LifeSpan)
|
||||||
|
{
|
||||||
|
*LifeSpan = (Data>>10) & 255;
|
||||||
|
if((Data >> 18) & 1)
|
||||||
|
*LifeSpan = -(*LifeSpan);
|
||||||
|
}
|
||||||
|
if(Explosive)
|
||||||
|
*Explosive = (Data>>19) & 1;
|
||||||
|
if(Bouncing)
|
||||||
|
*Bouncing = (Data>>20) & 3;
|
||||||
|
if(Freeze)
|
||||||
|
*Freeze = (Data>>22) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool CCharacterCore::IsRightTeam(int MapIndex)
|
bool CCharacterCore::IsRightTeam(int MapIndex)
|
||||||
{
|
{
|
||||||
if(Collision()->m_pSwitchers)
|
if(Collision()->m_pSwitchers)
|
||||||
|
@ -704,3 +759,18 @@ bool CCharacterCore::IsRightTeam(int MapIndex)
|
||||||
return Collision()->m_pSwitchers[Collision()->GetDTileNumber(MapIndex)].m_Status[m_pTeams->Team(m_Id)];
|
return Collision()->m_pSwitchers[Collision()->GetDTileNumber(MapIndex)].m_Status[m_pTeams->Team(m_Id)];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CCharacterCore::TakeDamage(vec2 Force)
|
||||||
|
{
|
||||||
|
vec2 Temp = m_Vel + Force;
|
||||||
|
if(Temp.x > 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_270) || (m_TileIndexL == TILE_STOP && m_TileFlagsL == ROTATION_270) || (m_TileIndexL == TILE_STOPS && (m_TileFlagsL == ROTATION_90 || m_TileFlagsL ==ROTATION_270)) || (m_TileIndexL == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_270) || (m_TileFIndexL == TILE_STOP && m_TileFFlagsL == ROTATION_270) || (m_TileFIndexL == TILE_STOPS && (m_TileFFlagsL == ROTATION_90 || m_TileFFlagsL == ROTATION_270)) || (m_TileFIndexL == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_270) || (m_TileSIndexL == TILE_STOP && m_TileSFlagsL == ROTATION_270) || (m_TileSIndexL == TILE_STOPS && (m_TileSFlagsL == ROTATION_90 || m_TileSFlagsL == ROTATION_270)) || (m_TileSIndexL == TILE_STOPA)))
|
||||||
|
Temp.x = 0;
|
||||||
|
if(Temp.x < 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_90) || (m_TileIndexR == TILE_STOP && m_TileFlagsR == ROTATION_90) || (m_TileIndexR == TILE_STOPS && (m_TileFlagsR == ROTATION_90 || m_TileFlagsR == ROTATION_270)) || (m_TileIndexR == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_90) || (m_TileFIndexR == TILE_STOP && m_TileFFlagsR == ROTATION_90) || (m_TileFIndexR == TILE_STOPS && (m_TileFFlagsR == ROTATION_90 || m_TileFFlagsR == ROTATION_270)) || (m_TileFIndexR == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_90) || (m_TileSIndexR == TILE_STOP && m_TileSFlagsR == ROTATION_90) || (m_TileSIndexR == TILE_STOPS && (m_TileSFlagsR == ROTATION_90 || m_TileSFlagsR == ROTATION_270)) || (m_TileSIndexR == TILE_STOPA)))
|
||||||
|
Temp.x = 0;
|
||||||
|
if(Temp.y < 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_180) || (m_TileIndexB == TILE_STOP && m_TileFlagsB == ROTATION_180) || (m_TileIndexB == TILE_STOPS && (m_TileFlagsB == ROTATION_0 || m_TileFlagsB == ROTATION_180)) || (m_TileIndexB == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_180) || (m_TileFIndexB == TILE_STOP && m_TileFFlagsB == ROTATION_180) || (m_TileFIndexB == TILE_STOPS && (m_TileFFlagsB == ROTATION_0 || m_TileFFlagsB == ROTATION_180)) || (m_TileFIndexB == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_180) || (m_TileSIndexB == TILE_STOP && m_TileSFlagsB == ROTATION_180) || (m_TileSIndexB == TILE_STOPS && (m_TileSFlagsB == ROTATION_0 || m_TileSFlagsB == ROTATION_180)) || (m_TileSIndexB == TILE_STOPA)))
|
||||||
|
Temp.y = 0;
|
||||||
|
if(Temp.y > 0 && ((m_TileIndex == TILE_STOP && m_TileFlags == ROTATION_0) || (m_TileIndexT == TILE_STOP && m_TileFlagsT == ROTATION_0) || (m_TileIndexT == TILE_STOPS && (m_TileFlagsT == ROTATION_0 || m_TileFlagsT == ROTATION_180)) || (m_TileIndexT == TILE_STOPA) || (m_TileFIndex == TILE_STOP && m_TileFFlags == ROTATION_0) || (m_TileFIndexT == TILE_STOP && m_TileFFlagsT == ROTATION_0) || (m_TileFIndexT == TILE_STOPS && (m_TileFFlagsT == ROTATION_0 || m_TileFFlagsT == ROTATION_180)) || (m_TileFIndexT == TILE_STOPA) || (m_TileSIndex == TILE_STOP && m_TileSFlags == ROTATION_0) || (m_TileSIndexT == TILE_STOP && m_TileSFlagsT == ROTATION_0) || (m_TileSIndexT == TILE_STOPS && (m_TileSFlagsT == ROTATION_0 || m_TileSFlagsT == ROTATION_180)) || (m_TileSIndexT == TILE_STOPA)))
|
||||||
|
Temp.y = 0;
|
||||||
|
m_Vel = Temp;
|
||||||
|
}
|
||||||
|
|
|
@ -233,6 +233,8 @@ public:
|
||||||
int m_Colliding;
|
int m_Colliding;
|
||||||
bool m_LeftWall;
|
bool m_LeftWall;
|
||||||
|
|
||||||
|
void TakeDamage(vec2 Force);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
CTeamsCore* m_pTeams;
|
CTeamsCore* m_pTeams;
|
||||||
|
@ -269,4 +271,35 @@ private:
|
||||||
bool IsRightTeam(int MapIndex);
|
bool IsRightTeam(int MapIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool HasExtraInfo(const CNetObj_Projectile *pProj);
|
||||||
|
void ExtractInfo(const CNetObj_Projectile *pProj, vec2 *StartPos, vec2 *StartVel);
|
||||||
|
void ExtractExtraInfo(const CNetObj_Projectile *pProj, int *Owner, int *m_LifeSpan, bool *Explosive, int *Bouncing, bool *Freeze);
|
||||||
|
|
||||||
|
//input count
|
||||||
|
struct CInputCount
|
||||||
|
{
|
||||||
|
int m_Presses;
|
||||||
|
int m_Releases;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline CInputCount CountInput(int Prev, int Cur)
|
||||||
|
{
|
||||||
|
CInputCount c = {0, 0};
|
||||||
|
Prev &= INPUT_STATE_MASK;
|
||||||
|
Cur &= INPUT_STATE_MASK;
|
||||||
|
int i = Prev;
|
||||||
|
|
||||||
|
while(i != Cur)
|
||||||
|
{
|
||||||
|
i = (i+1)&INPUT_STATE_MASK;
|
||||||
|
if(i&1)
|
||||||
|
c.m_Presses++;
|
||||||
|
else
|
||||||
|
c.m_Releases++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,33 +16,6 @@
|
||||||
#include <game/server/score.h>
|
#include <game/server/score.h>
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
|
||||||
//input count
|
|
||||||
struct CInputCount
|
|
||||||
{
|
|
||||||
int m_Presses;
|
|
||||||
int m_Releases;
|
|
||||||
};
|
|
||||||
|
|
||||||
CInputCount CountInput(int Prev, int Cur)
|
|
||||||
{
|
|
||||||
CInputCount c = {0, 0};
|
|
||||||
Prev &= INPUT_STATE_MASK;
|
|
||||||
Cur &= INPUT_STATE_MASK;
|
|
||||||
int i = Prev;
|
|
||||||
|
|
||||||
while(i != Cur)
|
|
||||||
{
|
|
||||||
i = (i+1)&INPUT_STATE_MASK;
|
|
||||||
if(i&1)
|
|
||||||
c.m_Presses++;
|
|
||||||
else
|
|
||||||
c.m_Releases++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS)
|
MACRO_ALLOC_POOL_ID_IMPL(CCharacter, MAX_CLIENTS)
|
||||||
|
|
||||||
// Character, "physical" player's part
|
// Character, "physical" player's part
|
||||||
|
@ -372,7 +345,6 @@ void CCharacter::FireWeapon()
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f;
|
vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f;
|
||||||
|
|
||||||
switch(m_Core.m_ActiveWeapon)
|
switch(m_Core.m_ActiveWeapon)
|
||||||
|
@ -550,7 +522,10 @@ void CCharacter::FireWeapon()
|
||||||
|
|
||||||
// pack the Projectile and send it to the client Directly
|
// pack the Projectile and send it to the client Directly
|
||||||
CNetObj_Projectile p;
|
CNetObj_Projectile p;
|
||||||
pProj->FillInfo(&p);
|
if(m_pPlayer && m_pPlayer->m_ClientVersion >= VERSION_DDNET_ANTIPING_PROJECTILE)
|
||||||
|
pProj->FillExtraInfo(&p);
|
||||||
|
else
|
||||||
|
pProj->FillInfo(&p);
|
||||||
|
|
||||||
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
|
||||||
Msg.AddInt(1);
|
Msg.AddInt(1);
|
||||||
|
@ -613,7 +588,7 @@ void CCharacter::HandleWeapons()
|
||||||
}
|
}
|
||||||
|
|
||||||
// fire Weapon, if wanted
|
// fire Weapon, if wanted
|
||||||
FireWeapon();
|
//FireWeapon();
|
||||||
/*
|
/*
|
||||||
// ammo regen
|
// ammo regen
|
||||||
int AmmoRegenTime = g_pData->m_Weapons.m_aId[m_Core.m_ActiveWeapon].m_Ammoregentime;
|
int AmmoRegenTime = g_pData->m_Weapons.m_aId[m_Core.m_ActiveWeapon].m_Ammoregentime;
|
||||||
|
@ -843,6 +818,8 @@ void CCharacter::TickDefered()
|
||||||
m_Core.m_pReset = false;
|
m_Core.m_pReset = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FireWeapon();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCharacter::TickPaused()
|
void CCharacter::TickPaused()
|
||||||
|
|
|
@ -232,6 +232,33 @@ void CProjectile::FillInfo(CNetObj_Projectile *pProj)
|
||||||
pProj->m_Type = m_Type;
|
pProj->m_Type = m_Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CProjectile::FillExtraInfo(CNetObj_Projectile *pProj)
|
||||||
|
{
|
||||||
|
//Send additional/modified info, by modifiying the fields of the netobj
|
||||||
|
float Angle = -atan2f(m_Direction.x, m_Direction.y);
|
||||||
|
|
||||||
|
int Data = 0;
|
||||||
|
Data |= (abs(m_Owner) & 255);
|
||||||
|
if(m_Owner < 0)
|
||||||
|
Data |= 1 << 8;
|
||||||
|
Data |= 1<<9; //This bit tells the client to use the extra info
|
||||||
|
Data |= ((abs(m_LifeSpan) <= 255 ? abs(m_LifeSpan) : 255) & 255) << 10;
|
||||||
|
if(m_LifeSpan < 0)
|
||||||
|
Data |= 1 << 18;
|
||||||
|
if(m_Explosive)
|
||||||
|
Data |= (1 << 19);
|
||||||
|
Data |= (m_Bouncing & 3) << 20;
|
||||||
|
if(m_Freeze)
|
||||||
|
Data |= (1 << 22);
|
||||||
|
|
||||||
|
pProj->m_X = (int)(m_Pos.x * 1000.0f);
|
||||||
|
pProj->m_Y = (int)(m_Pos.y * 1000.0f);
|
||||||
|
pProj->m_VelX = (int)(Angle * 1000000.0f);
|
||||||
|
pProj->m_VelY = Data;
|
||||||
|
pProj->m_StartTick = m_StartTick;
|
||||||
|
pProj->m_Type = m_Type;
|
||||||
|
}
|
||||||
|
|
||||||
void CProjectile::Snap(int SnappingClient)
|
void CProjectile::Snap(int SnappingClient)
|
||||||
{
|
{
|
||||||
float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
|
float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
|
||||||
|
@ -258,7 +285,12 @@ void CProjectile::Snap(int SnappingClient)
|
||||||
|
|
||||||
CNetObj_Projectile *pProj = static_cast<CNetObj_Projectile *>(Server()->SnapNewItem(NETOBJTYPE_PROJECTILE, m_ID, sizeof(CNetObj_Projectile)));
|
CNetObj_Projectile *pProj = static_cast<CNetObj_Projectile *>(Server()->SnapNewItem(NETOBJTYPE_PROJECTILE, m_ID, sizeof(CNetObj_Projectile)));
|
||||||
if(pProj)
|
if(pProj)
|
||||||
FillInfo(pProj);
|
{
|
||||||
|
if (SnappingClient > -1 && GameServer()->m_apPlayers[SnappingClient] && GameServer()->m_apPlayers[SnappingClient]->m_ClientVersion >= VERSION_DDNET_ANTIPING_PROJECTILE)
|
||||||
|
FillExtraInfo(pProj);
|
||||||
|
else
|
||||||
|
FillInfo(pProj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DDRace
|
// DDRace
|
||||||
|
|
|
@ -25,6 +25,7 @@ public:
|
||||||
|
|
||||||
vec2 GetPos(float Time);
|
vec2 GetPos(float Time);
|
||||||
void FillInfo(CNetObj_Projectile *pProj);
|
void FillInfo(CNetObj_Projectile *pProj);
|
||||||
|
void FillExtraInfo(CNetObj_Projectile *pProj);
|
||||||
|
|
||||||
virtual void Reset();
|
virtual void Reset();
|
||||||
virtual void Tick();
|
virtual void Tick();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
MACRO_CONFIG_INT(ClPredict, cl_predict, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Predict client movements")
|
MACRO_CONFIG_INT(ClPredict, cl_predict, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Predict client movements")
|
||||||
MACRO_CONFIG_INT(ClAntiPing, cl_antiping, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Antiping (predict other players' movements)")
|
MACRO_CONFIG_INT(ClAntiPing, cl_antiping, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Antiping (predict other players' movements)")
|
||||||
MACRO_CONFIG_INT(ClAntiPingGrenade, cl_antiping_grenade, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Antiping (predict grenades)")
|
MACRO_CONFIG_INT(ClAntiPingGrenade, cl_antiping_grenade, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Antiping (predict grenades)")
|
||||||
|
MACRO_CONFIG_INT(ClAntiPingWeapons, cl_antiping_weapons, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Antiping (predict weapons)")
|
||||||
MACRO_CONFIG_INT(ClNameplates, cl_nameplates, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Show name plates")
|
MACRO_CONFIG_INT(ClNameplates, cl_nameplates, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Show name plates")
|
||||||
MACRO_CONFIG_INT(ClNameplatesAlways, cl_nameplates_always, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Always show name plates disregarding of distance")
|
MACRO_CONFIG_INT(ClNameplatesAlways, cl_nameplates_always, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Always show name plates disregarding of distance")
|
||||||
MACRO_CONFIG_INT(ClNameplatesTeamcolors, cl_nameplates_teamcolors, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Use team colors for name plates")
|
MACRO_CONFIG_INT(ClNameplatesTeamcolors, cl_nameplates_teamcolors, 1, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Use team colors for name plates")
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#ifndef GAME_VERSION_H
|
#ifndef GAME_VERSION_H
|
||||||
#define GAME_VERSION_H
|
#define GAME_VERSION_H
|
||||||
#include "generated/nethash.cpp"
|
#include "generated/nethash.cpp"
|
||||||
#define GAME_VERSION "0.6.2, 5.3"
|
#define GAME_VERSION "0.6.2, 6.0"
|
||||||
#define GAME_NETVERSION "0.6 626fce9a778df4d4"
|
#define GAME_NETVERSION "0.6 626fce9a778df4d4"
|
||||||
static const char GAME_RELEASE_VERSION[8] = "5.3";
|
static const char GAME_RELEASE_VERSION[8] = "6.0";
|
||||||
#define CLIENT_VERSIONNR 503
|
#define CLIENT_VERSIONNR 600
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue