void CPlayer::StartInfection(bool force)
{
	if(!force && IsInfected())
		return;
	
	
	if(!IsInfected())
	{
		m_InfectionTick = Server()->Tick();
	}
	
	int random = rand()%8;
	
	if(random == 0)
	{
		SetClass(PLAYERCLASS_WITCH);
		
		if(GetClass() == PLAYERCLASS_WITCH)
		{
			GameServer()->SendBroadcast("A witch is coming !", -1);
			GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE);
		}
	}
	else if(random <= 2) SetClass(PLAYERCLASS_HUNTER);
	else if(random <= 4) SetClass(PLAYERCLASS_BOOMER);
	else SetClass(PLAYERCLASS_ZOMBIE);
}
void CPlayer::StartInfection(bool force)
{
	if(!force && IsInfected())
		return;
	
	
	if(!IsInfected())
	{
		m_InfectionTick = Server()->Tick();
	}
	
	int c = GameServer()->m_pController->ChooseInfectedClass(this);
	
	SetClass(c);
}
void CPlayer::StartInfection()
{
	if(IsInfected())
		return;
	
	int random = rand()%4;
	
	if(random == 0) SetClass(PLAYERCLASS_BOOMER);
	else if(random == 1) SetClass(PLAYERCLASS_HUNTER);
	else SetClass(PLAYERCLASS_ZOMBIE);
}
/*this function sets the vector of infections*/
void Host::InfectWith(Virus& newVirus, double simulationTime, int maxNumberInfections) //function of the host receiving a new virus
{
	//cout << "do i get stuck here??? InfectWith()"<<endl;
	Infection newInfection;
	list<Infection>::iterator it;
	list<Infection>::iterator end = infections.end();

	if(!IsInfected()) // if the host is NOT infected yet
	{
		newInfection.TransmitInfection(newVirus,simulationTime);//set the parameters to the new infection!
		infections.push_back(newInfection);
	}
	else //but if the host IS infected with some viruses
	{
		if(infections.size()<maxNumberInfections) //check first whether it is already at its maximum
		{
			//*
			bool isInTheInfectionsList = false;
			for (it = infections.begin(); it != end; it++)
			{
				if(!it->IsPathogenNew(newVirus)) // if the virus is not new  (i.e. as incubating, acute, chronic or immune) ignore it
				{
					isInTheInfectionsList=true;
				}
			}
			if(!isInTheInfectionsList)
			{
				newInfection.TransmitInfection(newVirus,simulationTime);//set the parameters to the new infection!
				infections.push_back(newInfection);
			}
			/*
			 int howManyInfections = 0;
			 for (it = infections.begin(); it != end; it++)
			 {
			 if(!it->IsPathogenNew(newVirus)) // if the virus is already there (i.e. as incubating, acute, chronic or immune) ignore it
			 continue;
			 else //but if it's not the same, keep track of how many infections are different from the new one
			 howManyInfections++;
			 }
			 
			 if(howManyInfections == infections.size()) // if the new virus is different from ALL infections present in that host
			 {
			 newInfection.TransmitInfection(newVirus,simulationTime);//set the parameters to the new infection!
			 infections.push_back(newInfection);
			 }
			 //*/
		}
	}
}
void Host:: InfectWithMoreWildType(Virus& newVirus, double simulationTime, int maxNumberInfections) //function of the host receiving a new virus
{
	//cout << "do i get stuck here??? InfectWith()"<<endl;
	Infection newInfection;
	list<Infection>::iterator it;
	list<Infection>::iterator end = infections.end();

	if(!IsInfected()) // if the host is NOT infected yet
	{
		newInfection.TransmitInfection(newVirus,simulationTime);//set the parameters to the new infection!
		infections.push_back(newInfection);
	}
	else //but if the host IS infected with some viruses
	{
		if(infections.size()<maxNumberInfections) //check first whether it is already at its maximum
		{
			if(newVirus.IsWildType())
			{
				newInfection.TransmitInfection(newVirus,simulationTime);//set the parameters to the new infection!
				infections.push_back(newInfection);
			}
		}
	}
}
void CPlayer::Tick()
{
#ifdef CONF_DEBUG
	if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
#endif
	if(!Server()->ClientIngame(m_ClientID))
		return;

	Server()->SetClientScore(m_ClientID, m_Score);
	Server()->SetClientNbRound(m_ClientID, m_NbRound);
	Server()->SetClientNbInfection(m_ClientID, m_NbInfection);
	Server()->SetClientLanguage(m_ClientID, m_Language);

	// 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(!GameServer()->m_World.m_Paused)
	{
		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_Spawning = true;

		if(m_pCharacter)
		{
			if(m_pCharacter->IsAlive())
			{
				m_ViewPos = m_pCharacter->m_Pos;
			}
			else
			{
				m_pCharacter->Destroy();
				delete m_pCharacter;
				m_pCharacter = 0;
			}
		}
		else if(m_Spawning && m_RespawnTick <= Server()->Tick())
			TryRespawn();
		
		if(!IsInfected()) m_HumanTime++;
	}
	else
	{
		++m_RespawnTick;
		++m_DieTick;
		++m_ScoreStartTick;
		++m_LastActionTick;
		++m_TeamChangeTick;
 	}
}
void CPlayer::Snap(int SnappingClient)
{
#ifdef CONF_DEBUG
	if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
#endif
	if(!Server()->ClientIngame(m_ClientID))
		return;

	CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, m_ClientID, sizeof(CNetObj_ClientInfo)));
	if(!pClientInfo)
		return;

	StrToInts(&pClientInfo->m_Name0, 4, Server()->ClientName(m_ClientID));
	
	int SnapScoreMode = PLAYERSCOREMODE_NORMAL;
	if(GameServer()->m_apPlayers[SnappingClient])
	{
		SnapScoreMode = GameServer()->m_apPlayers[SnappingClient]->GetScoreMode();
	}
	
