about summary refs log tree commit diff
path: root/src/game/server/entities/character.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/server/entities/character.cpp')
-rw-r--r--src/game/server/entities/character.cpp124
1 files changed, 100 insertions, 24 deletions
diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp
index 1c76f655..ac5f2f7c 100644
--- a/src/game/server/entities/character.cpp
+++ b/src/game/server/entities/character.cpp
@@ -45,6 +45,7 @@ CCharacter::CCharacter(CGameWorld *pWorld)
 	m_ProximityRadius = ms_PhysSize;
 	m_Health = 0;
 	m_Armor = 0;
+	m_FreezeTicks = 0;
 }
 
 void CCharacter::Reset()
@@ -56,8 +57,30 @@ bool CCharacter::Spawn(CPlayer *pPlayer, vec2 Pos)
 {
 	m_EmoteStop = -1;
 	m_LastAction = -1;
-	m_ActiveWeapon = WEAPON_GUN;
-	m_LastWeapon = WEAPON_HAMMER;
+	
+	/*zCatch */
+	if(GameServer()->m_pController->IsZCatch() && g_Config.m_SvMode == 1)
+	{
+		m_ActiveWeapon = WEAPON_RIFLE;
+		m_LastWeapon = WEAPON_RIFLE;
+	}
+	else if(GameServer()->m_pController->IsZCatch() && g_Config.m_SvMode == 3)
+	{
+		m_ActiveWeapon = WEAPON_HAMMER;
+		m_LastWeapon = WEAPON_HAMMER;
+	}
+	else if(GameServer()->m_pController->IsZCatch() && g_Config.m_SvMode == 4)
+	{
+		m_ActiveWeapon = WEAPON_GRENADE;
+		m_LastWeapon = WEAPON_GRENADE;
+	}
+	else
+	{
+		m_ActiveWeapon = WEAPON_GUN;
+		m_LastWeapon = WEAPON_HAMMER;
+	}
+    /* end zCatch */
+	
 	m_QueuedWeapon = -1;
 
 	m_pPlayer = pPlayer;
@@ -115,16 +138,21 @@ void CCharacter::HandleNinja()
 	if(m_ActiveWeapon != WEAPON_NINJA)
 		return;
 
-	if ((Server()->Tick() - m_Ninja.m_ActivationTick) > (g_pData->m_Weapons.m_Ninja.m_Duration * Server()->TickSpeed() / 1000))
+	/* zCatch */
+	if(GameServer()->m_pController->IsZCatch() == false)
 	{
-		// time's up, return
-		m_aWeapons[WEAPON_NINJA].m_Got = false;
-		m_ActiveWeapon = m_LastWeapon;
+		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;
 
-		SetWeapon(m_ActiveWeapon);
-		return;
+			SetWeapon(m_ActiveWeapon);
+			return;
+		}
 	}
-
+	/* zCatch end*/
+	
 	// force ninja Weapon
 	SetWeapon(WEAPON_NINJA);
 
@@ -444,6 +472,17 @@ void CCharacter::HandleWeapons()
 
 	// ammo regen
 	int AmmoRegenTime = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Ammoregentime;
+	if(GameServer()->m_pController->IsZCatch() && m_aWeapons[m_ActiveWeapon].m_Ammo > -1)
+	{
+		switch(m_ActiveWeapon)
+		{
+			case WEAPON_GUN: AmmoRegenTime = 125*5; break;
+			case WEAPON_GRENADE: AmmoRegenTime = 1000; break;
+			case WEAPON_RIFLE: AmmoRegenTime = 1200; break;
+			case WEAPON_SHOTGUN: AmmoRegenTime = 1000; break;
+		}
+	}
+
 	if(AmmoRegenTime)
 	{
 		// If equipped and not active, regen ammo?
@@ -455,7 +494,7 @@ void CCharacter::HandleWeapons()
 			if ((Server()->Tick() - m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart) >= AmmoRegenTime * Server()->TickSpeed() / 1000)
 			{
 				// Add some ammo
-				m_aWeapons[m_ActiveWeapon].m_Ammo = min(m_aWeapons[m_ActiveWeapon].m_Ammo + 1, 10);
+				m_aWeapons[m_ActiveWeapon].m_Ammo = min(m_aWeapons[m_ActiveWeapon].m_Ammo + 1, (GameServer()->m_pController->IsZCatch()) ? g_Config.m_SvGrenadeBullets : 10);
 				m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart = -1;
 			}
 		}
