Beispiel #1
0
void CServer::ProcessClientPacket(CNetChunk *pPacket)
{
	int ClientID = pPacket->m_ClientID;
	NETADDR Addr;
	CUnpacker Unpacker;
	Unpacker.Reset(pPacket->m_pData, pPacket->m_DataSize);

	// unpack msgid and system flag
	int Msg = Unpacker.GetInt();
	int Sys = Msg&1;
	Msg >>= 1;

	if(Unpacker.Error())
		return;

	if(Sys)
	{
		// system message
		if(Msg == NETMSG_INFO)
		{
			if(m_aClients[ClientID].m_State == CClient::STATE_AUTH)
			{
				char aVersion[64];
				str_copy(aVersion, Unpacker.GetString(CUnpacker::SANITIZE_CC), 64);
				bool CustClt = str_comp(aVersion, GameServer()->NetVersionCust()) == 0;
				dbg_msg("es", "%s client connected!", CustClt?"cust":"vanilla");
				if(!CustClt && str_comp(aVersion, GameServer()->NetVersion()) != 0)
				{
					// wrong version
					char aReason[256];
					str_format(aReason, sizeof(aReason), "Wrong version. Server is running '%s' and client '%s'", GameServer()->NetVersion(), aVersion);
					m_NetServer.Drop(ClientID, aReason);
					return;
				}

				const char *pPassword = Unpacker.GetString(CUnpacker::SANITIZE_CC);
				if(g_Config.m_Password[0] != 0 && str_comp(g_Config.m_Password, pPassword) != 0)
				{
					// wrong password
					m_NetServer.Drop(ClientID, "Wrong password");
					return;
				}

				m_aClients[ClientID].m_State = CClient::STATE_CONNECTING;
				m_aClients[ClientID].m_CustClt = CustClt;
				SendMap(ClientID);
			}
		}
		else if(Msg == NETMSG_REQUEST_MAP_DATA)
		{
			int Chunk = Unpacker.GetInt();
			int ChunkSize = 1024-128;
			int Offset = Chunk * ChunkSize;
			int Last = 0;

			// drop faulty map data requests
			if(Chunk < 0 || Offset > m_CurrentMapSize)
				return;

			if(Offset+ChunkSize >= m_CurrentMapSize)
			{
				ChunkSize = m_CurrentMapSize-Offset;
				if(ChunkSize < 0)
					ChunkSize = 0;
				Last = 1;
			}

			CMsgPacker Msg(NETMSG_MAP_DATA);
			Msg.AddInt(Last);
			Msg.AddInt(m_CurrentMapCrc);
			Msg.AddInt(Chunk);
			Msg.AddInt(ChunkSize);
			Msg.AddRaw(&m_pCurrentMapData[Offset], ChunkSize);
			SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true);

			if(g_Config.m_Debug)
			{
				char aBuf[256];
				str_format(aBuf, sizeof(aBuf), "sending chunk %d with size %d", Chunk, ChunkSize);
				Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
			}
		}
		else if(Msg == NETMSG_READY)
		{
			if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTING)
			{
				Addr = m_NetServer.ClientAddr(ClientID);
				char aAddrStr[NETADDR_MAXSTRSIZE];
				net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));

				char aBuf[256];
				str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%x addr=%s", ClientID, aAddrStr);
				Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
				m_aClients[ClientID].m_State = CClient::STATE_READY;
				GameServer()->OnClientConnected(ClientID);
				SendConnectionReady(ClientID);
			}
		}
		else if(Msg == NETMSG_ENTERGAME)
		{
			if(m_aClients[ClientID].m_State == CClient::STATE_READY && GameServer()->IsClientReady(ClientID))
			{
				Addr = m_NetServer.ClientAddr(ClientID);
				char aAddrStr[NETADDR_MAXSTRSIZE];
				net_addr_str(&Addr, aAddrStr, sizeof(aAddrStr));

				char aBuf[256];
				str_format(aBuf, sizeof(aBuf), "player has entered the game. ClientID=%x addr=%s", ClientID, aAddrStr);
				Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
				m_aClients[ClientID].m_State = CClient::STATE_INGAME;
				GameServer()->OnClientEnter(ClientID);
			}
		}
		else if(Msg == NETMSG_INPUT)
		{
			CClient::CInput *pInput;
			int64 TagTime;

			m_aClients[ClientID].m_LastAckedSnapshot = Unpacker.GetInt();
			int IntendedTick = Unpacker.GetInt();
			int Size = Unpacker.GetInt();

			// check for errors
			if(Unpacker.Error() || Size/4 > MAX_INPUT_SIZE)
				return;

			if(m_aClients[ClientID].m_LastAckedSnapshot > 0)
				m_aClients[ClientID].m_SnapRate = CClient::SNAPRATE_FULL;

			if(m_aClients[ClientID].m_Snapshots.Get(m_aClients[ClientID].m_LastAckedSnapshot, &TagTime, 0, 0) >= 0)
				m_aClients[ClientID].m_Latency = (int)(((time_get()-TagTime)*1000)/time_freq());

			// add message to report the input timing
			// skip packets that are old
			if(IntendedTick > m_aClients[ClientID].m_LastInputTick)
			{
				int TimeLeft = ((TickStartTime(IntendedTick)-time_get())*1000) / time_freq();

				CMsgPacker Msg(NETMSG_INPUTTIMING);
				Msg.AddInt(IntendedTick);
				Msg.AddInt(TimeLeft);
				SendMsgEx(&Msg, 0, ClientID, true);
			}

			m_aClients[ClientID].m_LastInputTick = IntendedTick;

			pInput = &m_aClients[ClientID].m_aInputs[m_aClients[ClientID].m_CurrentInput];

			if(IntendedTick <= Tick())
				IntendedTick = Tick()+1;

			pInput->m_GameTick = IntendedTick;

			for(int i = 0; i < Size/4; i++)
				pInput->m_aData[i] = Unpacker.GetInt();

			mem_copy(m_aClients[ClientID].m_LatestInput.m_aData, pInput->m_aData, MAX_INPUT_SIZE*sizeof(int));

			m_aClients[ClientID].m_CurrentInput++;
			m_aClients[ClientID].m_CurrentInput %= 200;

			// call the mod with the fresh input data
			if(m_aClients[ClientID].m_State == CClient::STATE_INGAME)
				GameServer()->OnClientDirectInput(ClientID, m_aClients[ClientID].m_LatestInput.m_aData);
		}
		else if(Msg == NETMSG_RCON_CMD)
		{
			const char *pCmd = Unpacker.GetString();

			if(Unpacker.Error() == 0 && m_aClients[ClientID].m_Authed)
			{
				char aBuf[256];
				str_format(aBuf, sizeof(aBuf), "ClientID=%d rcon='%s'", ClientID, pCmd);
				Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
				m_RconClientID = ClientID;
				Console()->ExecuteLine(pCmd);
				m_RconClientID = -1;
			}
		}
		else if(Msg == NETMSG_RCON_AUTH)
		{
			const char *pPw;
			Unpacker.GetString(); // login name, not used
			pPw = Unpacker.GetString(CUnpacker::SANITIZE_CC);

			if(Unpacker.Error() == 0)
			{
				if(g_Config.m_SvRconPassword[0] == 0)
				{
					SendRconLine(ClientID, "No rcon password set on server. Set sv_rcon_password to enable the remote console.");
				}
				else if(str_comp(pPw, g_Config.m_SvRconPassword) == 0)
				{
					CMsgPacker Msg(NETMSG_RCON_AUTH_STATUS);
					Msg.AddInt(1);
					SendMsgEx(&Msg, MSGFLAG_VITAL, ClientID, true);

					m_aClients[ClientID].m_Authed = 1;
					SendRconLine(ClientID, "Authentication successful. Remote console access granted.");
					char aBuf[256];
					str_format(aBuf, sizeof(aBuf), "ClientID=%d authed", ClientID);
					Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
				}
				else if(g_Config.m_SvRconMaxTries)
				{
					m_aClients[ClientID].m_AuthTries++;
					char aBuf[128];
					str_format(aBuf, sizeof(aBuf), "Wrong password %d/%d.", m_aClients[ClientID].m_AuthTries, g_Config.m_SvRconMaxTries);
					SendRconLine(ClientID, aBuf);
					if(m_aClients[ClientID].m_AuthTries >= g_Config.m_SvRconMaxTries)
					{
						if(!g_Config.m_SvRconBantime)
							m_NetServer.Drop(ClientID, "Too many remote console authentication tries");
						else
						{
							NETADDR Addr = m_NetServer.ClientAddr(ClientID);
							BanAdd(Addr, g_Config.m_SvRconBantime*60, "Too many remote console authentication tries");
						}
					}
				}
				else
				{
					SendRconLine(ClientID, "Wrong password.");
				}
			}
		}
		else if(Msg == NETMSG_PING)
		{
			CMsgPacker Msg(NETMSG_PING_REPLY);
			SendMsgEx(&Msg, 0, ClientID, true);
		}
		else
		{
			if(g_Config.m_Debug)
			{
				char aHex[] = "0123456789ABCDEF";
				char aBuf[512];

				for(int b = 0; b < pPacket->m_DataSize && b < 32; b++)
				{
					aBuf[b*3] = aHex[((const unsigned char *)pPacket->m_pData)[b]>>4];
					aBuf[b*3+1] = aHex[((const unsigned char *)pPacket->m_pData)[b]&0xf];
					aBuf[b*3+2] = ' ';
					aBuf[b*3+3] = 0;
				}

				char aBufMsg[256];
				str_format(aBufMsg, sizeof(aBufMsg), "strange message ClientID=%d msg=%d data_size=%d", ClientID, Msg, pPacket->m_DataSize);
				Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBufMsg);
				Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
			}
		}
	}
