This commit is contained in:
btd 2010-08-23 19:26:17 +04:00
commit cf63f18954
10 changed files with 368 additions and 321 deletions

File diff suppressed because it is too large Load diff

View file

@ -8,6 +8,7 @@
//===============================
/* DDRace */
//MACRO_CONFIG_STR(SvEntities, sv_entities, 64, "Latest", CFGFLAG_SERVER, "The type of entities used") still need to think of a way
MACRO_CONFIG_INT(SvEndlessSuperHook, sv_endless_super_hook, 0, 0, 1, CFGFLAG_SERVER, "Endless hook for super players on/off")
MACRO_CONFIG_INT(SvEmotionalTees, sv_emotional_tees, 1, 0, 1, CFGFLAG_SERVER, "Emotional Tees on/off")
MACRO_CONFIG_INT(SvOldShotgun, sv_old_shotgun, 0, 0, 1, CFGFLAG_SERVER, "Makes Shotgun laser pull towards the shooter, rather than the last bounce origin")
MACRO_CONFIG_INT(SvReconnectTime,sv_reconnect_time,5,0,9999,CFGFLAG_SERVER,"how much time between leaves and joins")
@ -16,7 +17,7 @@ MACRO_CONFIG_INT(SvVoteKickBanTime,sv_vote_kick_bantime, 300, 0, 9999, CFGFLAG_S
MACRO_CONFIG_INT(SvVoteMapTimeDelay,sv_vote_map_delay,0,0,9999,CFGFLAG_SERVER,"how much time between map votes")
//MACRO_CONFIG_INT(SvMaxConnections,sv_max_connections, 2, 1, 16, CFGFLAG_SERVER, "Maximum count of connection from one IP server can accept") not needed
MACRO_CONFIG_INT(SvMaxAfkTime,sv_max_afk_time, 0, 0, 9999, CFGFLAG_SERVER, "How many seconds a player is allowed to be afk, 0=disabled")
MACRO_CONFIG_INT(SvPauseable, sv_pauseable, 0, 0, 1, CFGFLAG_SERVER, "players can pause their char or not")
MACRO_CONFIG_INT(SvPauseable, sv_pauseable, 1, 0, 1, CFGFLAG_SERVER, "players can pause their char or not")
MACRO_CONFIG_INT(SvCheatTime, sv_cheattime, 0, 0, 1, CFGFLAG_SERVER, "players can cheat with time or not")
MACRO_CONFIG_INT(SvHit, sv_hit, 1, 0, 1, CFGFLAG_SERVER, "players can hammer/grenade/laser one another")
MACRO_CONFIG_INT(SvTunes, sv_tunes, 1, 0, 1, CFGFLAG_SERVER, "Turns Tuning On/Off")

View file

@ -218,6 +218,7 @@ public:
NETADDR m_Addr;
int m_Expires;
char m_Reason[100];
bool m_Soon;
};
private:
@ -277,7 +278,7 @@ public:
// banning
int BanAdd(NETADDR Addr, int Seconds, const char *Reason);
int BanAddNoDrop(NETADDR Addr, int Seconds, const char *Reason);
int BanAddNoDrop(NETADDR Addr, int Seconds);
int BanRemove(NETADDR Addr);
int BanNum(); // caution, slow
int BanGet(int Index, CBanInfo *pInfo); // caution, slow

View file

