virtual bool Item(cEntity * a_Entity) override { if (!a_Entity->IsMob()) // Floaters can only pull mobs not other entities. { return false; } cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); double LineCoeff; eBlockFace Face; EntBox.Expand(m_Floater->GetWidth() / 2, m_Floater->GetHeight() / 2, m_Floater->GetWidth() / 2); if (!EntBox.CalcLineIntersection(m_Pos, m_NextPos, LineCoeff, Face)) { // No intersection whatsoever return false; } if (LineCoeff < m_MinCoeff) { // The entity is closer than anything we've stored so far, replace it as the potential victim m_MinCoeff = LineCoeff; m_HitEntity = a_Entity; } // Don't break the enumeration, we want all the entities return false; }
virtual bool Item(cEntity * a_Entity) override { if ( (a_Entity == m_Projectile) || // Do not check collisions with self (a_Entity->GetUniqueID() == m_Projectile->GetCreatorUniqueID()) // Do not check whoever shot the projectile ) { // Don't check creator only for the first 5 ticks so that projectiles can collide with the creator if (m_Projectile->GetTicksAlive() <= 5) { return false; } } cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); // Instead of colliding the bounding box with another bounding box in motion, we collide an enlarged bounding box with a hairline. // The results should be good enough for our purposes double LineCoeff; eBlockFace Face; EntBox.Expand(m_Projectile->GetWidth() / 2, m_Projectile->GetHeight() / 2, m_Projectile->GetWidth() / 2); if (!EntBox.CalcLineIntersection(m_Pos, m_NextPos, LineCoeff, Face)) { // No intersection whatsoever return false; } if (!a_Entity->IsMob() && !a_Entity->IsMinecart() && !a_Entity->IsPlayer() && !a_Entity->IsBoat()) { // Not an entity that interacts with a projectile return false; } if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) { // A plugin disagreed. return false; } if (LineCoeff < m_MinCoeff) { // The entity is closer than anything we've stored so far, replace it as the potential victim m_MinCoeff = LineCoeff; m_HitEntity = a_Entity; } // Don't break the enumeration, we want all the entities return false; }
virtual bool Item(cEntity * a_Entity) override { if ( (a_Entity == m_Projectile) || // Do not check collisions with self (a_Entity == m_Projectile->GetCreator()) // Do not check whoever shot the projectile ) { // TODO: Don't check creator only for the first 5 ticks // so that arrows stuck in ground and dug up can hurt the player return false; } cBoundingBox EntBox(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); // Instead of colliding the bounding box with another bounding box in motion, we collide an enlarged bounding box with a hairline. // The results should be good enough for our purposes double LineCoeff; eBlockFace Face; EntBox.Expand(m_Projectile->GetWidth() / 2, m_Projectile->GetHeight() / 2, m_Projectile->GetWidth() / 2); if (!EntBox.CalcLineIntersection(m_Pos, m_NextPos, LineCoeff, Face)) { // No intersection whatsoever return false; } // TODO: Some entities don't interact with the projectiles (pickups, falling blocks) if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity)) { // A plugin disagreed. return false; } if (LineCoeff < m_MinCoeff) { // The entity is closer than anything we've stored so far, replace it as the potential victim m_MinCoeff = LineCoeff; m_HitEntity = a_Entity; } // Don't break the enumeration, we want all the entities return false; }