/* INFECTION MODIFICATION STRAT ***************************************/
	int PlayerInfoScore = 0;
	
	if(GetTeam() == TEAM_SPECTATORS)
	{
		StrToInts(&pClientInfo->m_Clan0, 3, Server()->ClientClan(m_ClientID));
	}
	else
	{
		if(SnapScoreMode == PLAYERSCOREMODE_ROUNDSCORE)
		{
			char aBuf[512];
			str_format(aBuf, sizeof(aBuf), "%s%i pt", (m_ScoreRound > 0 ? "+" : ""), m_ScoreRound);
			
			StrToInts(&pClientInfo->m_Clan0, 3, aBuf);
			
			PlayerInfoScore = m_ScoreRound;
		}
		else if(SnapScoreMode == PLAYERSCOREMODE_TIME)
		{
			float RoundDuration = static_cast<float>(m_HumanTime/((float)Server()->TickSpeed()))/60.0f;
			int Minutes = static_cast<int>(RoundDuration);
			int Seconds = static_cast<int>((RoundDuration - Minutes)*60.0f);
			
			char aBuf[512];
			str_format(aBuf, sizeof(aBuf), "%i:%s%i min", Minutes,((Seconds < 10) ? "0" : ""), Seconds);
			StrToInts(&pClientInfo->m_Clan0, 3, aBuf);
			
			PlayerInfoScore = m_HumanTime/Server()->TickSpeed();
		}
		//~ else if(SnapScoreMode == PLAYERSCOREMODE_NBROUND)
		//~ {
			//~ char aBuf[512];
			//~ str_format(aBuf, sizeof(aBuf), "%i round%s", m_NbRound, (m_NbRound >1 ? "s" : ""));
			//~ 
			//~ StrToInts(&pClientInfo->m_Clan0, 3, aBuf);
			//~ 
			//~ PlayerInfoScore = m_NbRound;
		//~ }
		else if(SnapScoreMode == PLAYERSCOREMODE_SCOREPERROUND)
		{
			float ScorePerRound = static_cast<float>(m_Score)/static_cast<float>(m_NbRound);
			
			char aBuf[512];
			str_format(aBuf, sizeof(aBuf), "%.2f pt/rnd", ScorePerRound);
			
			StrToInts(&pClientInfo->m_Clan0, 3, aBuf);
			
			PlayerInfoScore = static_cast<int>(ScorePerRound*10);
		}
		else if(SnapScoreMode == PLAYERSCOREMODE_INFECTION)
		{
			char aBuf[512];
			str_format(aBuf, sizeof(aBuf), "%i inf", m_NbInfection);
			
			StrToInts(&pClientInfo->m_Clan0, 3, aBuf);
			
			PlayerInfoScore = m_NbInfection;
		}
		else if(SnapScoreMode == PLAYERSCOREMODE_INFECTIONPERROUND)
		{
			float InfPerRound = static_cast<float>(m_NbInfection)/static_cast<float>(m_NbRound);
			
			char aBuf[512];
			str_format(aBuf, sizeof(aBuf), "%.2f inf/rnd", InfPerRound);
			
			StrToInts(&pClientInfo->m_Clan0, 3, aBuf);
			
			PlayerInfoScore = static_cast<int>(InfPerRound*10);
		}
		else
		{
			switch(GetClass())
			{
				case PLAYERCLASS_ENGINEER:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Engineer*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Engineer");
					break;
				case PLAYERCLASS_SOLDIER:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Soldier*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Soldier");
					break;
				case PLAYERCLASS_SCIENTIST:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Scientist*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Scientist");
					break;
				case PLAYERCLASS_MEDIC:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Medic*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Medic");
					break;
				case PLAYERCLASS_NINJA:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Ninja*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Ninja");
					break;
				case PLAYERCLASS_SMOKER:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Smoker*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Smoker");
					break;
				case PLAYERCLASS_BOOMER:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Boomer*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Boomer");
					break;
				case PLAYERCLASS_HUNTER:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Hunter*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Hunter");
					break;
				case PLAYERCLASS_GHOST:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Ghost*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Ghost");
					break;
				case PLAYERCLASS_UNDEAD:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Undead*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Undead");
					break;
				case PLAYERCLASS_WITCH:
					if(m_WinAsHuman) StrToInts(&pClientInfo->m_Clan0, 3, "*Witch*");
					else StrToInts(&pClientInfo->m_Clan0, 3, "Witch");
					break;
				default:
					StrToInts(&pClientInfo->m_Clan0, 3, "");
			}
			
			PlayerInfoScore = m_Score;
		}
	}
	
	pClientInfo->m_Country = Server()->ClientCountry(m_ClientID);

	if(
		GameServer()->m_apPlayers[SnappingClient] && !IsInfected() &&
		(
			(Server()->GetClientCustomSkin(SnappingClient) == 1 && SnappingClient == GetCID()) ||
			(Server()->GetClientCustomSkin(SnappingClient) == 2)
		)
	)
	{
		StrToInts(&pClientInfo->m_Skin0, 6, m_TeeInfos.m_CustomSkinName);
	}
	else StrToInts(&pClientInfo->m_Skin0, 6, m_TeeInfos.m_SkinName);
	
	pClientInfo->m_UseCustomColor = m_TeeInfos.m_UseCustomColor;
	pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
	pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