@ -8,7 +8,7 @@
Object->Prev = (struct CBan *)0; \
Object->Next = First; \
First = Object; }
#define MACRO_LIST_LINK_AFTER(Object, After, Prev, Next) \
{ Object->Prev = After; \
Object->Next = After->Next; \
@ -22,7 +22,7 @@
if(Object->Prev) Object->Prev->Next = Object->Next; \
else First = Object->Next; \
Object->Next = 0; Object->Prev = 0; }
#define MACRO_LIST_FIND(Start, Next, Expression) \
{ while(Start && !(Expression)) Start = Start->Next; }
@ -30,12 +30,12 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int
{
// zero out the whole structure
mem_zero(this, sizeof(*this));
// open socket
m_Socket = net_udp_create(BindAddr);
if(m_Socket == NETSOCKET_INVALID)
return false;
// clamp clients
m_MaxClients = MaxClients;
if(m_MaxClients > NET_MAX_CLIENTS)
@ -44,17 +44,17 @@ bool CNetServer::Open(NETADDR BindAddr, int MaxClients, int MaxClientsPerIP, int
m_MaxClients = 1;
m_MaxClientsPerIP = MaxClientsPerIP;
for(int i = 0; i < NET_MAX_CLIENTS; i++)
m_aSlots[i].m_Connection.Init(m_Socket);
// setup all pointers for bans
for(int i = 1; i < NET_SERVER_MAXBANS-1; i++)
{
m_BanPool[i].m_pNext = &m_BanPool[i+1];
m_BanPool[i].m_pPrev = &m_BanPool[i-1];
}
m_BanPool[0].m_pNext = &m_BanPool[1];
m_BanPool[NET_SERVER_MAXBANS-1].m_pPrev = &m_BanPool[NET_SERVER_MAXBANS-2];
m_BanPool_FirstFree = &m_BanPool[0];
@ -80,19 +80,17 @@ int CNetServer::Drop(int ClientID, const char *pReason)
{
// TODO: insert lots of checks here
NETADDR Addr = ClientAddr(ClientID);
char Bufz[100];
str_format( Bufz, sizeof(Bufz),"trying to connect so soon");
dbg_msg("net_server", "client dropped. cid=%d ip=%d.%d.%d.%d reason=\"%s\"",
ClientID,
Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3],
pReason
);
if(m_pfnDelClient)
m_pfnDelClient(ClientID, m_UserPtr);
m_aSlots[ClientID].m_Connection.Disconnect(pReason);
BanAddNoDrop(Addr, g_Config.m_SvReconnectTime, Bufz);
BanAddNoDrop(Addr, g_Config.m_SvReconnectTime);
return 0;
}
@ -101,7 +99,7 @@ int CNetServer::BanGet(int Index, CBanInfo *pInfo)
CBan *pBan;
for(pBan = m_BanPool_FirstUsed; pBan && Index; pBan = pBan->m_pNext, Index--)
{}
if(!pBan)
return 0;
*pInfo = pBan->m_Info;
@ -131,65 +129,66 @@ int CNetServer::BanRemove(NETADDR Addr)
{
int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3])&0xff;
CBan *pBan = m_aBans[IpHash];
MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0);
if(pBan)
{
BanRemoveByObject(pBan);
return 0;
}
return -1;
}
int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char * Reason)
int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char* Reason)
{
int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3])&0xff;
int Stamp = -1;
CBan *pBan;
// remove the port
Addr.port = 0;
if(Seconds)
Stamp = time_timestamp() + Seconds;
// search to see if it already exists
pBan = m_aBans[IpHash];
MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0);
if(pBan)
{
// adjust the ban
if (pBan->m_Info.m_Expires > Seconds || pBan->m_Info.m_Expires == 0xffffffff)
if(pBan->m_Info.m_Expires==-1 || pBan->m_Info.m_Expires>Stamp)
return 0;
// adjust the ban
pBan->m_Info.m_Expires = Stamp;
pBan->m_Info.m_Soon = false;
strcpy(pBan->m_Info.m_Reason, Reason);
return 0;
}
if(!m_BanPool_FirstFree)
return -1;
// fetch and clear the new ban
pBan = m_BanPool_FirstFree;
MACRO_LIST_UNLINK(pBan, m_BanPool_FirstFree, m_pPrev, m_pNext);
// setup the ban info
pBan->m_Info.m_Expires = Stamp;
pBan->m_Info.m_Addr = Addr;
pBan->m_Info.m_Soon = false;
strcpy(pBan->m_Info.m_Reason, Reason);
// add it to the ban hash
MACRO_LIST_LINK_FIRST(pBan, m_aBans[IpHash], m_pHashPrev, m_pHashNext);
// insert it into the used list
{
if(m_BanPool_FirstUsed)
{
CBan *pInsertAfter = m_BanPool_FirstUsed;
MACRO_LIST_FIND(pInsertAfter, m_pNext, Stamp < pInsertAfter->m_Info.m_Expires);
if(pInsertAfter)
pInsertAfter = pInsertAfter->m_pPrev;
else
@ -199,7 +198,7 @@ int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char * Reason)
while(pInsertAfter->m_pNext)
pInsertAfter = pInsertAfter->m_pNext;
}
if(pInsertAfter)
{
MACRO_LIST_LINK_AFTER(pBan, pInsertAfter, m_pPrev, m_pNext);
@ -214,25 +213,20 @@ int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char * Reason)
MACRO_LIST_LINK_FIRST(pBan, m_BanPool_FirstUsed, m_pPrev, m_pNext);
}
}
// drop banned clients
{
char Buf[128];
NETADDR BanAddr;
if(Seconds) {
str_format(Buf, sizeof(Buf), "you have been banned for %d minutes", Seconds/60);
strcat(Buf, Reason);
} else {
str_format(Buf, sizeof(Buf), "you have been banned for life");
strcat(Buf, Reason);
}
if(Seconds)
str_format(Buf, sizeof(Buf), "You have been banned for %d second(s) for %s", Seconds,Reason);
else
str_format(Buf, sizeof(Buf), "You have been banned for life for %s",Reason);
for(int i = 0; i < MaxClients(); i++)
{
BanAddr = m_aSlots[i].m_Connection.PeerAddress();
BanAddr.port = 0;
if(net_addr_comp(&Addr, &BanAddr) == 0)
Drop(i, Buf);
}
@ -240,55 +234,51 @@ int CNetServer::BanAdd(NETADDR Addr, int Seconds, const char * Reason)
return 0;
}
int CNetServer::BanAddNoDrop(NETADDR Addr, int Seconds, const char *Reason)
int CNetServer::BanAddNoDrop(NETADDR Addr, int Seconds)
{
int IpHash = (Addr.ip[0]+Addr.ip[1]+Addr.ip[2]+Addr.ip[3])&0xff;
int Stamp = -1;
CBan *pBan;
// remove the port
Addr.port = 0;
if(Seconds)
Stamp = time_timestamp() + Seconds;
// search to see if it already exists
pBan = m_aBans[IpHash];
MACRO_LIST_FIND(pBan, m_pHashNext, net_addr_comp(&pBan->m_Info.m_Addr, &Addr) == 0);
if(pBan)
{
// adjust the ban
if (pBan->m_Info.m_Expires > Seconds || pBan->m_Info.m_Expires == 0xffffffff)
if(pBan->m_Info.m_Expires==-1 || pBan->m_Info.m_Expires>Stamp)
return 0;
// adjust the ban
pBan->m_Info.m_Expires = Stamp;
strcpy(pBan->m_Info.m_Reason, Reason);
pBan->m_Info.m_Soon = true;
return 0;
}
if(!m_BanPool_FirstFree)
return -1;
// fetch and clear the new ban
pBan = m_BanPool_FirstFree;
MACRO_LIST_UNLINK(pBan, m_BanPool_FirstFree, m_pPrev, m_pNext);
// setup the ban info
pBan->m_Info.m_Expires = Stamp;
pBan->m_Info.m_Addr = Addr;
strcpy(pBan->m_Info.m_Reason, Reason);
pBan->m_Info.m_Soon = true;
// add it to the ban hash
MACRO_LIST_LINK_FIRST(pBan, m_aBans[IpHash], m_pHashPrev, m_pHashNext);
// insert it into the used list
{
if(m_BanPool_FirstUsed)
{
CBan *pInsertAfter = m_BanPool_FirstUsed;
MACRO_LIST_FIND(pInsertAfter, m_pNext, Stamp < pInsertAfter->m_Info.m_Expires);
if(pInsertAfter)
pInsertAfter = pInsertAfter->m_pPrev;
else
@ -298,7 +288,7 @@ int CNetServer::BanAddNoDrop(NETADDR Addr, int Seconds, const char *Reason)
while(pInsertAfter->m_pNext)
pInsertAfter = pInsertAfter->m_pNext;
}
if(pInsertAfter)
{
MACRO_LIST_LINK_AFTER(pBan, pInsertAfter, m_pPrev, m_pNext);
@ -316,7 +306,6 @@ int CNetServer::BanAddNoDrop(NETADDR Addr, int Seconds, const char *Reason)
return 0;
}
int CNetServer::Update()
{
int Now = time_timestamp();
@ -326,14 +315,14 @@ int CNetServer::Update()
if(m_aSlots[i].m_Connection.State() == NET_CONNSTATE_ERROR)
Drop(i, m_aSlots[i].m_Connection.ErrorString());
}
// remove expired bans
while(m_BanPool_FirstUsed && m_BanPool_FirstUsed->m_Info.m_Expires < Now)
while(m_BanPool_FirstUsed && m_BanPool_FirstUsed->m_Info.m_Expires < Now && m_BanPool_FirstUsed->m_Info.m_Expires != -1)
{
CBan *pBan = m_BanPool_FirstUsed;
BanRemoveByObject(pBan);
}
return 0;
}
@ -343,22 +332,22 @@ int CNetServer::Update()
int CNetServer::Recv(CNetChunk *pChunk)
{
unsigned Now = time_timestamp();
while(1)
{
NETADDR Addr;
// check for a chunk
if(m_RecvUnpacker.FetchChunk(pChunk))
return 1;
// TODO: empty the recvinfo
int Bytes = net_udp_recv(m_Socket, &Addr, m_RecvUnpacker.m_aBuffer, NET_MAX_PACKETSIZE);
// no more packets for now
if(Bytes <= 0)
break;
if(CNetBase::UnpackPacket(m_RecvUnpacker.m_aBuffer, Bytes, &m_RecvUnpacker.m_Data) == 0)
{
CBan *pBan = 0;
@ -366,33 +355,34 @@ int CNetServer::Recv(CNetChunk *pChunk)
int IpHash = (BanAddr.ip[0]+BanAddr.ip[1]+BanAddr.ip[2]+BanAddr.ip[3])&0xff;
int Found = 0;
BanAddr.port = 0;
// search a ban
for(pBan = m_aBans[IpHash]; pBan; pBan = pBan->m_pHashNext)
{
if(net_addr_comp(&pBan->m_Info.m_Addr, &BanAddr) == 0)
break;
}
// check if we just should drop the packet
if(pBan)
{
// banned, reply with a message
char BanStr[128];
if(pBan->m_Info.m_Expires && (pBan->m_Info.m_Expires!=0xffffffff))
if(pBan->m_Info.m_Expires && (pBan->m_Info.m_Expires!=-1))
{
int Mins = ((pBan->m_Info.m_Expires - Now))/60;
if(Mins > 1)
str_format(BanStr, sizeof(BanStr), "Banned for %d minute(s) for %s", Mins, pBan->m_Info.m_Reason);
else
str_format(BanStr, sizeof(BanStr), "Banned for %d minute(s) for %s", (pBan->m_Info.m_Expires - Now), pBan->m_Info.m_Reason);
str_format(BanStr, sizeof(BanStr), "Banned for %d second(s) for %s", (pBan->m_Info.m_Expires - Now), pBan->m_Info.m_Reason);
}
else
str_format(BanStr, sizeof(BanStr), "Banned for life for %s", pBan->m_Info.m_Reason);
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, BanStr, str_length(BanStr)+1);
if(!pBan->m_Info.m_Soon)
CNetBase::SendControlMsg(m_Socket, &Addr, 0, NET_CTRLMSG_CLOSE, BanStr, str_length(BanStr)+1);
continue;
}
if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONNLESS)
{
pChunk->m_Flags = NETSENDFLAG_CONNLESS;
@ -403,12 +393,12 @@ int CNetServer::Recv(CNetChunk *pChunk)
return 1;
}
else
{
{
// TODO: check size here
if(m_RecvUnpacker.m_Data.m_Flags&NET_PACKETFLAG_CONTROL && m_RecvUnpacker.m_Data.m_aChunkData[0] == NET_CTRLMSG_CONNECT)
{
Found = 0;
// check if we already got this client
for(int i = 0; i < MaxClients(); i++)
{
@ -420,7 +410,7 @@ int CNetServer::Recv(CNetChunk *pChunk)
break;
}
}
// client that wants to connect
if(!Found)
{
@ -458,7 +448,7 @@ int CNetServer::Recv(CNetChunk *pChunk)
break;
}
}
if(!Found)
{
const char FullMsg[] = "server is full";
@ -495,7 +485,7 @@ int CNetServer::Send(CNetChunk *pChunk)
dbg_msg("netserver", "packet payload too big. %d. dropping packet", pChunk->m_DataSize);
return -1;
}
if(pChunk->m_Flags&NETSENDFLAG_CONNLESS)
{
// send connectionless packet
@ -506,10 +496,10 @@ int CNetServer::Send(CNetChunk *pChunk)
int Flags = 0;
dbg_assert(pChunk->m_ClientID >= 0, "errornous client id");
dbg_assert(pChunk->m_ClientID < MaxClients(), "errornous client id");
if(pChunk->m_Flags&NETSENDFLAG_VITAL)
Flags = NET_CHUNKFLAG_VITAL;
if(m_aSlots[pChunk->m_ClientID].m_Connection.QueueChunk(Flags, pChunk->m_DataSize, pChunk->m_pData) == 0)
{
if(pChunk->m_Flags&NETSENDFLAG_FLUSH)

View file

@ -292,7 +292,7 @@ void CCharacter::FireWeapon()
m_NumObjectsHit = 0;
GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE);
if (!g_Config.m_SvHit || m_RaceState == RACE_PAUSE) break;
if (!g_Config.m_SvHit) break;
CCharacter *aEnts[64];
int Hits = 0;
@ -357,10 +357,8 @@ void CCharacter::FireWeapon()
case WEAPON_SHOTGUN:
{
if(m_RaceState != RACE_PAUSE) {
new CLaser(&GameServer()->m_World, m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID(), 1);
GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);
}
/*int ShotSpread = 2;
CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
@ -395,8 +393,6 @@ void CCharacter::FireWeapon()
case WEAPON_GRENADE:
{
if (m_RaceState != RACE_PAUSE) {
CProjectile *Proj = new CProjectile(GameWorld(), WEAPON_GRENADE,
m_pPlayer->GetCID(),
ProjStartPos,
@ -418,20 +414,16 @@ void CCharacter::FireWeapon()
Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
}
} break;
case WEAPON_RIFLE:
{
if (m_RaceState != RACE_PAUSE) {
new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID(), 0);
//GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
}
} break;
case WEAPON_NINJA:
{
if (m_RaceState != RACE_PAUSE) {
// reset Hit objects
m_NumObjectsHit = 0;
@ -440,7 +432,6 @@ void CCharacter::FireWeapon()
//m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
m_Ninja.m_CurrentMoveTime = 10;
//GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE);
}
} break;
}
@ -510,13 +501,13 @@ bool CCharacter::GiveWeapon(int Weapon, int Ammo)
void CCharacter::GiveNinja()
{
if(!m_aWeapons[WEAPON_NINJA].m_Got)
GameServer()->CreateSound(m_Pos, SOUND_PICKUP_NINJA);
m_Ninja.m_ActivationTick = Server()->Tick();
m_aWeapons[WEAPON_NINJA].m_Got = true;
m_aWeapons[WEAPON_NINJA].m_Ammo = -1;
m_LastWeapon = m_ActiveWeapon;
m_ActiveWeapon = WEAPON_NINJA;
GameServer()->CreateSound(m_Pos, SOUND_PICKUP_NINJA);
}
void CCharacter::SetEmote(int Emote, int Tick)
@ -559,14 +550,6 @@ void CCharacter::Tick()
int MapIndex = GameServer()->Collision()->GetMapIndex(m_PrevPos, m_Pos);
int TileIndex1 = GameServer()->Collision()->GetCollisionDDRace(MapIndex);
int TileIndex2 = GameServer()->Collision()->GetFCollisionDDRace(MapIndex);
if(m_RaceState == RACE_PAUSE) {
m_Input.m_Direction = 0;
m_Input.m_Jump = 0;
m_Input.m_Hook = 0;
m_Input.m_Fire = 0;
m_Core.m_Jumped = 0;
ResetPos();
}
if(m_pPlayer->m_ForceBalanced)
{
@ -602,6 +585,8 @@ void CCharacter::Tick()
m_Core.m_HookTick = 0;
if (m_Super && m_Core.m_Jumped > 1)
m_Core.m_Jumped = 1;
if (m_Super && g_Config.m_SvEndlessSuperHook)
m_Core.m_HookTick = 0;
/*dbg_msg("character","TileIndex1=%d , TileIndex2=%d",TileIndex1,TileIndex2); //REMOVE*/
//DDRace
char aBuftime[128];
@ -719,8 +704,8 @@ void CCharacter::Tick()
{
if((int)GameServer()->Collision()->GetPos(TileIndex1).y < (int)m_Core.m_Pos.y)
m_Core.m_Pos.y = m_PrevPos.y;
if(m_Jumped&3 && m_Core.m_Jumped != m_Jumped) // check double jump
m_Core.m_Jumped = m_Jumped;
m_Core.m_Jumped = 0;
//m_Jumped = 1;
m_Core.m_Vel.y = 0;
}
}
@ -730,8 +715,7 @@ void CCharacter::Tick()
{
if((int)GameServer()->Collision()->GetPos(TileIndex2).y < (int)m_Core.m_Pos.y)
m_Core.m_Pos.y = m_PrevPos.y;
if(m_Jumped&3 && m_Core.m_Jumped != m_Jumped) // check double jump
m_Core.m_Jumped = m_Jumped;
m_Core.m_Jumped = 0;
m_Core.m_Vel.y = 0;
}
}
@ -1012,7 +996,13 @@ bool CCharacter::UnFreeze()
m_Ninja.m_ActivationDir=vec2(0,0);
m_Ninja.m_ActivationTick=0;
m_Ninja.m_CurrentMoveTime=0;
for(int i=0;i<WEAPON_NINJA;i++)
{
if (m_aWeapons[i].m_Got)
{
m_aWeapons[i].m_Ammo = -1;
}
}
return true;
}
return false;
@ -1147,7 +1137,7 @@ bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_SHORT);
*/
// set attacker's face to happy (taunt!)
if(g_Config.m_SvEmotionalTees)
/*if(g_Config.m_SvEmotionalTees)
{
if (From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From])
{
@ -1157,14 +1147,12 @@ bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
pChr->m_EmoteType = EMOTE_HAPPY;
pChr->m_EmoteStop = Server()->Tick() + Server()->TickSpeed();
}
}
}*///Removed you can set your emote via /emoteEMOTENAME
//set the attacked face to pain
m_EmoteType = EMOTE_PAIN;
m_EmoteStop = Server()->Tick() + 500 * Server()->TickSpeed() / 1000;
return true;
}
else return true;
}
void CCharacter::Snap(int SnappingClient)