Beispiel #2
0
void CProjectile::Tick()
{
	float Pt = (Server()->Tick()-m_StartTick-1)/(float)Server()->TickSpeed();
	float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed();
	vec2 PrevPos = GetPos(Pt);
	vec2 CurPos = GetPos(Ct);
	int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &CurPos, 0);
	CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
	CCharacter *TargetChr = GameServer()->m_World.IntersectCharacter(PrevPos, CurPos, 6.0f, CurPos, OwnerChar);

	m_LifeSpan--;

	if(TargetChr || Collide || m_LifeSpan < 0 || GameLayerClipped(CurPos))
	{
        int EventID = GameServer()->m_pLua->m_pEventListener->CreateEventStack();
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(m_Owner);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(m_Weapon);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(CurPos.x);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(CurPos.y);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(m_StartTick);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(m_Direction.x);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(m_Direction.y);
        if (TargetChr)
            GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(TargetChr->GetPlayer()->GetCID());
        else
            GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(-1);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(Collide);
        GameServer()->m_pLua->m_pEventListener->GetParameters(EventID)->FindFree()->Set(m_ID);

        GameServer()->m_pLua->m_pEventListener->OnEvent("OnProjectileDestroy");

        if (GameServer()->m_pLua->m_pEventListener->GetReturns(EventID)->m_aVars[0].IsNumeric() && GameServer()->m_pLua->m_pEventListener->GetReturns(EventID)->m_aVars[0].GetInteger() == 1)
            return;

		if(m_LifeSpan >= 0 || m_Weapon == WEAPON_GRENADE)
			GameServer()->CreateSound(CurPos, m_SoundImpact);

		if(m_Explosive && GameServer()->m_pLua->m_pEventListener->GetReturns(EventID)->m_aVars[1].GetInteger() == 0)
			GameServer()->CreateExplosion(CurPos, m_Owner, m_Weapon, false);

		else if(TargetChr)
			TargetChr->TakeDamage(m_Direction * max(0.001f, m_Force), m_Damage, m_Owner, m_Weapon);

		GameServer()->m_World.DestroyEntity(this);
	}
}
Beispiel #3
0
void CGameControllerOpenFNG::HandleSacr(int Killer, int Victim, int ShrineTeam)
{//assertion: Killer >= 0, victim anyways
	CCharacter *pVictim = CHAR(Victim);

	if (!pVictim) //due to HandleFreeze, i suspect this COULD also possibly happen. 
	{
		D("no pVictim in HandleSacr(%d, %d, %d)", Killer, Victim, ShrineTeam);
		return;
	}

	int FailTeam = pVictim->GetPlayer()->GetTeam();
	bool Wrong = ShrineTeam != -1 && FailTeam == ShrineTeam;

	m_aTeamscore[1-FailTeam] += Wrong?CFG(WrongSacrTeamscore):(ShrineTeam == -1 ? CFG(SacrTeamscore) : CFG(RightSacrTeamscore));

	if (!Wrong)
	{
		if (CFG(SacrSound) == 1)
			GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE);
		else if (CFG(SacrSound) == 2)
			GameServer()->CreateSound(pVictim->m_Pos, SOUND_CTF_CAPTURE);
	}

	if (((Wrong && CFG(WrongSacrTeamscore)) || (!Wrong && (ShrineTeam == -1 ? CFG(SacrTeamscore) : CFG(RightSacrTeamscore)))) && CFG(SacrBroadcast))
	{
		char aBuf[64];
		str_format(aBuf, sizeof aBuf, "%s sacrificed%s (%+d)", GetTeamName(1-FailTeam), Wrong?" in wrong shrine":(ShrineTeam == -1 ? "" : ", pleasing their gods"),
		                                                                           Wrong?CFG(WrongSacrTeamscore):(ShrineTeam == -1 ? CFG(SacrTeamscore):CFG(RightSacrTeamscore)));
		m_Broadcast.Update(-1, aBuf, CFG(BroadcastTime) * TS);
	}

	CPlayer *pPlKiller = TPLAYER(Killer);
	CPlayer *pPlVictim = TPLAYER(Victim);

	if (!pPlKiller || !pVictim)
		return;

	pPlKiller->m_Score += Wrong ? CFG(WrongSacrScore)
	                            : (ShrineTeam == -1 ? CFG(SacrScore)
	                                                : CFG(RightSacrScore));

	pPlVictim->m_Score += Wrong ? CFG(WrongSacrScoreVic)
	                            : (ShrineTeam == -1 ? CFG(SacrScoreVic)
	                                                : CFG(RightSacrScoreVic));

	SendFreezeKill(Killer, Victim, WEAPON_NINJA);

	if (Wrong && pPlKiller->GetCharacter() && CFG(PunishWrongSacr))
	{
		pPlKiller->GetCharacter()->Freeze(CFG(PunishWrongSacr) * TS);
		GS->CreateSound(pPlKiller->GetCharacter()->m_Pos, SOUND_PLAYER_PAIN_LONG);
		GS->SendChatTarget(pPlKiller->GetCID(), "The gods are not pleased with this sacrifice!");
	}

	if (!Wrong && pPlKiller->GetCharacter())
		pPlKiller->GetCharacter()->SetEmote(EMOTE_HAPPY, TICK + TS * 2);

	if (pPlKiller->GetCharacter() && CFG(SacrLoltext) && ((!Wrong && CFG(SacrScore)) || (Wrong && CFG(WrongSacrScore))))
	{
		char aBuf[64];
		str_format(aBuf, sizeof aBuf, "%+d", Wrong?CFG(WrongSacrScore):(ShrineTeam == -1 ? CFG(SacrScore) : CFG(RightSacrScore)));
		GS->CreateLolText(pPlKiller->GetCharacter(), false, vec2(0.f, -50.f), vec2(0.f, 0.f), 50, aBuf);
	}

	if(!Wrong && pPlKiller->GetCharacter())
		GameServer()->GetPlayerChar(Killer)->AddSpree();
}
Beispiel #4
0
int CGameControllerMOD::ChooseInfectedClass(CPlayer* pPlayer)
{
	float random = frandom();
	float TotalProbInfectedClass = m_TotalProbInfectedClass;
	
	//Get information about existing infected
	int nbInfected = 0;
	bool thereIsAWitch = false;
	bool thereIsAnUndead = false;
	for(int i = 0; i < MAX_CLIENTS; i++)
	{
		CPlayer *pPlayer = GameServer()->m_apPlayers[i];
		
		if(!pPlayer) continue;
		if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
		
		if(pPlayer->IsInfected()) nbInfected++;
		if(pPlayer->GetClass() == PLAYERCLASS_WITCH) thereIsAWitch = true;
		if(pPlayer->GetClass() == PLAYERCLASS_UNDEAD) thereIsAnUndead = true;
	}
	
	//Check if hunters are enabled
	bool hunterEnabled = true;
	if(Server()->GetClassAvailability(PLAYERCLASS_HUNTER) == 0)
	{
		TotalProbInfectedClass -= m_ClassProbability[PLAYERCLASS_HUNTER];
		hunterEnabled = false;
	}
	
	//Check if ghost are enabled
	bool ghostEnabled = true;
	if(Server()->GetClassAvailability(PLAYERCLASS_GHOST) == 0)
	{
		TotalProbInfectedClass -= m_ClassProbability[PLAYERCLASS_GHOST];
		ghostEnabled = false;
	}
	
	//Check if spider are enabled
	bool spiderEnabled = true;
	if(Server()->GetClassAvailability(PLAYERCLASS_SPIDER) == 0)
	{
		TotalProbInfectedClass -= m_ClassProbability[PLAYERCLASS_SPIDER];
		spiderEnabled = false;
	}
	
	//Check if boomers are enabled
	bool boomerEnabled = true;
	if(Server()->GetClassAvailability(PLAYERCLASS_BOOMER) == 0)
	{
		TotalProbInfectedClass -= m_ClassProbability[PLAYERCLASS_BOOMER];
		boomerEnabled = false;
	}
	
	//Check if undeads are enabled
	bool undeadEnabled = true;
	if(nbInfected < 2 || thereIsAnUndead || (Server()->GetClassAvailability(PLAYERCLASS_UNDEAD) == 0) || !pPlayer->m_WasHumanThisRound)
	{
		TotalProbInfectedClass -= m_ClassProbability[PLAYERCLASS_UNDEAD];
		undeadEnabled = false;
	}
	
	//Check if witches are enabled
	bool witchEnabled = true;
	if(nbInfected < 2 || thereIsAWitch || (Server()->GetClassAvailability(PLAYERCLASS_WITCH) == 0) || !pPlayer->m_WasHumanThisRound)
	{
		TotalProbInfectedClass -= m_ClassProbability[PLAYERCLASS_WITCH];
		witchEnabled = false;
	}
	
	random *= TotalProbInfectedClass;
	
	//Find the random class
	if(undeadEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_UNDEAD];
		if(random < 0.0f)
		{
			GameServer()->SendBroadcast_Language(-1, "The undead is coming!");
			GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE);
			return PLAYERCLASS_UNDEAD;
		}
	}
	
	if(witchEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_WITCH];
		if(random < 0.0f)
		{
			GameServer()->SendBroadcast_Language(-1, "The witch is coming!");
			GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE);
			return PLAYERCLASS_WITCH;
		}
	}
	
	if(boomerEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_BOOMER];
		if(random < 0.0f)
		{
			return PLAYERCLASS_BOOMER;
		}
	}
	
	if(ghostEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_GHOST];
		if(random < 0.0f)
		{
			return PLAYERCLASS_GHOST;
		}
	}
	
	if(spiderEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_SPIDER];
		if(random < 0.0f)
		{
			return PLAYERCLASS_SPIDER;
		}
	}
	
	if(hunterEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_HUNTER];
		if(random < 0.0f)
		{
			return PLAYERCLASS_HUNTER;
		}
	}
	
	return PLAYERCLASS_SMOKER;
}
void CMercenaryBomb::Reset()
{
	GameServer()->m_World.DestroyEntity(this);
}
Beispiel #6
0
void CGameControllerMOD::Tick()
{
	IGameController::Tick();
	
	m_HumanCounter = 0;
	m_InfectedCounter = 0;
	
	//Count type of players
	for(int i = 0; i < MAX_CLIENTS; i ++)
	{
		CPlayer *pPlayer = GameServer()->m_apPlayers[i];
		
		if(!pPlayer) continue;
		if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
		
		if(pPlayer->IsInfected()) m_InfectedCounter++;
		else m_HumanCounter++;
	}
	
	m_InfectedStarted = false;
	
	//If the game can start ...
	if(m_GameOverTick == -1 && m_HumanCounter + m_InfectedCounter >= 2)
	{
		//If the infection started
		if(m_RoundStartTick + Server()->TickSpeed()*10 < Server()->Tick())
		{	
			m_InfectedStarted = true;
	
			for(int i = 0; i < MAX_CLIENTS; i ++)
			{
				CPlayer *pPlayer = GameServer()->m_apPlayers[i];
				
				if(!pPlayer) continue;
				if(pPlayer->GetTeam() == TEAM_SPECTATORS)
				{
					pPlayer->StartInfection();
				}
				else if(pPlayer->GetClass() == PLAYERCLASS_NONE)
				{
					pPlayer->SetClass(ChooseHumanClass(pPlayer));
					if(pPlayer->GetCharacter())
						pPlayer->GetCharacter()->IncreaseArmor(10);
				}
			}
			
			//If needed, infect players
			int nbInfectedNeeded = 2;
			if(m_InfectedCounter + m_HumanCounter < 4)
			{
				nbInfectedNeeded = 1;
			}
			
			while(m_InfectedCounter < nbInfectedNeeded)
			{
				float InfectionProb = 1.0/static_cast<float>(m_HumanCounter);
				float random = frandom();
				
				//Fair infection
				bool FairInfectionFound = false;
				for(int i = 0; i < MAX_CLIENTS; i ++)
				{
					CPlayer *pPlayer = GameServer()->m_apPlayers[i];
					
					if(!pPlayer) continue;
					if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
					if(pPlayer->IsInfected()) continue;
					
					if(!Server()->IsClientInfectedBefore(i))
					{
						Server()->InfecteClient(i);
						GameServer()->m_apPlayers[i]->StartInfection();
						m_InfectedCounter++;
						m_HumanCounter--;
						
						GameServer()->SendChatTarget_Language_s(-1, "%s has been infected", Server()->ClientName(i));
						FairInfectionFound = true;
						break;
					}
				}
				
				//Unfair infection
				if(!FairInfectionFound)
				{
					for(int i = 0; i < MAX_CLIENTS; i ++)
					{
						CPlayer *pPlayer = GameServer()->m_apPlayers[i];
						
						if(!pPlayer) continue;
						if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
						if(pPlayer->IsInfected()) continue;
						
						if(random < InfectionProb)
						{
							Server()->InfecteClient(i);
							GameServer()->m_apPlayers[i]->StartInfection();
							m_InfectedCounter++;
							m_HumanCounter--;
							
							GameServer()->SendChatTarget_Language_s(-1, "%s has been infected", Server()->ClientName(i));
							
							break;
						}
						else
						{
							random -= InfectionProb;
						}
					}
				}
			}
		}
		else
		{
			for(int i = 0; i < MAX_CLIENTS; i ++)
			{
				CPlayer *pPlayer = GameServer()->m_apPlayers[i];
				
				if(!pPlayer) continue;
				if(pPlayer->GetTeam() == TEAM_SPECTATORS)
				{
					pPlayer->SetClass(PLAYERCLASS_NONE);
				}
			}
		}
		
		//Win check
		if(m_InfectedStarted && m_HumanCounter == 0 && m_InfectedCounter > 1)
		{			
			float RoundDuration = static_cast<float>((Server()->Tick()-m_RoundStartTick)/((float)Server()->TickSpeed()))/60.0f;
			int Minutes = static_cast<int>(RoundDuration);
			int Seconds = static_cast<int>((RoundDuration - Minutes)*60.0f);
			
			GameServer()->SendChatTarget_Language_ii(-1, "Infected won the round in %i:%02i minutes", Minutes, Seconds);
			
			EndRound();
		}
		
		//Start the final explosion if the time is over
		if(m_InfectedStarted && !m_ExplosionStarted && g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60)
		{
			for(CCharacter *p = (CCharacter*) GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER); p; p = (CCharacter *)p->TypeNext())
			{
				if(p->IsInfected())
				{
					GameServer()->SendEmoticon(p->GetPlayer()->GetCID(), EMOTICON_GHOST);
				}
				else
				{
					GameServer()->SendEmoticon(p->GetPlayer()->GetCID(), EMOTICON_EYES);
				}
			}
			m_ExplosionStarted = true;
		}
		
		//Do the final explosion
		if(m_ExplosionStarted)
		{		
			bool NewExplosion = false;
			
			for(int j=0; j<m_MapHeight; j++)
			{
				for(int i=0; i<m_MapWidth; i++)
				{
					if((m_GrowingMap[j*m_MapWidth+i] & 1) && (
						(i > 0 && m_GrowingMap[j*m_MapWidth+i-1] & 2) ||
						(i < m_MapWidth-1 && m_GrowingMap[j*m_MapWidth+i+1] & 2) ||
						(j > 0 && m_GrowingMap[(j-1)*m_MapWidth+i] & 2) ||
						(j < m_MapHeight-1 && m_GrowingMap[(j+1)*m_MapWidth+i] & 2)
					))
					{
						NewExplosion = true;
						m_GrowingMap[j*m_MapWidth+i] |= 8;
						m_GrowingMap[j*m_MapWidth+i] &= ~1;
						if(rand()%10 == 0)
						{
							vec2 TilePos = vec2(16.0f, 16.0f) + vec2(i*32.0f, j*32.0f);
							GameServer()->CreateExplosion(TilePos, -1, WEAPON_GAME, true);
							GameServer()->CreateSound(TilePos, SOUND_GRENADE_EXPLODE);
						}
					}
				}
			}
			
			for(int j=0; j<m_MapHeight; j++)
			{
				for(int i=0; i<m_MapWidth; i++)
				{
					if(m_GrowingMap[j*m_MapWidth+i] & 8)
					{
						m_GrowingMap[j*m_MapWidth+i] &= ~8;
						m_GrowingMap[j*m_MapWidth+i] |= 2;
					}
				}
			}
			
			for(CCharacter *p = (CCharacter*) GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER); p; p = (CCharacter *)p->TypeNext())
			{
				if(!p->IsInfected())
					continue;
				
				int tileX = static_cast<int>(round(p->m_Pos.x))/32;
				int tileY = static_cast<int>(round(p->m_Pos.y))/32;
				
				if(tileX < 0) tileX = 0;
				if(tileX >= m_MapWidth) tileX = m_MapWidth-1;
				if(tileY < 0) tileY = 0;
				if(tileY >= m_MapHeight) tileY = m_MapHeight-1;
				
				if(m_GrowingMap[tileY*m_MapWidth+tileX] & 2 && p->GetPlayer())
				{
					p->Die(p->GetPlayer()->GetCID(), WEAPON_GAME);
				}
			}
		
			//If no more explosions, game over, decide who win
			if(!NewExplosion)
			{
				if(m_HumanCounter)
				{
					if(m_HumanCounter <= 1)
					{
						GameServer()->SendChatTarget_Language(-1, "One human won the round");
					}
					else
					{
						GameServer()->SendChatTarget_Language_i(-1, "%i humans won the round", m_HumanCounter);
					}
					
					for(int i = 0; i < MAX_CLIENTS; i ++)
					{
						CPlayer *pPlayer = GameServer()->m_apPlayers[i];
						
						if(!pPlayer) continue;
						if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
						
						if(!pPlayer->IsInfected())
						{
							pPlayer->IncreaseScore(5);
							pPlayer->m_WinAsHuman++;
							
							GameServer()->SendChatTarget_Language(i, "You have survived, +5 points");
						}
					}
				}
				else
				{
					GameServer()->SendChatTarget_Language_ii(-1, "Infected won the round in %i:%02i minutes", g_Config.m_SvTimelimit, 0);
				}
				
				EndRound();
			}
		}
	}
	else
	{
		m_RoundStartTick = Server()->Tick();
	}
}
Beispiel #7
0
bool CGameControllerMOD::PreSpawn(CPlayer* pPlayer, vec2 *pOutPos)
{
	// spectators can't spawn
	if(pPlayer->GetTeam() == TEAM_SPECTATORS)
		return false;
	
	if(m_InfectedStarted)
	{
		pPlayer->StartInfection();
	}
	else
	{
		pPlayer->m_WasHumanThisRound = true;
	}
		
	if(pPlayer->IsInfected() && m_ExplosionStarted)
		return false;
		
	if(m_InfectedStarted && pPlayer->IsInfected() && rand()%3 > 0)
	{
		for(int i = 0; i < MAX_CLIENTS; i ++)
		{
			CPlayer *pWitch = GameServer()->m_apPlayers[i];
			
			if(!pWitch) continue;
			if(pWitch->GetCID() == pPlayer->GetCID()) continue;
			if(pWitch->GetClass() != PLAYERCLASS_WITCH) continue;
			if(!pWitch->GetCharacter()) continue;
			
			vec2 spawnTile = vec2(16.0f, 16.0f) + vec2(
				static_cast<float>(static_cast<int>(round(pWitch->GetCharacter()->m_Pos.x))/32)*32.0,
				static_cast<float>(static_cast<int>(round(pWitch->GetCharacter()->m_Pos.y))/32)*32.0);
			
			for(int j=-1; j<=1; j++)
			{
				if(IsSpawnable(vec2(spawnTile.x + j*32.0, spawnTile.y-64.0)))
				{
					*pOutPos = spawnTile + vec2(j*32.0, -64.0);
					return true;
				}
				if(IsSpawnable(vec2(spawnTile.x + j*32.0, spawnTile.y+64.0)))
				{
					*pOutPos = spawnTile + vec2(j*32.0, 64.0);
					return true;
				}
				if(IsSpawnable(vec2(spawnTile.x-64.0, spawnTile.y + j*32.0)))
				{
					*pOutPos = spawnTile + vec2(-64.0, j*32.0);
					return true;
				}
				if(IsSpawnable(vec2(spawnTile.x+64.0, spawnTile.y + j*32.0)))
				{
					*pOutPos = spawnTile + vec2(64.0, j*32.0);
					return true;
				}
			}
		}
	}
			
	CSpawnEval Eval;
	int Team = (pPlayer->IsInfected() ? TEAM_RED : TEAM_BLUE);
	Eval.m_FriendlyTeam = Team;

	// first try own team spawn, then normal spawn and then enemy
	EvaluateSpawnType(&Eval, Team);

	*pOutPos = Eval.m_Pos;
	return Eval.m_Got;
}
Beispiel #8
0
void CPlayer::Tick()
{
	if(!IsDummy() && !Server()->ClientIngame(m_ClientID))
		return;

	Server()->SetClientScore(m_ClientID, m_Score);

	// do latency stuff
	{
		IServer::CClientInfo Info;
		if(Server()->GetClientInfo(m_ClientID, &Info))
		{
			m_Latency.m_Accum += Info.m_Latency;
			m_Latency.m_AccumMax = max(m_Latency.m_AccumMax, Info.m_Latency);
			m_Latency.m_AccumMin = min(m_Latency.m_AccumMin, Info.m_Latency);
		}
		// each second
		if(Server()->Tick()%Server()->TickSpeed() == 0)
		{
			m_Latency.m_Avg = m_Latency.m_Accum/Server()->TickSpeed();
			m_Latency.m_Max = m_Latency.m_AccumMax;
			m_Latency.m_Min = m_Latency.m_AccumMin;
			m_Latency.m_Accum = 0;
			m_Latency.m_AccumMin = 1000;
			m_Latency.m_AccumMax = 0;
		}
	}

	if(m_pCharacter && !m_pCharacter->IsAlive())
	{
		delete m_pCharacter;
		m_pCharacter = 0;
	}

	if(!GameServer()->m_pController->IsGamePaused())
	{
		if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW)
			m_ViewPos -= vec2(clamp(m_ViewPos.x-m_LatestActivity.m_TargetX, -500.0f, 500.0f), clamp(m_ViewPos.y-m_LatestActivity.m_TargetY, -400.0f, 400.0f));

		if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick() && !m_DeadSpecMode)
			Respawn();

		if(m_pCharacter)
		{
			if(m_pCharacter->IsAlive())
				m_ViewPos = m_pCharacter->m_Pos;
		}
		else if(m_Spawning && m_RespawnTick <= Server()->Tick())
			TryRespawn();

		if(!m_DeadSpecMode && m_LastActionTick != Server()->Tick())
			++m_InactivityTickCounter;
	}
	else
	{
		++m_RespawnTick;
		++m_DieTick;
		++m_ScoreStartTick;
		++m_LastActionTick;
		++m_TeamChangeTick;
 	}
}
Beispiel #9
0
void CPickup::Tick()
{
	// wait for respawn
	if(m_SpawnTick > 0)
	{
		if(Server()->Tick() > m_SpawnTick)
		{
			// respawn
			m_SpawnTick = -1;

			if(m_Type == POWERUP_WEAPON)
				GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SPAWN);
		}
		else
			return;
	}
	// Check if a player intersected us
	CCharacter *pChr = GameServer()->m_World.ClosestCharacter(m_Pos, 20.0f, 0);
	if(pChr && pChr->IsAlive())
	{
		// player picked us up, is someone was hooking us, let them go
		int RespawnTime = -1;
		switch (m_Type)
		{
			case POWERUP_HEALTH:
				if(pChr->IncreaseHealth(1))
				{
					GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
				}
				break;
				
			case POWERUP_ARMOR:
				if(pChr->IncreaseArmor(1))
				{
					GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR);
					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
				}
				break;

			case POWERUP_WEAPON:
				if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS)
				{
					if(pChr->GiveWeapon(m_Subtype, 10))
					{
						RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;

						if(m_Subtype == WEAPON_GRENADE)
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
						else if(m_Subtype == WEAPON_SHOTGUN)
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
						else if(m_Subtype == WEAPON_RIFLE)
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);

						if(pChr->GetPlayer())
							GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), m_Subtype);
					}
				}
				break;
				
			case POWERUP_NINJA:
				{
					// activate ninja on target player
					pChr->GiveNinja();
					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;

					// loop through all players, setting their emotes
					CEntity *apEnts[64];
					int Num = GameServer()->m_World.FindEntities(vec2(0, 0), 1000000, apEnts, 64, NETOBJTYPE_CHARACTER);
					
					for (int i = 0; i < Num; ++i)
					{
						CCharacter *pC = static_cast<CCharacter *>(apEnts[i]);
						if (pC != pChr)
							pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed());
					}

					pChr->SetEmote(EMOTE_ANGRY, Server()->Tick() + 1200 * Server()->TickSpeed() / 1000);
					break;
				}
				
			default:
				break;
		};

		if(RespawnTime >= 0)
		{
			dbg_msg("game", "pickup player='%d:%s' item=%d/%d",
				pChr->GetPlayer()->GetCID(), Server()->ClientName(pChr->GetPlayer()->GetCID()), m_Type, m_Subtype);
			m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * RespawnTime;
		}
	}
}
Beispiel #10
0
void CDragger::Move()
{
	if (m_Target && (!m_Target->IsAlive() || (m_Target->IsAlive()
			&& (m_Target->m_Super || m_Target->IsPaused()
					|| (m_Layer == LAYER_SWITCH && m_Number
							&& !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[m_Target->Team()])))))
		m_Target = 0;

	mem_zero(m_SoloEnts, sizeof(m_SoloEnts));
	CCharacter *TempEnts[MAX_CLIENTS];

	int Num = GameServer()->m_World.FindEntities(m_Pos, g_Config.m_SvDraggerRange,
			(CEntity**) m_SoloEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
	mem_copy(TempEnts, m_SoloEnts, sizeof(TempEnts));

	int Id = -1;
	int MinLen = 0;
	CCharacter *Temp;
	for (int i = 0; i < Num; i++)
	{
		Temp = m_SoloEnts[i];
		if (Temp->Team() != m_CaughtTeam)
		{
			m_SoloEnts[i] = 0;
			continue;
		}
		if (m_Layer == LAYER_SWITCH && m_Number
				&& !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Temp->Team()])
		{
			m_SoloEnts[i] = 0;
			continue;
		}
		int Res =
				m_NW ? GameServer()->Collision()->IntersectNoLaserNW(m_Pos,
								Temp->m_Pos, 0, 0) :
						GameServer()->Collision()->IntersectNoLaser(m_Pos,
								Temp->m_Pos, 0, 0);

		if (Res == 0)
		{
			int Len = length(Temp->m_Pos - m_Pos);
			if (MinLen == 0 || MinLen > Len)
			{
				MinLen = Len;
				Id = i;
			}

			if (!Temp->Teams()->m_Core.GetSolo(Temp->GetPlayer()->GetCID()))
				m_SoloEnts[i] = 0;
		}
		else
		{
			m_SoloEnts[i] = 0;
		}
	}

	if (!m_Target)
		m_Target = Id != -1 ? TempEnts[Id] : 0;

	if (m_Target)
	{
		for (int i = 0; i < MAX_CLIENTS; i++)
		{
			if (m_SoloEnts[i] == m_Target)
				m_SoloEnts[i] = 0;
		}
	}
}
Beispiel #11
0
void CDragger::Drag()
{
	if (m_Target)
	{
		CCharacter *Target = m_Target;

		for (int i = -1; i < MAX_CLIENTS; i++)
		{
			if (i >= 0)
				Target = m_SoloEnts[i];

			if (!Target)
				continue;

			int Res = 0;
			if (!m_NW)
				Res = GameServer()->Collision()->IntersectNoLaser(m_Pos,
						Target->m_Pos, 0, 0);
			else
				Res = GameServer()->Collision()->IntersectNoLaserNW(m_Pos,
						Target->m_Pos, 0, 0);
			if (Res || length(m_Pos - Target->m_Pos) > g_Config.m_SvDraggerRange)
			{
				Target = 0;
				if (i == -1)
					m_Target = 0;
				else
					m_SoloEnts[i] = 0;
			}
			else if (length(m_Pos - Target->m_Pos) > 28)
			{
				vec2 Temp = Target->Core()->m_Vel
						+ (normalize(m_Pos - Target->m_Pos) * m_Strength);
				if (Temp.x > 0
						&& ((Target->m_TileIndex == TILE_STOP
								&& Target->m_TileFlags == ROTATION_270)
								|| (Target->m_TileIndexL == TILE_STOP
										&& Target->m_TileFlagsL == ROTATION_270)
								|| (Target->m_TileIndexL == TILE_STOPS
										&& (Target->m_TileFlagsL == ROTATION_90
												|| Target->m_TileFlagsL
														== ROTATION_270))
								|| (Target->m_TileIndexL == TILE_STOPA)
								|| (Target->m_TileFIndex == TILE_STOP
										&& Target->m_TileFFlags == ROTATION_270)
								|| (Target->m_TileFIndexL == TILE_STOP
										&& Target->m_TileFFlagsL == ROTATION_270)
								|| (Target->m_TileFIndexL == TILE_STOPS
										&& (Target->m_TileFFlagsL == ROTATION_90
												|| Target->m_TileFFlagsL
														== ROTATION_270))
								|| (Target->m_TileFIndexL == TILE_STOPA)
								|| (Target->m_TileSIndex == TILE_STOP
										&& Target->m_TileSFlags == ROTATION_270)
								|| (Target->m_TileSIndexL == TILE_STOP
										&& Target->m_TileSFlagsL == ROTATION_270)
								|| (Target->m_TileSIndexL == TILE_STOPS
										&& (Target->m_TileSFlagsL == ROTATION_90
												|| Target->m_TileSFlagsL
														== ROTATION_270))
								|| (Target->m_TileSIndexL == TILE_STOPA)))
					Temp.x = 0;
				if (Temp.x < 0
						&& ((Target->m_TileIndex == TILE_STOP
								&& Target->m_TileFlags == ROTATION_90)
								|| (Target->m_TileIndexR == TILE_STOP
										&& Target->m_TileFlagsR == ROTATION_90)
								|| (Target->m_TileIndexR == TILE_STOPS
										&& (Target->m_TileFlagsR == ROTATION_90
												|| Target->m_TileFlagsR
														== ROTATION_270))
								|| (Target->m_TileIndexR == TILE_STOPA)
								|| (Target->m_TileFIndex == TILE_STOP
										&& Target->m_TileFFlags == ROTATION_90)
								|| (Target->m_TileFIndexR == TILE_STOP
										&& Target->m_TileFFlagsR == ROTATION_90)
								|| (Target->m_TileFIndexR == TILE_STOPS
										&& (Target->m_TileFFlagsR == ROTATION_90
												|| Target->m_TileFFlagsR
														== ROTATION_270))
								|| (Target->m_TileFIndexR == TILE_STOPA)
								|| (Target->m_TileSIndex == TILE_STOP
										&& Target->m_TileSFlags == ROTATION_90)
								|| (Target->m_TileSIndexR == TILE_STOP
										&& Target->m_TileSFlagsR == ROTATION_90)
								|| (Target->m_TileSIndexR == TILE_STOPS
										&& (Target->m_TileSFlagsR == ROTATION_90
												|| Target->m_TileSFlagsR
														== ROTATION_270))
								|| (Target->m_TileSIndexR == TILE_STOPA)))
					Temp.x = 0;
				if (Temp.y < 0
						&& ((Target->m_TileIndex == TILE_STOP
								&& Target->m_TileFlags == ROTATION_180)
								|| (Target->m_TileIndexB == TILE_STOP
										&& Target->m_TileFlagsB == ROTATION_180)
								|| (Target->m_TileIndexB == TILE_STOPS
										&& (Target->m_TileFlagsB == ROTATION_0
												|| Target->m_TileFlagsB
														== ROTATION_180))
								|| (Target->m_TileIndexB == TILE_STOPA)
								|| (Target->m_TileFIndex == TILE_STOP
										&& Target->m_TileFFlags == ROTATION_180)
								|| (Target->m_TileFIndexB == TILE_STOP
										&& Target->m_TileFFlagsB == ROTATION_180)
								|| (Target->m_TileFIndexB == TILE_STOPS
										&& (Target->m_TileFFlagsB == ROTATION_0
												|| Target->m_TileFFlagsB
														== ROTATION_180))
								|| (Target->m_TileFIndexB == TILE_STOPA)
								|| (Target->m_TileSIndex == TILE_STOP
										&& Target->m_TileSFlags == ROTATION_180)
								|| (Target->m_TileSIndexB == TILE_STOP
										&& Target->m_TileSFlagsB == ROTATION_180)
								|| (Target->m_TileSIndexB == TILE_STOPS
										&& (Target->m_TileSFlagsB == ROTATION_0
												|| Target->m_TileSFlagsB
														== ROTATION_180))
								|| (Target->m_TileSIndexB == TILE_STOPA)))
					Temp.y = 0;
				if (Temp.y > 0
						&& ((Target->m_TileIndex == TILE_STOP
								&& Target->m_TileFlags == ROTATION_0)
								|| (Target->m_TileIndexT == TILE_STOP
										&& Target->m_TileFlagsT == ROTATION_0)
								|| (Target->m_TileIndexT == TILE_STOPS
										&& (Target->m_TileFlagsT == ROTATION_0
												|| Target->m_TileFlagsT
														== ROTATION_180))
								|| (Target->m_TileIndexT == TILE_STOPA)
								|| (Target->m_TileFIndex == TILE_STOP
										&& Target->m_TileFFlags == ROTATION_0)
								|| (Target->m_TileFIndexT == TILE_STOP
										&& Target->m_TileFFlagsT == ROTATION_0)
								|| (Target->m_TileFIndexT == TILE_STOPS
										&& (Target->m_TileFFlagsT == ROTATION_0
												|| Target->m_TileFFlagsT
														== ROTATION_180))
								|| (Target->m_TileFIndexT == TILE_STOPA)
								|| (Target->m_TileSIndex == TILE_STOP
										&& Target->m_TileSFlags == ROTATION_0)
								|| (Target->m_TileSIndexT == TILE_STOP
										&& Target->m_TileSFlagsT == ROTATION_0)
								|| (Target->m_TileSIndexT == TILE_STOPS
										&& (Target->m_TileSFlagsT == ROTATION_0
												|| Target->m_TileSFlagsT
														== ROTATION_180))
								|| (Target->m_TileSIndexT == TILE_STOPA)))
					Temp.y = 0;
				Target->Core()->m_Vel = Temp;
			}
		}
	}
}
Beispiel #12
0
void CDragger::Snap(int SnappingClient)
{
	if (((CGameControllerDDRace*) GameServer()->m_pController)->m_Teams.GetTeamState(
			m_CaughtTeam) == CGameTeams::TEAMSTATE_EMPTY)
		return;

	CCharacter *Target = m_Target;

	for (int i = 0; i < MAX_CLIENTS; i++)
	{
		if (m_SoloIDs[i] == -1)
			break;

		Server()->SnapFreeID(m_SoloIDs[i]);
		m_SoloIDs[i] = -1;
	}

	int pos = 0;

	for (int i = -1; i < MAX_CLIENTS; i++)
	{
		if (i >= 0)
		{
			Target = m_SoloEnts[i];

			if (!Target)
				continue;
		}

		if (Target)
		{
			if (NetworkClipped(SnappingClient, m_Pos)
					&& NetworkClipped(SnappingClient, Target->m_Pos))
				continue;
		}
		else if (NetworkClipped(SnappingClient, m_Pos))
			continue;

		CCharacter * Char = GameServer()->GetPlayerChar(SnappingClient);

		if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1
					|| GameServer()->m_apPlayers[SnappingClient]->IsPaused())
				&& GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW)
			Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID);

		int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11;
		if (Char && Char->IsAlive()
				&& (m_Layer == LAYER_SWITCH && m_Number
						&& !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()]
						&& (!Tick)))
			continue;
		if (Char && Char->IsAlive())
		{
			if (Char->Team() != m_CaughtTeam)
				continue;
		}
		else
		{
			// send to spectators only active draggers and some inactive from team 0
			if (!((Target && Target->IsAlive()) || m_CaughtTeam == 0))
				continue;
		}

		if (Char && Char->IsAlive() && Target && Target->IsAlive() && Target->GetPlayer()->GetCID() != Char->GetPlayer()->GetCID() && !Char->GetPlayer()->m_ShowOthers &&
			(Char->Teams()->m_Core.GetSolo(SnappingClient) || Char->Teams()->m_Core.GetSolo(Target->GetPlayer()->GetCID())))
		{
			continue;
		}

		CNetObj_Laser *obj;

		if (i == -1)
		{
			obj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(
					NETOBJTYPE_LASER, m_ID, sizeof(CNetObj_Laser)));
		}
		else
		{
			m_SoloIDs[pos] = Server()->SnapNewID();
			obj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem( // TODO: Have to free IDs again?
					NETOBJTYPE_LASER, m_SoloIDs[pos], sizeof(CNetObj_Laser)));
			pos++;
		}

		if (!obj)
			continue;
		obj->m_X = (int)m_Pos.x;
		obj->m_Y = (int)m_Pos.y;
		if (Target)
		{
			obj->m_FromX = (int)Target->m_Pos.x;
			obj->m_FromY = (int)Target->m_Pos.y;
		}
		else
		{
			obj->m_FromX = (int)m_Pos.x;
			obj->m_FromY = (int)m_Pos.y;
		}

		int StartTick = m_EvalTick;
		if (StartTick < Server()->Tick() - 4)
			StartTick = Server()->Tick() - 4;
		else if (StartTick > Server()->Tick())
			StartTick = Server()->Tick();
		obj->m_StartTick = StartTick;
	}
}
Beispiel #13
0
void CDigitanksEntity::Think()
{
	BaseClass::Think();

	if (m_flNextDirtyOrigin > 0 && GameServer()->GetGameTime() > m_flNextDirtyOrigin)
	{
		DirtyVisibility();

		m_flNextDirtyOrigin = 0;
	}

	if (m_flNextDirtyArea > 0 && GameServer()->GetGameTime() > m_flNextDirtyArea)
	{
		CDigitanksEntity* pOther = this;

		while (true)
		{
			pOther = CBaseEntity::FindClosest<CDigitanksEntity>(GetGlobalOrigin(), pOther);

			if (!pOther)
				break;

			if (pOther == this)
				continue;

			if (pOther->Distance(GetGlobalOrigin()) > VisibleRange() + DigitanksGame()->FogPenetrationDistance())
				break;

			pOther->DirtyVisibility();
		}

		m_flNextDirtyArea = 0;
	}

	if (GameNetwork()->IsHost() && !IsAlive() && GameServer()->GetGameTime() > m_flTimeKilled + 1.0f)
	{
		GameServer()->Delete(this);

		if (DigitanksGame()->GetTerrain()->IsPointOverHole(GetGlobalOrigin()))
		{
			CWreckage* pWreckage = CreateWreckage();

			if (pWreckage)
			{
				pWreckage->FellIntoHole();
				if (DigitanksGame()->GetGameType() == GAMETYPE_ARTILLERY)
					pWreckage->SetScale(2);
			}
		}
		else if (DigitanksGame()->GetGameType() == GAMETYPE_ARTILLERY)
		{
			switch (RandomInt(0, 8))
			{
			case 0:
			case 6:
			case 7:
			case 8:
			default:
			{
				for (size_t i = 0; i < 8; i++)
				{
					CDebris* pDebris = GameServer()->Create<CDebris>("CDebris");
					pDebris->SetGlobalOrigin(GetGlobalOrigin());
				}

				CWreckage* pWreckage = CreateWreckage();
				pWreckage->SetScale(2);

				DigitanksGame()->GetOverheadCamera()->Shake(GetGlobalOrigin(), 3);
				break;
			}

			case 1:
			{
				CProjectile* pProjectile = GameServer()->Create<CLargeShell>("CLargeShell");
				pProjectile->SetOwner(NULL);
				pProjectile->SetGlobalOrigin(GetGlobalOrigin());
				pProjectile->Explode();
				break;
			}

			case 2:
			{
				CProjectile* pProjectile = GameServer()->Create<CAOEShell>("CAOEShell");
				pProjectile->SetOwner(NULL);
				pProjectile->SetGlobalOrigin(GetGlobalOrigin());
				pProjectile->Explode();
				break;
			}

			case 3:
			{
				CProjectile* pProjectile = GameServer()->Create<CClusterBomb>("CClusterBomb");
				pProjectile->SetOwner(NULL);
				pProjectile->SetGlobalOrigin(GetGlobalOrigin());
				pProjectile->Explode();
				break;
			}

			case 4:
			{
				CProjectile* pProjectile = GameServer()->Create<CEarthshaker>("CEarthshaker");
				pProjectile->SetOwner(NULL);
				pProjectile->SetGlobalOrigin(GetGlobalOrigin());
				pProjectile->Explode();
				break;
			}

			case 5:
			{
				CProjectile* pProjectile = GameServer()->Create<CTractorBomb>("CTractorBomb");
				pProjectile->SetOwner(NULL);
				pProjectile->SetGlobalOrigin(GetGlobalOrigin());
				pProjectile->Explode();
				break;
			}
			}
		}
		else
		{
			// Strategy mode
			CreateWreckage();
		}
	}

	m_hCageParticles.SetActive(IsImprisoned() && GetVisibility() > 0.1f);
}
Beispiel #14
0
void CDigitanksEntity::OnRender(CGameRenderingContext* pContext) const
{
	BaseClass::OnRender(pContext);

	if (GameServer()->GetRenderer()->IsRenderingTransparent() && IsImprisoned())
	{
		CGameRenderingContext c(GameServer()->GetRenderer(), true);
		c.SetBackCulling(false);
		c.SetBlend(BLEND_ADDITIVE);
		c.Scale(GetBoundingRadius(), GetBoundingRadius(), GetBoundingRadius());
		c.Rotate((float)GameServer()->GetGameTime() * 90, Vector(0, 0, 1));

		float flVisibility = GetVisibility() * 0.6f;
		c.UseProgram("scroll");
		c.SetUniform("iTexture", 0);
		c.SetUniform("flAlpha", flVisibility);
		c.SetUniform("flTime", (float)-GameServer()->GetGameTime());
		c.SetUniform("flSpeed", 1.0f);

		c.RenderModel(m_iCageModel, this);
	}

	if (GameServer()->GetRenderer()->IsRenderingTransparent() && IsImprisoned())
	{
		CGameRenderingContext c(GameServer()->GetRenderer(), true);
		c.SetBackCulling(false);
		c.SetBlend(BLEND_ADDITIVE);
		c.Scale(GetBoundingRadius()+1, GetBoundingRadius()+1, GetBoundingRadius()+1);
		c.Rotate(-(float)GameServer()->GetGameTime() * 90, Vector(0, 0, 1));

		float flVisibility = GetVisibility() * 0.6f;
		c.UseProgram("scroll");
		c.SetUniform("iTexture", 0);
		c.SetUniform("flAlpha", flVisibility);
		c.SetUniform("flTime", (float)-GameServer()->GetGameTime());
		c.SetUniform("flSpeed", 1.0f);

		c.RenderModel(m_iCageModel);
	}

	if (!GameServer()->GetRenderer()->IsRenderingTransparent())
		return;

	if (!DigitanksGame()->GetTerrain()->GetBit(CTerrain::WorldToArraySpace(GetGlobalOrigin().x), CTerrain::WorldToArraySpace(GetGlobalOrigin().y), TB_TREE))
		return;

	if (GetVisibility() < 0.6f)
		return;

	CGameRenderingContext c(GameServer()->GetRenderer(), true);
	c.SetBlend(BLEND_NONE);
	c.SetAlpha(1);
	c.BindTexture(0);

	TStubbed("Tank outlines in trees");

	/*
	// Draw outlines of objects in trees.
	glPushAttrib( GL_ALL_ATTRIB_BITS );

	glDisable( GL_TEXTURE_2D );
	glEnable( GL_POLYGON_OFFSET_FILL );
	glPolygonOffset( -3.5f, -3.5f );

	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glDepthMask(true);
	glEnable(GL_DEPTH_TEST);
	pContext->RenderModel(GetModel());

	glDisable( GL_POLYGON_OFFSET_FILL );
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glDepthMask(false);
	glEnable(GL_DEPTH_TEST);
	glLineWidth( 2.0f );
	glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
	glColor3ubv( Color(0, 0, 0) );
	pContext->RenderModel(GetModel());

	glPopAttrib();
	*/
}
Beispiel #15
0
void CCharacter::Destroy()
{
	GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
	m_Alive = false;
}
Beispiel #16
0
void CLaser::Reset()
{
	GameServer()->m_World.DestroyEntity(this);
}
Beispiel #17
0
CGameControllerMOD::CGameControllerMOD(class CGameContext *pGameServer)
: IGameController(pGameServer)
{
	m_pGameType = "InfClass";
	srand (time(0));
	
	m_TotalProbInfectedClass = 0.0;
	
	m_ClassProbability[PLAYERCLASS_SMOKER] = 1.0f;
	m_TotalProbInfectedClass += m_ClassProbability[PLAYERCLASS_SMOKER];
	
	m_ClassProbability[PLAYERCLASS_HUNTER] = 0.6666f * m_ClassProbability[PLAYERCLASS_SMOKER];
	m_TotalProbInfectedClass += m_ClassProbability[PLAYERCLASS_HUNTER];
	
	m_ClassProbability[PLAYERCLASS_BOOMER] = 0.6666f * m_ClassProbability[PLAYERCLASS_SMOKER];
	m_TotalProbInfectedClass += m_ClassProbability[PLAYERCLASS_BOOMER];
	
	m_ClassProbability[PLAYERCLASS_GHOST] = 0.25f * m_ClassProbability[PLAYERCLASS_SMOKER];
	m_TotalProbInfectedClass += m_ClassProbability[PLAYERCLASS_GHOST];
	
	m_ClassProbability[PLAYERCLASS_SPIDER] = 0.25f * m_ClassProbability[PLAYERCLASS_SMOKER];
	m_TotalProbInfectedClass += m_ClassProbability[PLAYERCLASS_SPIDER];
	
	m_ClassProbability[PLAYERCLASS_WITCH] = 0.25f * m_ClassProbability[PLAYERCLASS_SMOKER];
	m_TotalProbInfectedClass += m_ClassProbability[PLAYERCLASS_WITCH];
	
	m_ClassProbability[PLAYERCLASS_UNDEAD] = 0.20f * m_ClassProbability[PLAYERCLASS_SMOKER];
	m_TotalProbInfectedClass += m_ClassProbability[PLAYERCLASS_UNDEAD];
	
	m_TotalProbHumanClass = 0.0;
	
	m_ClassProbability[PLAYERCLASS_ENGINEER] = 1.0f;
	m_TotalProbHumanClass += m_ClassProbability[PLAYERCLASS_ENGINEER];
	
	m_ClassProbability[PLAYERCLASS_SOLDIER] = 1.0f;
	m_TotalProbHumanClass += m_ClassProbability[PLAYERCLASS_SOLDIER];
	
	m_ClassProbability[PLAYERCLASS_MERCENARY] = 1.0f;
	m_TotalProbHumanClass += m_ClassProbability[PLAYERCLASS_MERCENARY];
	
	m_ClassProbability[PLAYERCLASS_SNIPER] = 1.0f;
	m_TotalProbHumanClass += m_ClassProbability[PLAYERCLASS_SNIPER];
	
	m_ClassProbability[PLAYERCLASS_SCIENTIST] = 0.5f;
	m_TotalProbHumanClass += m_ClassProbability[PLAYERCLASS_SCIENTIST];
	
	m_ClassProbability[PLAYERCLASS_NINJA] = 0.5f;
	m_TotalProbHumanClass += m_ClassProbability[PLAYERCLASS_NINJA];
	
	m_ClassProbability[PLAYERCLASS_MEDIC] = 0.5f;
	m_TotalProbHumanClass += m_ClassProbability[PLAYERCLASS_MEDIC];
	
	m_GrowingMap = 0;
	
	m_ExplosionStarted = false;
	m_MapWidth = GameServer()->Collision()->GetWidth();
	m_MapHeight = GameServer()->Collision()->GetHeight();
	m_GrowingMap = new int[m_MapWidth*m_MapHeight];
	
	m_HumanCounter = 0;
	m_InfectedCounter = 0;
	m_InfectedStarted = false;
	
	for(int j=0; j<m_MapHeight; j++)
	{
		for(int i=0; i<m_MapWidth; i++)
		{
			vec2 TilePos = vec2(16.0f, 16.0f) + vec2(i*32.0f, j*32.0f);
			if(GameServer()->Collision()->CheckPoint(TilePos))
			{
				m_GrowingMap[j*m_MapWidth+i] = 4;
			}
			else
			{
				m_GrowingMap[j*m_MapWidth+i] = 1;
			}
		}
	}
}
Beispiel #18
0
void CLaser::Tick()
{
	if(Server()->Tick() > m_EvalTick+(Server()->TickSpeed()*GameServer()->Tuning()->m_LaserBounceDelay)/1000.0f)
		DoBounce();
}
Beispiel #19
0
void CGameControllerMOD::Snap(int SnappingClient)
{
	CNetObj_GameInfo *pGameInfoObj = (CNetObj_GameInfo *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFO, 0, sizeof(CNetObj_GameInfo));
	if(!pGameInfoObj)
		return;

	pGameInfoObj->m_GameFlags = m_GameFlags;
	pGameInfoObj->m_GameStateFlags = 0;
	if(m_GameOverTick != -1)
		pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_GAMEOVER;
	if(m_SuddenDeath)
		pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_SUDDENDEATH;
	if(GameServer()->m_World.m_Paused)
		pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_PAUSED;
	pGameInfoObj->m_RoundStartTick = m_RoundStartTick;
	pGameInfoObj->m_WarmupTimer = m_Warmup;

	pGameInfoObj->m_ScoreLimit = g_Config.m_SvScorelimit;
	pGameInfoObj->m_TimeLimit = g_Config.m_SvTimelimit;

	pGameInfoObj->m_RoundNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap : 0;
	pGameInfoObj->m_RoundCurrent = m_RoundCount+1;

	//Generate class mask
	int ClassMask = 0;
	{
		int Defender = 0;
		int Medic = 0;
		int Support = 0;
		
		for(int i = 0; i < MAX_CLIENTS; i ++)
		{
			CPlayer *pPlayer = GameServer()->m_apPlayers[i];
			
			if(!pPlayer) continue;
			if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
			
			switch(pPlayer->GetClass())
			{
				case PLAYERCLASS_NINJA:
				case PLAYERCLASS_MERCENARY:
				case PLAYERCLASS_SNIPER:
					Support++;
					break;
				case PLAYERCLASS_ENGINEER:
				case PLAYERCLASS_SOLDIER:
				case PLAYERCLASS_SCIENTIST:
					Defender++;
					break;
				case PLAYERCLASS_MEDIC:
					Medic++;
					break;
					
			}
		}
		
		if(Defender < g_Config.m_InfDefenderLimit)
			ClassMask |= CMapConverter::MASK_DEFENDER;
		if(Medic < g_Config.m_InfMedicLimit)
			ClassMask |= CMapConverter::MASK_MEDIC;
		if(Support < g_Config.m_InfSupportLimit)
			ClassMask |= CMapConverter::MASK_SUPPORT;
	}
	
	if(GameServer()->m_apPlayers[SnappingClient] && GameServer()->m_apPlayers[SnappingClient]->m_InClassChooserMenu)
	{
		int Item = GameServer()->m_apPlayers[SnappingClient]->m_MenuClassChooserItem;
		int Timer = ((CMapConverter::TIMESHIFT_MENUCLASS + (Item+1) + ClassMask*CMapConverter::TIMESHIFT_MENUCLASS_MASK)*60 + 30)*Server()->TickSpeed();
		
		pGameInfoObj->m_RoundStartTick = Server()->Tick() - Timer;
		pGameInfoObj->m_TimeLimit = 0;
	}

	CNetObj_GameData *pGameDataObj = (CNetObj_GameData *)Server()->SnapNewItem(NETOBJTYPE_GAMEDATA, 0, sizeof(CNetObj_GameData));
	if(!pGameDataObj)
		return;

	//Search for witch
	for(int i = 0; i < MAX_CLIENTS; i++)
	{
		CPlayer *pPlayer = GameServer()->m_apPlayers[i];
		
		if(!pPlayer) continue;
		if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
		
		if(pPlayer->GetClass() == PLAYERCLASS_WITCH)
		{
			pGameDataObj->m_FlagCarrierRed = i;
		}
	}
	pGameDataObj->m_FlagCarrierBlue = FLAG_ATSTAND;
}
Beispiel #20
0
bool CLaser::HitCharacter(vec2 From, vec2 To)
{
	vec2 At;
	CCharacter *OwnerChar = GameServer()->GetPlayerChar(m_Owner);
	CCharacter *Hit = GameServer()->m_World.IntersectCharacter(m_Pos, To, 0.f, At, OwnerChar);

	if(!Hit)
		return false;

	if(!OwnerChar)
	{
		if(Hit->m_GameZone && Hit->m_Frozen && m_Type == WEAPON_RIFLE)
			Hit->Unfreeze();
		else if(m_Type == WEAPON_RIFLE)
			Hit->TakeDamage(vec2(0.f, 0.f), GameServer()->Tuning()->m_LaserDamage, m_Owner, WEAPON_RIFLE);
		return false;
	}

	//CCharacter *pTarget = GameServer()->GetPlayerChar(Hit->GetPlayer()->GetCID());

	m_From = From;
	m_Pos = At;
	m_Energy = -1;

	if(m_Type == WEAPON_SHOTGUN)
	{
		Hit->m_Core.m_Vel + normalize(From - Hit->m_Core.m_Pos) * 10;
		return true;
	}

	if(OwnerChar->GetPlayer()->m_Insta && Hit->GetPlayer()->m_Insta)
		Hit->Die(OwnerChar->GetPlayer()->GetCID(), WEAPON_RIFLE);
	else if(Hit->m_GameZone && OwnerChar->m_GameZone && Hit->m_Frozen)
		Hit->Unfreeze();
	else if(OwnerChar->m_JailRifle && !Hit->GetPlayer()->m_Insta && !OwnerChar->m_GameZone)
	{
		char zBuf[200];
	    Hit->GetPlayer()->m_AccData.m_Arrested = 300;
		Hit->Die(OwnerChar->GetPlayer()->GetCID(), WEAPON_RIFLE);
  		str_format(zBuf, sizeof zBuf, "'%s' is arrested now", Server()->ClientName(Hit->GetPlayer()->GetCID()));
		GameServer()->SendChat(-1, CGameContext::CHAT_ALL, zBuf);
	}
	else if(!OwnerChar->GetPlayer()->m_Insta && !Hit->GetPlayer()->m_Insta)
		Hit->TakeDamage(vec2(0.f, 0.f), GameServer()->Tuning()->m_LaserDamage, m_Owner, WEAPON_RIFLE);
	
	// City
	if(OwnerChar && !Hit->GetPlayer()->m_AccData.m_Arrested && !Hit->GetPlayer()->m_Insta && !Hit->Protected())
	{
		if(GameServer()->m_apPlayers[m_Owner]->m_AccData.m_RifleSwap && !OwnerChar->GetPlayer()->m_Insta)
		{
			if(!OwnerChar->Protected() && !OwnerChar->m_JailRifle && !OwnerChar->GetPlayer()->m_AccData.m_Arrested)
			{
				vec2 TempPos = OwnerChar->m_Pos;
				OwnerChar->m_Core.m_Pos = Hit->m_Pos;
				Hit->m_Core.m_Pos = TempPos;
			}
		}
	}

	return true;
}
Beispiel #21
0
int CGameControllerMOD::ChooseHumanClass(CPlayer* pPlayer)
{
	float random = frandom();
	float TotalProbHumanClass = m_TotalProbHumanClass;
	
	//Get information about existing infected
	int nbSupport = 0;
	int nbMedic = 0;
	int nbDefender = 0;
	for(int i = 0; i < MAX_CLIENTS; i++)
	{
		CPlayer *pPlayer = GameServer()->m_apPlayers[i];
		
		if(!pPlayer) continue;
		if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue;
		
		switch(pPlayer->GetClass())
		{
			case PLAYERCLASS_NINJA:
			case PLAYERCLASS_MERCENARY:
			case PLAYERCLASS_SNIPER:
				nbSupport++;
				break;
			case PLAYERCLASS_MEDIC:
				nbMedic++;
				break;
			case PLAYERCLASS_ENGINEER:
			case PLAYERCLASS_SOLDIER:
			case PLAYERCLASS_SCIENTIST:
				nbDefender++;
				break;
		}
	}
	
	bool defenderEnabled = true;
	if(nbDefender >= g_Config.m_InfDefenderLimit)
	{
		TotalProbHumanClass -= m_ClassProbability[PLAYERCLASS_ENGINEER];
		TotalProbHumanClass -= m_ClassProbability[PLAYERCLASS_SOLDIER];
		TotalProbHumanClass -= m_ClassProbability[PLAYERCLASS_SCIENTIST];
		defenderEnabled = false;
	}
	
	bool supportEnabled = true;
	if(nbSupport >= g_Config.m_InfSupportLimit)
	{
		TotalProbHumanClass -= m_ClassProbability[PLAYERCLASS_NINJA];
		TotalProbHumanClass -= m_ClassProbability[PLAYERCLASS_MERCENARY];
		TotalProbHumanClass -= m_ClassProbability[PLAYERCLASS_SNIPER];
		supportEnabled = false;
	}
	
	bool medicEnabled = true;
	if(nbMedic >= g_Config.m_InfMedicLimit)
	{
		TotalProbHumanClass -= m_ClassProbability[PLAYERCLASS_MEDIC];
		medicEnabled = false;
	}
	
	if(defenderEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_ENGINEER]/TotalProbHumanClass;
		if(random < 0.0f)
		{
			return PLAYERCLASS_ENGINEER;
		}
		
		random -= m_ClassProbability[PLAYERCLASS_SOLDIER]/TotalProbHumanClass;
		if(random < 0.0f)
		{
			return PLAYERCLASS_SOLDIER;
		}
		
		random -= m_ClassProbability[PLAYERCLASS_SCIENTIST]/TotalProbHumanClass;
		if(random < 0.0f)
		{
			return PLAYERCLASS_SCIENTIST;
		}
	}
	
	if(medicEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_MEDIC]/TotalProbHumanClass;
		if(random < 0.0f)
		{
			return PLAYERCLASS_MEDIC;
		}
	}
	
	if(supportEnabled)
	{
		random -= m_ClassProbability[PLAYERCLASS_NINJA]/TotalProbHumanClass;
		if(random < 0.0f)
		{
			return PLAYERCLASS_NINJA;
		}
		
		random -= m_ClassProbability[PLAYERCLASS_MERCENARY]/TotalProbHumanClass;
		if(random < 0.0f)
		{
			return PLAYERCLASS_MERCENARY;
		}
		
		random -= m_ClassProbability[PLAYERCLASS_SNIPER]/TotalProbHumanClass;
		if(random < 0.0f)
		{
			return PLAYERCLASS_SNIPER;
		}
	}
	
	return PLAYERCLASS_ENGINEER;
}
Beispiel #22
0
void CCharacter::HandleNinja()
{
	if(m_ActiveWeapon != WEAPON_NINJA)
		return;
	
	vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));

	if ((Server()->Tick() - m_Ninja.m_ActivationTick) > (g_pData->m_Weapons.m_Ninja.m_Duration * Server()->TickSpeed() / 1000))
	{
		// time's up, return
		m_aWeapons[WEAPON_NINJA].m_Got = false;
		m_ActiveWeapon = m_LastWeapon;
		if(m_ActiveWeapon == WEAPON_NINJA)
			m_ActiveWeapon = WEAPON_GUN;
			
		SetWeapon(m_ActiveWeapon);
		return;
	}
	
	// force ninja Weapon
	SetWeapon(WEAPON_NINJA);

	m_Ninja.m_CurrentMoveTime--;

	if (m_Ninja.m_CurrentMoveTime == 0)
	{
		// reset velocity
		m_Core.m_Vel *= 0.2f;
	}

	if (m_Ninja.m_CurrentMoveTime > 0)
	{
		// Set velocity
		m_Core.m_Vel = m_Ninja.m_ActivationDir * g_pData->m_Weapons.m_Ninja.m_Velocity;
		vec2 OldPos = m_Pos;
		GameServer()->Collision()->MoveBox(&m_Core.m_Pos, &m_Core.m_Vel, vec2(m_ProximityRadius, m_ProximityRadius), 0.f);
		
		// reset velocity so the client doesn't predict stuff
		m_Core.m_Vel = vec2(0.f, 0.f);

		// check if we Hit anything along the way
		{
			CCharacter *aEnts[MAX_CLIENTS];
			vec2 Dir = m_Pos - OldPos;
			float Radius = m_ProximityRadius * 2.0f;
			vec2 Center = OldPos + Dir * 0.5f;
			int Num = GameServer()->m_World.FindEntities(Center, Radius, (CEntity**)aEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);

			for (int i = 0; i < Num; ++i)
			{
				if (aEnts[i] == this)
					continue;
					
				// make sure we haven't Hit this object before
				bool bAlreadyHit = false;
				for (int j = 0; j < m_NumObjectsHit; j++)
				{
					if (m_apHitObjects[j] == aEnts[i])
						bAlreadyHit = true;
				}
				if (bAlreadyHit)
					continue;

				// check so we are sufficiently close
				if (distance(aEnts[i]->m_Pos, m_Pos) > (m_ProximityRadius * 2.0f))
					continue;

				// Hit a player, give him damage and stuffs...
				GameServer()->CreateSound(aEnts[i]->m_Pos, SOUND_NINJA_HIT);
				// set his velocity to fast upward (for now)
				if(m_NumObjectsHit < 10)
					m_apHitObjects[m_NumObjectsHit++] = aEnts[i];
					
				aEnts[i]->TakeDamage(vec2(0, 10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA);
			}
		}
		
		return;
	}

	return;
}
Beispiel #23
0
void CPickup::Tick()
{
	
	
	// wait for respawn
	//if(m_SpawnTick > 0) - 12.5.
	if(m_SpawnTick > 0 && !m_Dropable && !m_Flashing)
	{
		if(Server()->Tick() > m_SpawnTick && !m_SkipAutoRespawn)
		{
			// respawn
			m_SpawnTick = -1;

			if(m_Type == POWERUP_WEAPON)
				GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SPAWN);
		}
		else
			return;
	}
	
	// item drops from enemies
	if (m_Dropable)
	{
		if (m_Life > 0)
			m_Life--;
		else
		{
			m_SpawnTick = 999;
			return;
		}

			
		if (m_Life < 100)
			m_Flashing = true;
	}
	
	// a small visual effect before pickup disappears
	if (m_Flashing)
	{
		m_FlashTimer--;
		
		if (m_FlashTimer <= 0)
			m_FlashTimer = 20;
			
		if (m_FlashTimer > 10)
			m_SpawnTick = 999;
		else
			m_SpawnTick = -1;
	}
	
	
	
	// physics
	if (m_Dropable)
	{
		m_Vel.y += 0.5f;
		
		bool Grounded = false;
		if(GameServer()->Collision()->CheckPoint(m_Pos.x+12, m_Pos.y+12+5))
			Grounded = true;
		if(GameServer()->Collision()->CheckPoint(m_Pos.x-12, m_Pos.y+12+5))
			Grounded = true;
		
		if (Grounded)
			m_Vel.x *= 0.8f;
		else
			m_Vel.x *= 0.99f;
		
		GameServer()->Collision()->MoveBox(&m_Pos, &m_Vel, vec2(24.0f, 24.0f), 0.4f);
	}
	
	
	// Check if a player intersected us
	CCharacter *pChr = GameServer()->m_World.ClosestCharacter(m_Pos, 20.0f, 0);
	if(pChr && pChr->IsAlive()) // && !pChr->GetPlayer()->m_pAI)
	{
		// player picked us up, is someone was hooking us, let them go
		int RespawnTime = -1;
		switch (m_Type)
		{
			case POWERUP_HEALTH:
				if (m_Subtype > 0 && m_Owner >= 0 && m_Owner < MAX_CLIENTS && GameServer()->m_apPlayers[m_Owner])
				{
					int Team = GameServer()->m_apPlayers[m_Owner]->GetTeam();
					
					if (Team != pChr->GetPlayer()->GetTeam())
					{
						if (m_Subtype == 1)
							GameServer()->CreateExplosion(m_Pos, m_Owner, WEAPON_HAMMER, false, false);
						
						if (m_Subtype == 2)
						{
							CSuperexplosion *S = new CSuperexplosion(&GameServer()->m_World, m_Pos, m_Owner, WEAPON_HAMMER, 1);
							GameServer()->m_World.InsertEntity(S);
						}

						GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
						RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
						m_Life = 0;
						m_Flashing = false;
						m_Subtype = 0;
						break;
					}
				}
				
				
				if(pChr->IncreaseHealth(10))
				{
					GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
					m_Life = 0;
					m_Flashing = false;
				}
				else
				if (pChr->GetPlayer()->GotAbility(STORE_HEALTH) && pChr->StoreHealth())
				{
					GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
					m_Life = 0;
					m_Flashing = false;
				}
				break;

			case POWERUP_ARMOR:
				if(pChr->IncreaseArmor(1))
				{
					GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR);
					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
					m_Life = 0;
					m_Flashing = false;
				}
				break;

			case POWERUP_WEAPON:
				if(m_Subtype >= 0 && m_Subtype < NUM_CUSTOMWEAPONS)
				{
					int Parent = aCustomWeapon[m_Subtype].m_ParentWeapon;
					
					if (Parent < 0 || Parent >= NUM_WEAPONS)
					{
						RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
						m_Life = 0;
						m_Flashing = false;
						break;
					}
					
					if (pChr->GiveCustomWeapon(m_Subtype, 0.2f + frandom()*0.3f))
					{
						if(Parent == WEAPON_GRENADE)
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
						else
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
						
						if(pChr->GetPlayer())
						{
							//GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), Parent);
							
							char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Picked up %s", aCustomWeapon[m_Subtype].m_Name);
							GameServer()->SendChatTarget(pChr->GetPlayer()->GetCID(), aBuf);
						}
						
						RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
						m_Life = 0;
						m_Flashing = false;
					}
					else
					{
						if (pChr->GiveAmmo(&m_Subtype, 0.125f + frandom()*0.15f))
						{
							char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Picked up ammo for %s", aCustomWeapon[m_Subtype].m_Name);
							GameServer()->SendChatTarget(pChr->GetPlayer()->GetCID(), aBuf);
							
							RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
							m_Life = 0;
							m_Flashing = false;
						}
					}
					
					/*if(pChr->GiveWeapon(m_Subtype, 10)) // !pChr->m_WeaponPicked && 
					{
						RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;

						//pChr->m_WeaponPicked = true;
						
						if(m_Subtype == WEAPON_GRENADE)
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
						else if(m_Subtype == WEAPON_SHOTGUN)
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
						else if(m_Subtype == WEAPON_RIFLE)
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);

						if(pChr->GetPlayer())
							GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), m_Subtype);
					}*/
				}
				break;

			// sword not in use, instead snap weapon to look like sword
			case POWERUP_NINJA:
				{
					/*
					// activate ninja on target player
					pChr->GiveNinja();
					RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;

					// loop through all players, setting their emotes
					CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
					for(; pC; pC = (CCharacter *)pC->TypeNext())
					{
						if (pC != pChr)
							pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed());
					}

					pChr->SetEmote(EMOTE_ANGRY, Server()->Tick() + 1200 * Server()->TickSpeed() / 1000);
					m_Flashing = false;
					break;
					*/
				}

			default:
				break;
		};

		if(RespawnTime >= 0)
		{
			char aBuf[256];
			str_format(aBuf, sizeof(aBuf), "pickup player='%d:%s' item=%d/%d",
				pChr->GetPlayer()->GetCID(), Server()->ClientName(pChr->GetPlayer()->GetCID()), m_Type, m_Subtype);
			GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
			m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * RespawnTime;
		}
	}
}
Beispiel #24
0
void CCharacter::FireWeapon()
{
	if(m_ReloadTimer != 0)
		return;
		
	DoWeaponSwitch();
	vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
	
	bool FullAuto = false;
	if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE)
		FullAuto = true;


	// check if we gonna fire
	bool WillFire = false;
	if(CountInput(m_LatestPrevInput.m_Fire, m_LatestInput.m_Fire).m_Presses)
		WillFire = true;
		
	if(FullAuto && (m_LatestInput.m_Fire&1) && m_aWeapons[m_ActiveWeapon].m_Ammo)
		WillFire = true;
		
	if(!WillFire)
		return;
		
	// check for ammo
	if(!m_aWeapons[m_ActiveWeapon].m_Ammo)
	{
		// 125ms is a magical limit of how fast a human can click
		m_ReloadTimer = 125 * Server()->TickSpeed() / 1000;
		GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO);
		return;
	}
	
	vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f;
	
	switch(m_ActiveWeapon)
	{
		case WEAPON_HAMMER:
		{
			// reset objects Hit
			m_NumObjectsHit = 0;
			GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE);
			
			CCharacter *apEnts[MAX_CLIENTS];
			int Hits = 0;
			int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts, 
														MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);

			for (int i = 0; i < Num; ++i)
			{
				CCharacter *pTarget = apEnts[i];
				
				if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL))
					continue;

				// set his velocity to fast upward (for now)
				if(length(pTarget->m_Pos-ProjStartPos) > 0.0f)
					GameServer()->CreateHammerHit(pTarget->m_Pos-normalize(pTarget->m_Pos-ProjStartPos)*m_ProximityRadius*0.5f);
				else
					GameServer()->CreateHammerHit(ProjStartPos);
				
				vec2 Dir;
				if (length(pTarget->m_Pos - m_Pos) > 0.0f)
					Dir = normalize(pTarget->m_Pos - m_Pos);
				else
					Dir = vec2(0.f, -1.f);
					
				pTarget->TakeDamage(vec2(0.f, -1.f) + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f, g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage,
					m_pPlayer->GetCID(), m_ActiveWeapon);
				Hits++;
			}
			
			// if we Hit anything, we have to wait for the reload
			if(Hits)
				m_ReloadTimer = Server()->TickSpeed()/3;
			
		} break;

		case WEAPON_GUN:
		{
			CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GUN,
				m_pPlayer->GetCID(),
				ProjStartPos,
				Direction,
				(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime),
				1, 0, 0, -1, WEAPON_GUN);
				
			// pack the Projectile and send it to the client Directly
			CNetObj_Projectile p;
			pProj->FillInfo(&p);
			
			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
			Msg.AddInt(1);
			for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
				Msg.AddInt(((int *)&p)[i]);
				
			Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
	
			GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE);
		} break;
		
		case WEAPON_SHOTGUN:
		{
			int ShotSpread = 2;

			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
			Msg.AddInt(ShotSpread*2+1);
			
			for(int i = -ShotSpread; i <= ShotSpread; ++i)
			{
				float Spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
				float a = GetAngle(Direction);
				a += Spreading[i+2];
				float v = 1-(absolute(i)/(float)ShotSpread);
				float Speed = mix((float)GameServer()->Tuning()->m_ShotgunSpeeddiff, 1.0f, v);
				CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_SHOTGUN,
					m_pPlayer->GetCID(),
					ProjStartPos,
					vec2(cosf(a), sinf(a))*Speed,
					(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime),
					1, 0, 0, -1, WEAPON_SHOTGUN);
					
				// pack the Projectile and send it to the client Directly
				CNetObj_Projectile p;
				pProj->FillInfo(&p);
				
				for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
					Msg.AddInt(((int *)&p)[i]);
			}

			Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID());					
			
			GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE);
		} break;

		case WEAPON_GRENADE:
		{
			CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GRENADE,
				m_pPlayer->GetCID(),
				ProjStartPos,
				Direction,
				(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime),
				1, true, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);

			// pack the Projectile and send it to the client Directly
			CNetObj_Projectile p;
			pProj->FillInfo(&p);
			
			CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE);
			Msg.AddInt(1);
			for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++)
				Msg.AddInt(((int *)&p)[i]);
			Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID());
			
			GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
		} break;
		
		case WEAPON_RIFLE:
		{
			new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID());
			GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
		} break;
		
		case WEAPON_NINJA:
		{
			// reset Hit objects
			m_NumObjectsHit = 0;
			
			m_AttackTick = Server()->Tick();
			m_Ninja.m_ActivationDir = Direction;
			m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;

			GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE);
		} break;
		
	}
	
	m_AttackTick = Server()->Tick();
	
	if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // -1 == unlimited
		m_aWeapons[m_ActiveWeapon].m_Ammo--;
	
	if(!m_ReloadTimer)
		m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000;
}
Beispiel #25
0
void CProjectile::Reset()
{
	GameServer()->m_World.DestroyEntity(this);
}
Beispiel #26
0
void CCharacter::TickDefered()
{
	// advance the dummy
	{
		CWorldCore TempWorld;
		m_ReckoningCore.Init(&TempWorld, GameServer()->Collision());
		m_ReckoningCore.Tick(false);
		m_ReckoningCore.Move();
		m_ReckoningCore.Quantize();
	}
	
	//lastsentcore
	vec2 StartPos = m_Core.m_Pos;
	vec2 StartVel = m_Core.m_Vel;
	bool StuckBefore = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
	
	m_Core.Move();
	bool StuckAfterMove = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
	m_Core.Quantize();
	bool StuckAfterQuant = GameServer()->Collision()->TestBox(m_Core.m_Pos, vec2(28.0f, 28.0f));
	m_Pos = m_Core.m_Pos;
	
	if(!StuckBefore && (StuckAfterMove || StuckAfterQuant))
	{
		// Hackish solution to get rid of strict-aliasing warning
		union
		{
			float f;
			unsigned u;
		}StartPosX, StartPosY, StartVelX, StartVelY;

		StartPosX.f = StartPos.x;
		StartPosY.f = StartPos.y;
		StartVelX.f = StartVel.x;
		StartVelY.f = StartVel.y;

		char aBuf[256];
		str_format(aBuf, sizeof(aBuf), "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x", 
			StuckBefore,
			StuckAfterMove,
			StuckAfterQuant,
			StartPos.x, StartPos.y,
			StartVel.x, StartVel.y,
			StartPosX.u, StartPosY.u,
			StartVelX.u, StartVelY.u);
		GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
	}

	int Events = m_Core.m_TriggeredEvents;
	int Mask = CmaskAllExceptOne(m_pPlayer->GetCID());
	
	if(Events&COREEVENT_GROUND_JUMP) GameServer()->CreateSound(m_Pos, SOUND_PLAYER_JUMP, Mask);
	
	if(Events&COREEVENT_HOOK_ATTACH_PLAYER) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_PLAYER, CmaskAll());
	if(Events&COREEVENT_HOOK_ATTACH_GROUND) GameServer()->CreateSound(m_Pos, SOUND_HOOK_ATTACH_GROUND, Mask);
	if(Events&COREEVENT_HOOK_HIT_NOHOOK) GameServer()->CreateSound(m_Pos, SOUND_HOOK_NOATTACH, Mask);

	
	if(m_pPlayer->GetTeam() == TEAM_SPECTATORS)
	{
		m_Pos.x = m_Input.m_TargetX;
		m_Pos.y = m_Input.m_TargetY;
	}
	
	// update the m_SendCore if needed
	{
		CNetObj_Character Predicted;
		CNetObj_Character Current;
		mem_zero(&Predicted, sizeof(Predicted));
		mem_zero(&Current, sizeof(Current));
		m_ReckoningCore.Write(&Predicted);
		m_Core.Write(&Current);

		// only allow dead reackoning for a top of 3 seconds
		if(m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0)
		{
			m_ReckoningTick = Server()->Tick();
			m_SendCore = m_Core;
			m_ReckoningCore = m_Core;
		}
	}
}
Beispiel #27
0
void CGameControllerOpenFNG::DoInteractions()
{
	DoHookers();

	for(int i = 0; i < MAX_CLIENTS; i++)
	{
		CCharacter *pChr = CHAR(i);
		if (!pChr)
			continue;

		int FrzTicks = pChr->GetFreezeTicks();
		int Col = GameServer()->Collision()->GetCollisionAt(pChr->m_Pos.x, pChr->m_Pos.y);
		if (Col == TILE_SHRINE_ALL || Col == TILE_SHRINE_RED || Col == TILE_SHRINE_BLUE)
		{
			if (FrzTicks > 0 && m_aLastInteraction[i] < 0)
				pChr->Freeze(FrzTicks = 0);

			bool WasSacrificed = false;
			if (FrzTicks > 0)
			{
				int ShrineTeam = Col == TILE_SHRINE_RED ? TEAM_RED : Col == TILE_SHRINE_BLUE ? TEAM_BLUE : -1;
				HandleSacr(m_aLastInteraction[i], i, ShrineTeam);
				WasSacrificed = true;
			}

			pChr->Die(pChr->GetPlayer()->GetCID(), WEAPON_WORLD, WasSacrificed);
		}


		if (FrzTicks > 0)
		{
			if ((FrzTicks+1) % TS == 0) {
				int mask = -1;
				if (!CFG(MeltShowAll))
					mask = (int)~m_aCltMask[1-(pChr->GetPlayer()->GetTeam()&1)];

				GS->CreateDamageInd(pChr->m_Pos, 0, (FrzTicks+1) / TS, mask);

				if (CFG(ClickyMelt))
				{
					mask = -1;
					if (CFG(ClickyMelt) == 1)
						mask = (int)m_aCltMask[1-(pChr->GetPlayer()->GetTeam()&1)];

					GS->CreateSound(pChr->m_Pos, SOUND_WEAPON_NOAMMO, mask);
				}
			}

			if (FrzTicks == 1 && CFG(MeltSafeticks))
				pChr->SetEmote(EMOTE_SURPRISE, TICK + CFG(MeltSafeticks) + 1);

			m_aMoltenBy[i] = -1;

			if (m_aFrozenBy[i] != -1)
				continue;

			int Killer = pChr->WasFrozenBy();
			if (Killer < 0) //may happen then the gods are not pleased
			{
				m_aFrozenBy[i] = -1;
				continue;
			}

			m_aFrozenBy[i] = Killer;
			
			HandleFreeze(Killer, i);
		}
		else
		{
			m_aFrozenBy[i] = -1;

			int Melter = pChr->WasMoltenBy();
			if (Melter < 0)
				m_aMoltenBy[i] = -1;
			
			if (Melter == m_aMoltenBy[i])
				continue;

			m_aMoltenBy[i] = Melter;

			HandleMelt(Melter, i);
		}
	}
}
Beispiel #28
0
bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
{
	m_Core.m_Vel += Force;
	
	if(GameServer()->m_pController->IsFriendlyFire(m_pPlayer->GetCID(), From) && !g_Config.m_SvTeamdamage)
		return false;

	// m_pPlayer only inflicts half damage on self
	if(From == m_pPlayer->GetCID())
		Dmg = max(1, Dmg/2);

	m_DamageTaken++;

	// create healthmod indicator
	if(Server()->Tick() < m_DamageTakenTick+25)
	{
		// make sure that the damage indicators doesn't group together
		GameServer()->CreateDamageInd(m_Pos, m_DamageTaken*0.25f, Dmg);
	}
	else
	{
		m_DamageTaken = 0;
		GameServer()->CreateDamageInd(m_Pos, 0, Dmg);
	}

	if(Dmg)
	{
		if(m_Armor)
		{
			if(Dmg > 1)
			{
				m_Health--;
				Dmg--;
			}
			
			if(Dmg > m_Armor)
			{
				Dmg -= m_Armor;
				m_Armor = 0;
			}
			else
			{
				m_Armor -= Dmg;
				Dmg = 0;
			}
		}
		
		m_Health -= Dmg;
	}

	m_DamageTakenTick = Server()->Tick();

	// do damage Hit sound
	if(From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From])
		GameServer()->CreateSound(GameServer()->m_apPlayers[From]->m_ViewPos, SOUND_HIT, CmaskOne(From));

	// check for death
	if(m_Health <= 0)
	{
		Die(From, Weapon);
		
		// set attacker's face to happy (taunt!)
		if (From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From])
		{
			CCharacter *pChr = GameServer()->m_apPlayers[From]->GetCharacter();
			if (pChr)
			{
				pChr->m_EmoteType = EMOTE_HAPPY;
				pChr->m_EmoteStop = Server()->Tick() + Server()->TickSpeed();
			}
		}
	
		return false;
	}

	if (Dmg > 2)
		GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG);
	else
		GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_SHORT);

	m_EmoteType = EMOTE_PAIN;
	m_EmoteStop = Server()->Tick() + 500 * Server()->TickSpeed() / 1000;

	return true;
}
void IGameController::ResetGame()
{
	GameServer()->m_World.m_ResetRequested = true;
}
Beispiel #30
0
void CServer::DoSnapshot()
{
	GameServer()->OnPreSnap();

	// create snapshot for demo recording
	if(m_DemoRecorder.IsRecording())
	{
		char aData[CSnapshot::MAX_SIZE];
		int SnapshotSize;

		// build snap and possibly add some messages
		m_SnapshotBuilder.Init();
		GameServer()->OnSnap(-1);
		SnapshotSize = m_SnapshotBuilder.Finish(aData);

		// write snapshot
		m_DemoRecorder.RecordSnapshot(Tick(), aData, SnapshotSize);
	}

	// create snapshots for all clients
	for(int i = 0; i < MAX_CLIENTS; i++)
	{
		// client must be ingame to recive snapshots
		if(m_aClients[i].m_State != CClient::STATE_INGAME)
			continue;

		// this client is trying to recover, don't spam snapshots
		if(m_aClients[i].m_SnapRate == CClient::SNAPRATE_RECOVER && (Tick()%50) != 0)
			continue;

		// this client is trying to recover, don't spam snapshots
		if(m_aClients[i].m_SnapRate == CClient::SNAPRATE_INIT && (Tick()%10) != 0)
			continue;

		{
			char aData[CSnapshot::MAX_SIZE];
			CSnapshot *pData = (CSnapshot*)aData;	// Fix compiler warning for strict-aliasing
			char aDeltaData[CSnapshot::MAX_SIZE];
			char aCompData[CSnapshot::MAX_SIZE];
			int SnapshotSize;
			int Crc;
			static CSnapshot EmptySnap;
			CSnapshot *pDeltashot = &EmptySnap;
			int DeltashotSize;
			int DeltaTick = -1;
			int DeltaSize;

			m_SnapshotBuilder.Init();

			GameServer()->OnSnap(i);

			// finish snapshot
			SnapshotSize = m_SnapshotBuilder.Finish(pData);
			Crc = pData->Crc();

			// remove old snapshos
			// keep 3 seconds worth of snapshots
			m_aClients[i].m_Snapshots.PurgeUntil(m_CurrentGameTick-SERVER_TICK_SPEED*3);

			// save it the snapshot
			m_aClients[i].m_Snapshots.Add(m_CurrentGameTick, time_get(), SnapshotSize, pData, 0);

			// find snapshot that we can preform delta against
			EmptySnap.Clear();

			{
				DeltashotSize = m_aClients[i].m_Snapshots.Get(m_aClients[i].m_LastAckedSnapshot, 0, &pDeltashot, 0);
				if(DeltashotSize >= 0)
					DeltaTick = m_aClients[i].m_LastAckedSnapshot;
				else
				{
					// no acked package found, force client to recover rate
					if(m_aClients[i].m_SnapRate == CClient::SNAPRATE_FULL)
						m_aClients[i].m_SnapRate = CClient::SNAPRATE_RECOVER;
				}
			}

			// create delta
			DeltaSize = m_SnapshotDelta.CreateDelta(pDeltashot, pData, aDeltaData);

			if(DeltaSize)
			{
				// compress it
				int SnapshotSize;
				const int MaxSize = MAX_SNAPSHOT_PACKSIZE;
				int NumPackets;

				SnapshotSize = CVariableInt::Compress(aDeltaData, DeltaSize, aCompData);
				NumPackets = (SnapshotSize+MaxSize-1)/MaxSize;

				for(int n = 0, Left = SnapshotSize; Left; n++)
				{
					int Chunk = Left < MaxSize ? Left : MaxSize;
					Left -= Chunk;

					if(NumPackets == 1)
					{
						CMsgPacker Msg(NETMSG_SNAPSINGLE);
						Msg.AddInt(m_CurrentGameTick);
						Msg.AddInt(m_CurrentGameTick-DeltaTick);
						Msg.AddInt(Crc);
						Msg.AddInt(Chunk);
						Msg.AddRaw(&aCompData[n*MaxSize], Chunk);
						SendMsgEx(&Msg, MSGFLAG_FLUSH, i, true);
					}
					else
					{
						CMsgPacker Msg(NETMSG_SNAP);
						Msg.AddInt(m_CurrentGameTick);
						Msg.AddInt(m_CurrentGameTick-DeltaTick);
						Msg.AddInt(NumPackets);
						Msg.AddInt(n);
						Msg.AddInt(Crc);
						Msg.AddInt(Chunk);
						Msg.AddRaw(&aCompData[n*MaxSize], Chunk);
						SendMsgEx(&Msg, MSGFLAG_FLUSH, i, true);
					}
				}
			}
			else
			{
				CMsgPacker Msg(NETMSG_SNAPEMPTY);
				Msg.AddInt(m_CurrentGameTick);
				Msg.AddInt(m_CurrentGameTick-DeltaTick);
				SendMsgEx(&Msg, MSGFLAG_FLUSH, i, true);
			}
		}
	}

	GameServer()->OnPostSnap();
}