/* INFECTION MODIFICATION END *****************************************/

	CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, m_ClientID, sizeof(CNetObj_PlayerInfo)));
	if(!pPlayerInfo)
		return;

	pPlayerInfo->m_Latency = SnappingClient == -1 ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID];
	pPlayerInfo->m_Local = 0;
	pPlayerInfo->m_ClientID = m_ClientID;
/* INFECTION MODIFICATION START ***************************************/
	pPlayerInfo->m_Score = PlayerInfoScore;
/* INFECTION MODIFICATION END *****************************************/
	pPlayerInfo->m_Team = m_Team;

	if(m_ClientID == SnappingClient)
		pPlayerInfo->m_Local = 1;

	if(m_ClientID == SnappingClient && m_Team == TEAM_SPECTATORS)
	{
		CNetObj_SpectatorInfo *pSpectatorInfo = static_cast<CNetObj_SpectatorInfo *>(Server()->SnapNewItem(NETOBJTYPE_SPECTATORINFO, m_ClientID, sizeof(CNetObj_SpectatorInfo)));
		if(!pSpectatorInfo)
			return;

		pSpectatorInfo->m_SpectatorID = m_SpectatorID;
		pSpectatorInfo->m_X = m_ViewPos.x;
		pSpectatorInfo->m_Y = m_ViewPos.y;
	}
}
bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
{
	m_Core.m_Vel += Force;

/* INFECTION MODIFICATION START ***************************************/
	CPlayer* pKillerPlayer = GameServer()->m_apPlayers[From];
	if(pKillerPlayer && pKillerPlayer->IsInfected() == IsInfected() && From != m_pPlayer->GetCID())
		return false;
/* INFECTION MODIFICATION END *****************************************/

	// 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])
	{
		int Mask = CmaskOne(From);
		for(int i = 0; i < MAX_CLIENTS; i++)
		{
			if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS && GameServer()->m_apPlayers[i]->m_SpectatorID == From)
				Mask |= CmaskOne(i);
		}
		GameServer()->CreateSound(GameServer()->m_apPlayers[From]->m_ViewPos, SOUND_HIT, Mask);
	}
	
