| 1873 | } |
| 1874 | |
| 1875 | virtual bool Item(cEntity * a_Entity) override |
| 1876 | { |
| 1877 | if (a_Entity->IsPickup()) |
| 1878 | { |
| 1879 | if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned) |
| 1880 | { |
| 1881 | return false; |
| 1882 | } |
| 1883 | } |
| 1884 | |
| 1885 | Vector3d EntityPos = a_Entity->GetPosition(); |
| 1886 | cBoundingBox bbEntity(EntityPos, a_Entity->GetWidth() / 2, a_Entity->GetHeight()); |
| 1887 | |
| 1888 | if (!m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround |
| 1889 | { |
| 1890 | return false; |
| 1891 | } |
| 1892 | |
| 1893 | Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); |
| 1894 | |
| 1895 | // Work out how far we are from the edge of the TNT's explosive effect |
| 1896 | AbsoluteEntityPos -= m_ExplosionPos; |
| 1897 | |
| 1898 | // All to positive |
| 1899 | AbsoluteEntityPos.x = abs(AbsoluteEntityPos.x); |
| 1900 | AbsoluteEntityPos.y = abs(AbsoluteEntityPos.y); |
| 1901 | AbsoluteEntityPos.z = abs(AbsoluteEntityPos.z); |
| 1902 | |
| 1903 | double FinalDamage = (((1 / AbsoluteEntityPos.x) + (1 / AbsoluteEntityPos.y) + (1 / AbsoluteEntityPos.z)) * 2) * m_ExplosionSize; |
| 1904 | |
| 1905 | // Clip damage values |
| 1906 | if (FinalDamage > a_Entity->GetMaxHealth()) |
| 1907 | FinalDamage = a_Entity->GetMaxHealth(); |
| 1908 | else if (FinalDamage < 0) |
| 1909 | FinalDamage = 0; |
| 1910 | |
| 1911 | if (!a_Entity->IsTNT() && !a_Entity->IsFallingBlock()) // Don't apply damage to other TNT entities and falling blocks, they should be invincible |
| 1912 | { |
| 1913 | a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); |
| 1914 | } |
| 1915 | |
| 1916 | // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() |
| 1917 | Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; |
| 1918 | if (distance_explosion.SqrLength() < 4096.0) |
| 1919 | { |
| 1920 | distance_explosion.Normalize(); |
| 1921 | distance_explosion *= m_ExplosionSize * m_ExplosionSize; |
| 1922 | |
| 1923 | a_Entity->AddSpeed(distance_explosion); |
| 1924 | } |
| 1925 | |
| 1926 | return false; |
| 1927 | } |
| 1928 | |
| 1929 | protected: |
| 1930 | cBoundingBox & m_bbTNT; |
no test coverage detected