@@ -499,6 +538,9 @@ void CCharacter::SetEmote(int Emote, int Tick)
 
 void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
 {
+	if(m_FreezeTicks)
+		return;
+
 	// check for changes
 	if(mem_comp(&m_Input, pNewInput, sizeof(CNetObj_PlayerInput)) != 0)
 		m_LastAction = Server()->Tick();
@@ -514,6 +556,9 @@ void CCharacter::OnPredictedInput(CNetObj_PlayerInput *pNewInput)
 
 void CCharacter::OnDirectInput(CNetObj_PlayerInput *pNewInput)
 {
+	if(m_FreezeTicks)
+		return;
+
 	mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
 	mem_copy(&m_LatestInput, pNewInput, sizeof(m_LatestInput));
 
@@ -556,6 +601,23 @@ void CCharacter::Tick()
 	m_Core.m_Input = m_Input;
 	m_Core.Tick(true);
 
+	if(m_FreezeTicks)
+	{
+		if(Server()->Tick() % Server()->TickSpeed() == 0)
+		{
+			GameServer()->CreateDamageInd(m_Pos, 0, m_FreezeTicks/Server()->TickSpeed()+1);
+			GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO);
+		}
+		//Set weapon back to the last one
+		if(m_FreezeTicks == 1)
+			{
+				m_ActiveWeapon = m_LastWeapon;
+				GameServer()->SendBroadcast("", m_pPlayer->GetCID());
+			}
+		m_FreezeTicks--;
+	}
+
+
 	// handle death-tiles and leaving gamelayer
 	if(GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
 		GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
@@ -712,6 +774,8 @@ void CCharacter::Die(int Killer, int Weapon)
 
 	// this is for auto respawn after 3 secs
 	m_pPlayer->m_DieTick = Server()->Tick();
+	// unfreeze the player
+	m_FreezeTicks = 0;
 
 	m_Alive = false;
 	GameServer()->m_World.RemoveEntity(this);
@@ -725,24 +789,27 @@ bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
 
 	if(GameServer()->m_pController->IsFriendlyFire(m_pPlayer->GetCID(), From) && !g_Config.m_SvTeamdamage)
 		return false;
+	
+	/* zCatch */
+	if(GameServer()->m_pController->IsZCatch())
+	{
+		if(From == m_pPlayer->GetCID() || Weapon == WEAPON_GAME)
+			return false;
 
-	// m_pPlayer only inflicts half damage on self
-	if(From == m_pPlayer->GetCID())
-		Dmg = max(1, Dmg/2);
-
-	m_DamageTaken++;
+		if(g_Config.m_SvMode == 4 && Weapon == WEAPON_GRENADE && Dmg < g_Config.m_SvGrenadeMinDamage)
+			return false;
 
-	// 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);
+		m_Health = 0;
+		m_Armor = 0;
 	}
 	else
 	{
-		m_DamageTaken = 0;
-		GameServer()->CreateDamageInd(m_Pos, 0, Dmg);
+		if(From == m_pPlayer->GetCID())
+			Dmg = max(1, Dmg/2);
 	}
+	/* end zCatch */
+	
+	m_DamageTaken++;
 
 	if(Dmg)
 	{
@@ -857,8 +924,8 @@ void CCharacter::Snap(int SnappingClient)
 	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;
+		pCharacter->m_Health = (m_FreezeTicks) ? (m_FreezeTicks/Server()->TickSpeed())/10 : m_Health;
+		pCharacter->m_Armor = (m_FreezeTicks) ? (m_FreezeTicks/Server()->TickSpeed()) % 10 +1 : m_Armor;
 		if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0)
 			pCharacter->m_AmmoCount = m_aWeapons[m_ActiveWeapon].m_Ammo;
 	}
@@ -871,3 +938,12 @@ void CCharacter::Snap(int SnappingClient)
 
 	pCharacter->m_PlayerFlags = GetPlayer()->m_PlayerFlags;
 }
+
+void CCharacter::Freeze(int Ticks)
+{
+	m_FreezeTicks = Ticks;
+	m_LastWeapon = m_ActiveWeapon;
+	m_ActiveWeapon = WEAPON_NINJA;
+	ResetInput();
+	GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG);
+}