/* INFECTION MODIFICATION START ***************************************/
	if(GameServer()->m_apPlayers[From]->IsInfected() && !IsInfected())
	{
		if(!(GameServer()->m_apPlayers[From]->GetClass() == PLAYERCLASS_ZOMBIE && Weapon == WEAPON_NINJA))
		{
			m_pPlayer->StartInfection();
		
			CNetMsg_Sv_KillMsg Msg;
			Msg.m_Killer = From;
			Msg.m_Victim = m_pPlayer->GetCID();
			Msg.m_Weapon = WEAPON_HAMMER;
			Msg.m_ModeSpecial = 0;
			Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, -1);
		}
	}
/* INFECTION MODIFICATION END *****************************************/

	// 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 CCharacter::FireWeapon()
{
	if(m_ReloadTimer != 0)
		return;

/* INFECTION MODIFICATION START ***************************************/
	if(GetClass() == PLAYERCLASS_NONE)
		return;
/* INFECTION MODIFICATION END *****************************************/

	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;
		if(m_LastNoAmmoSound+Server()->TickSpeed() <= Server()->Tick())
		{
			GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO);
			m_LastNoAmmoSound = Server()->Tick();
		}
		return;
	}

	vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f;

	switch(m_ActiveWeapon)
	{
		case WEAPON_HAMMER:
		{
/* INFECTION MODIFICATION START ***************************************/
			if(GetClass() == PLAYERCLASS_ENGINEER)
			{
				if(m_pBarrier)
				{
					GameServer()->m_World.DestroyEntity(m_pBarrier);
					m_pBarrier = 0;
				}
					
				if(m_FirstShot)
				{
					m_FirstShot = false;
					m_FirstShotCoord = m_Pos;
				}
				else if(distance(m_FirstShotCoord, m_Pos) > 10.0)
				{
					m_FirstShot = true;
					
					CBarrier *pBarrier = new CBarrier(GameWorld(), m_FirstShotCoord, m_Pos, m_pPlayer->GetCID());
					m_pBarrier = pBarrier;
					
					GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
				}
			}
			else if(GetClass() == PLAYERCLASS_SOLDIER)
			{
				if(m_pBomb)
				{
					m_pBomb->Explode();
				}
				else
				{
					CBomb *pBomb = new CBomb(GameWorld(), ProjStartPos, m_pPlayer->GetCID());
					m_pBomb = pBomb;
					
					GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
				}
					
			}
			else if(GetClass() == PLAYERCLASS_BOOMER)
			{
				Die(m_pPlayer->GetCID(), WEAPON_WORLD);
			}
			else
			{
/* INFECTION MODIFICATION END *****************************************/
				// 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);
					
/* INFECTION MODIFICATION START ***************************************/
					if(IsInfected() && pTarget->IsInfected())
					{
						pTarget->IncreaseHealth(2);
						pTarget->IncreaseArmor(2);
					}
					else
					{
						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);
					}
/* INFECTION MODIFICATION END *****************************************/
					Hits++;
				}

				// if we Hit anything, we have to wait for the reload
				if(Hits)
					m_ReloadTimer = Server()->TickSpeed()/3;
					
/* INFECTION MODIFICATION START ***************************************/
			}