View file

@ -18,8 +18,7 @@ enum
{
RACE_NONE = 0,
RACE_STARTED,
RACE_CHEAT, // no time and won't start again unless oredered by a mod or death
RACE_PAUSE//No time nor movement
RACE_CHEAT // no time and won't start again unless ordered by a mod or death
};
class CCharacter : public CEntity

View file

@ -76,6 +76,14 @@ void CPickup::Tick()
pChr->m_aWeapons[i].m_Ammo = 0;
sound = true;
}
if(pChr->m_FreezeTime)
{
pChr->m_aWeapons[WEAPON_GUN].m_Ammo = 0;
pChr->m_aWeapons[WEAPON_HAMMER].m_Ammo =0;
}
pChr->m_Ninja.m_ActivationDir=vec2(0,0);
pChr->m_Ninja.m_ActivationTick=0;
pChr->m_Ninja.m_CurrentMoveTime=0;
}
if (sound)
{
@ -87,7 +95,7 @@ void CPickup::Tick()
case POWERUP_WEAPON:
if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS)
if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS && (!pChr->m_aWeapons[m_Subtype].m_Got || pChr->m_aWeapons[m_Subtype].m_Ammo != -1))
{
if(pChr->GiveWeapon(m_Subtype, -1))
{

View file

@ -651,8 +651,8 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
if(g_Config.m_SvPauseable)
{
CCharacter* chr = p->GetCharacter();
if(!p->GetTeam())
if(!p->GetTeam() && (!chr->m_aWeapons[WEAPON_NINJA].m_Got || chr->m_FreezeTime) && chr->IsGrounded() && chr->m_Pos==chr->m_PrevPos)
{
p->SaveCharacter();
p->SetTeam(-1);
@ -663,13 +663,18 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
p->SetTeam(0);
//p->LoadCharacter();//TODO:Check if this system Works
}
else
SendChatTarget(ClientId, (chr->m_aWeapons[WEAPON_NINJA].m_Got)?"You can't use /pause while you are a ninja":(!chr->IsGrounded())?"You can't use /pause while you are a in air":"You can't use /pause while you are moving");
//if(chr->m_RaceState==RACE_STARTED)
// chr->m_RaceState = RACE_PAUSE;
//else if(chr->m_RaceState==RACE_PAUSE)
// chr->m_RaceState = RACE_STARTED;*/
}
} else if(!str_comp_nocase(pMsg->m_pMessage, "/info"))
else
SendChatTarget(ClientId, "The admin didn't activate /pause");
}
else if(!str_comp_nocase(pMsg->m_pMessage, "/info"))
{
SendChatTarget(ClientId, "DDRace Mod. Version: " DDRACE_VERSION);
SendChatTarget(ClientId, "Official site: DDRace.info");
@ -1113,6 +1118,7 @@ void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)
pChr->m_EmoteType = EMOTE_HAPPY;
break;
case EMOTICON_1:
case EMOTICON_4:
case EMOTICON_9:
case EMOTICON_15:
pChr->m_EmoteType = EMOTE_PAIN;