/* INFECTION MODIFICATION END *****************************************/

		} 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_Ninja.m_ActivationDir = Direction;
			m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000;
			m_Ninja.m_OldVelAmount = length(m_Core.m_Vel);

			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;
}
    void StiRelationshipStartReporter::onNewRelationship(IRelationship* relationship)
    {
        LOG_DEBUG_F("%s: rel id = %d, male id = %d, female id = %d\n", __FUNCTION__,
                    relationship->GetSuid().data,
                    relationship->MalePartner()->GetSuid().data,
                    relationship->FemalePartner()->GetSuid().data );
        // TODO - set the relationship suid in the relationship code (or relationship manager)
        auto male_partner = relationship->MalePartner();
        auto female_partner    = relationship->FemalePartner();

        if (male_partner && female_partner)
        {
            // get set of relationships in order to count the number for each type
            RelationshipSet_t &his_relationships =  male_partner->GetRelationships();
            RelationshipSet_t &her_relationships =  female_partner->GetRelationships();

            RelationshipStartInfo info;
            info.id                 = relationship->GetSuid().data;
            info.start_time         = relationship->GetStartTime();
            info.scheduled_end_time = relationship->GetScheduledEndTime();
            info.relationship_type  = (unsigned int)relationship->GetType();

            IIndividualHumanEventContext* individual = nullptr;

            if (male_partner->QueryInterface(GET_IID(IIndividualHumanEventContext), (void**)&individual) != s_OK)
            {
                throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "male_partner", "IIndividualHumanContext", "IIndividualHumanSTI*" );
            }

            // --------------------------------------------------------
            // --- Assuming that the individuals in a relationship
            // --- must be in the same node.
            //release_assert( false );
            // --------------------------------------------------------
            info.original_node_id = relationship->GetOriginalNodeId();
            info.current_node_id  = individual->GetNodeEventContext()->GetNodeContext()->GetExternalID();

            info.participant_a.id                                = male_partner->GetSuid().data;
            info.participant_a.is_infected                       = male_partner->IsInfected();
            info.participant_a.gender                            = individual->GetGender();
            info.participant_a.age                               = individual->GetAge()/365;
            info.participant_a.active_relationship_count         = male_partner->GetRelationships().size();
            info.participant_a.props                             = GetPropertyString( individual ) ;

            for( int i = 0 ; i < RelationshipType::COUNT ; ++i )
            {
                info.participant_a.relationship_count[ i ] = 0 ;
            }

            for (auto relationship : his_relationships)
            {
                info.participant_a.relationship_count[ int(relationship->GetType()) ]++;
            }

            info.participant_a.cumulative_lifetime_relationships = male_partner->GetLifetimeRelationshipCount();
            info.participant_a.relationships_in_last_six_months  = male_partner->GetLast6MonthRels();
            info.participant_a.extrarelational_flags             = male_partner->GetExtrarelationalFlags();
            info.participant_a.is_circumcised                    = male_partner->IsCircumcised();
            info.participant_a.has_sti                           = male_partner->HasSTICoInfection();
            info.participant_a.is_superspreader                  = male_partner->IsBehavioralSuperSpreader();


            if (female_partner->QueryInterface(GET_IID(IIndividualHumanEventContext), (void**)&individual) != s_OK)
            {
                throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "female_partner", "IIndividualHumanContext", "IIndividualHumanSTI*" );
            }

            info.participant_b.id                                = female_partner->GetSuid().data;
            info.participant_b.is_infected                       = female_partner->IsInfected();
            info.participant_b.gender                            = individual->GetGender();
            info.participant_b.age                               = individual->GetAge()/365;
            info.participant_b.active_relationship_count         = female_partner->GetRelationships().size();
            info.participant_b.props                             = GetPropertyString( individual ) ;

            for( int i = 0 ; i < RelationshipType::COUNT ; ++i )
            {
                info.participant_b.relationship_count[ i ] = 0 ;
            }

            for (auto relationship : her_relationships)
            {
                info.participant_b.relationship_count[ int(relationship->GetType()) ]++;
            }

            info.participant_b.cumulative_lifetime_relationships = female_partner->GetLifetimeRelationshipCount();
            info.participant_b.relationships_in_last_six_months  = female_partner->GetLast6MonthRels();
            info.participant_b.extrarelational_flags             = female_partner->GetExtrarelationalFlags();
            info.participant_b.is_circumcised                    = female_partner->IsCircumcised();
            info.participant_b.has_sti                           = female_partner->HasSTICoInfection();
            info.participant_b.is_superspreader                  = female_partner->IsBehavioralSuperSpreader();

            CollectOtherData( info.id, male_partner, female_partner );

            report_data.push_back(info);
        }
        else
        {
            LOG_WARN_F( "%s: one or more partners of new relationship %d has already migrated\n", __FUNCTION__, relationship->GetSuid().data );
        }
    }
Exemple #11
0
    void IndividualHumanPy::Update( float currenttime, float dt)
    {
#ifdef ENABLE_PYTHON_FEVER
        static auto pFunc = PythonSupportPtr->IdmPyInit( PythonSupport::SCRIPT_PYTHON_FEVER.c_str(), "update" );
        if( pFunc )
        {
            // pass individual id AND dt
            static PyObject * vars = PyTuple_New(2);
            vars = Py_BuildValue( "ll", GetSuid().data, int(dt) );
            auto pyVal = PyObject_CallObject( pFunc, vars );
            if( pyVal != nullptr )
            {
                char * state = "UNSET";
                PyArg_ParseTuple(pyVal,"si",&state, &state_changed ); //o-> pyobject |i-> int|s-> char*
                state_to_report = state;
            }
            else
            {
                state_to_report = "D";
            }
#if !defined(_WIN32) || !defined(_DEBUG)
            Py_DECREF(pyVal);
#endif
            PyErr_Print();
        }
        LOG_DEBUG_F( "state_to_report for individual %d = %s; Infected = %d, change = %d.\n", GetSuid().data, state_to_report.c_str(), IsInfected(), state_changed );

        if( state_to_report == "S" && state_changed && GetInfections().size() > 0 )
        {
            LOG_DEBUG_F( "[Update] Somebody cleared their infection.\n" );
            // ClearInfection
            auto inf = GetInfections().front();
            IInfectionPy * inf_pydemo  = NULL;
            if (s_OK != inf->QueryInterface(GET_IID(IInfectionPy ), (void**)&inf_pydemo) )
            {
                throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "inf", "IInfectionPy ", "Infection" );
            }
            // get InfectionPy pointer
            inf_pydemo->Clear();
        }
        else if( state_to_report == "D" && state_changed )
        {
            LOG_INFO_F( "[Update] Somebody died from their infection.\n" );
        }
#endif
        return IndividualHuman::Update( currenttime, dt);
    }
void CCharacter::Snap(int SnappingClient)
{
	if(NetworkClipped(SnappingClient))
		return;

/* INFECTION MODIFICATION START ***************************************/
	if(GetClass() == PLAYERCLASS_WITCH)
	{
		CNetObj_Flag *pFlag = (CNetObj_Flag *)Server()->SnapNewItem(NETOBJTYPE_FLAG, m_FlagID, sizeof(CNetObj_Flag));
		if(!pFlag)
			return;

		pFlag->m_X = (int)m_Pos.x;
		pFlag->m_Y = (int)m_Pos.y;
		pFlag->m_Team = TEAM_RED;
	}
/* INFECTION MODIFICATION END ***************************************/

	CNetObj_Character *pCharacter = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, m_pPlayer->GetCID(), sizeof(CNetObj_Character)));
	if(!pCharacter)
		return;
	
	int EmoteNormal = (IsInfected() ? EMOTE_ANGRY : EMOTE_NORMAL);

	// write down the m_Core
	if(!m_ReckoningTick || GameServer()->m_World.m_Paused)
	{
		// no dead reckoning when paused because the client doesn't know
		// how far to perform the reckoning
		pCharacter->m_Tick = 0;
		m_Core.Write(pCharacter);
	}
	else
	{
		pCharacter->m_Tick = m_ReckoningTick;
		m_SendCore.Write(pCharacter);
	}

	// set emote
	if (m_EmoteStop < Server()->Tick())
	{
		m_EmoteType = EmoteNormal;
		m_EmoteStop = -1;
	}

	pCharacter->m_Emote = m_EmoteType;

	pCharacter->m_AmmoCount = 0;
	pCharacter->m_Health = 0;
	pCharacter->m_Armor = 0;

	pCharacter->m_Weapon = m_ActiveWeapon;
	pCharacter->m_AttackTick = m_AttackTick;

	pCharacter->m_Direction = m_Input.m_Direction;

	if(m_pPlayer->GetCID() == SnappingClient || SnappingClient == -1 ||
		(!g_Config.m_SvStrictSpectateMode && m_pPlayer->GetCID() == GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID))
	{
		pCharacter->m_Health = m_Health;
		pCharacter->m_Armor = m_Armor;
		if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0)
			pCharacter->m_AmmoCount = m_aWeapons[m_ActiveWeapon].m_Ammo;
	}

	if(pCharacter->m_Emote == EmoteNormal)
	{
		if(250 - ((Server()->Tick() - m_LastAction)%(250)) < 5)
			pCharacter->m_Emote = EMOTE_BLINK;
	}

	pCharacter->m_PlayerFlags = GetPlayer()->m_PlayerFlags;
}