View file

@ -228,24 +228,61 @@ void CPlayer::TryRespawn()
void CPlayer::LoadCharacter() {
Character->m_Core = m_PauseInfo.m_Core;
Character->m_StartTime = m_PauseInfo.m_StartTime;
Character->m_StartTime = Server()->Tick() - (m_PauseInfo.m_PauseTime - m_PauseInfo.m_StartTime);
Character->m_RaceState = m_PauseInfo.m_RaceState;
Character->m_RefreshTime = Server()->Tick();
for(int i = 0; i < NUM_WEAPONS; ++i) {
if(m_PauseInfo.m_aHasWeapon[i]) {
if(m_PauseInfo.m_aHasWeapon[i])
if(!m_PauseInfo.m_FreezeTime)
Character->GiveWeapon(i, -1);
}
else
Character->GiveWeapon(i, 0);
}
Character->m_FreezeTime = m_PauseInfo.m_FreezeTime;
Character->m_Doored = m_PauseInfo.m_Doored;
Character->m_OldPos = m_PauseInfo.m_OldPos;
Character->m_OlderPos = m_PauseInfo.m_OlderPos;
Character->m_LastAction = m_PauseInfo.m_LastAction;
Character->m_Jumped = m_PauseInfo.m_Jumped;
Character->m_Health = m_PauseInfo.m_Health;
Character->m_Armor = m_PauseInfo.m_Armor;
Character->m_PlayerState = m_PauseInfo.m_PlayerState;
Character->m_LastMove = m_PauseInfo.m_LastMove;
Character->m_LastSpeedup = m_PauseInfo.m_LastSpeedup;
Character->m_PrevPos = m_PauseInfo.m_PrevPos;
Character->m_ActiveWeapon = m_PauseInfo.m_ActiveWeapon;
Character->m_LastWeapon = m_PauseInfo.m_LastWeapon;
Character->m_HammerType = m_PauseInfo.m_HammerType;
Character->m_Super = m_PauseInfo.m_Super;
m_PauseInfo.m_Respawn = false;
}
void CPlayer::SaveCharacter() {
void CPlayer::SaveCharacter()
{
m_PauseInfo.m_Core = Character->m_Core;
m_PauseInfo.m_StartTime = Character->m_StartTime;
m_PauseInfo.m_RaceState = Character->m_RaceState;
for(int i = 0; i < NUM_WEAPONS; ++i) {
for(int i = 0; i < WEAPON_NINJA; ++i)
{
m_PauseInfo.m_aHasWeapon[i] = Character->m_aWeapons[i].m_Got;
}
m_PauseInfo.m_FreezeTime=Character->m_FreezeTime;
m_PauseInfo.m_Doored = Character->m_Doored;
m_PauseInfo.m_OldPos = Character->m_OldPos;
m_PauseInfo.m_OlderPos = Character->m_OlderPos;
m_PauseInfo.m_LastAction = Character->m_LastAction;
m_PauseInfo.m_Jumped = Character->m_Jumped;
m_PauseInfo.m_Health = Character->m_Health;
m_PauseInfo.m_Armor = Character->m_Armor;
m_PauseInfo.m_PlayerState = Character->m_PlayerState;
m_PauseInfo.m_LastMove = Character->m_LastMove;
m_PauseInfo.m_LastSpeedup = Character->m_LastSpeedup;
m_PauseInfo.m_PrevPos = Character->m_PrevPos;
m_PauseInfo.m_ActiveWeapon = Character->m_ActiveWeapon;
m_PauseInfo.m_LastWeapon = Character->m_LastWeapon;
m_PauseInfo.m_HammerType = Character->m_HammerType;
m_PauseInfo.m_Super = Character->m_Super;
m_PauseInfo.m_PauseTime = Server()->Tick();
//m_PauseInfo.m_RefreshTime = Character->m_RefreshTime;
}
@ -300,4 +337,4 @@ void CPlayer::AfkTimer(int new_target_x, int new_target_y)
serv->Kick(m_ClientID,"Away from keyboard");
}
}
}
}

View file

@ -38,8 +38,25 @@ public:
int m_StartTime;
int m_RaceState;
//int m_RefreshTime;
int m_FreezeTime;
bool m_Doored;
vec2 m_OldPos;
vec2 m_OlderPos;
int m_LastAction;
int m_Jumped;
int m_Health;
int m_Armor;
int m_PlayerState;
int m_LastMove;
int m_LastSpeedup;
vec2 m_PrevPos;
int m_ActiveWeapon;
int m_LastWeapon;
bool m_Respawn;
bool m_aHasWeapon[NUM_WEAPONS];
int m_HammerType;
bool m_Super;
int m_PauseTime;
} m_PauseInfo;
void LoadCharacter();
void SaveCharacter();