### Refactored bucket code.

```Before:
A shot would calculate its collision approximation rectangle.
A shot would then determine if the player could be hit (invulnerable, friends etc).
A shot would then determine if the player origin was inside a circle,
centered on the shot start position with a radius of the shot movement delta + shot radius + player radius.
A shot would then determine if the player was inside the approximation rectangle.

After:
A shot would determine if a player could be hit (invulnerable, friends etc).
A shot would determine which player origins were inside a circle,
centered between the shot start and end positions with a radius of the shot movement delta / 2 + shot radius + player radius.
If any players were inside the circle, the shot would then calculate its collision approximation rectangle.
A shot would then determine if any circle players were inside the approximation rectangle.

Goal:
By centering the shot nearness circle inbetween the shot start position and shot end position the area of that circle is greatly reduced.
By rearranging the order of operations many of those operations are no longer performed for every shot every frame.```
parent d2be5d5f0958
 ... ... @@ -652,9 +652,6 @@ class CollisionEllipse(CollisionShape): # If the point falls within the rectangle then a more accurate function will be used elsewhere to determine if there is an actual collision def isNearPath(self, point, startPos, endPos, radius, delta, gradients, distanceBetween, offsetCoords, axis): largestRadius = max(self.rx, self.ry) # Could the distance between the start and end sufficient to have reached the fixed point if ((startPos - point)**2 + (startPos - point)**2)**0.5 - radius - delta - largestRadius > 0: return False # Is the object still if delta == 0: return True ... ...
 ... ... @@ -1676,49 +1676,54 @@ class ServerUniverse(Universe): ''' Performs collision checks of all shots with all nearby players. ''' largestRadius = [] for p in self.players: playerRadius = max(p.collision_shape.rx, p.collision_shape.ry) if not playerRadius in largestRadius: largestRadius.append(playerRadius) for shot in list(self.shots): delta = ((shot.oldPos - shot.pos)**2 + (shot.oldPos - shot.pos)**2)**0.5 radius = shot.gun_type.shot_radius gradients = [] distanceBetween = {} offsetCoords = {} axis = [] if shot.oldPos != shot.pos and shot.oldPos != shot.pos: gradientA = (shot.pos - shot.oldPos) / (shot.pos - shot.oldPos) gradientB = -1 / gradientA gradients = [gradientA, gradientB] slopeA = abs(gradientA) / gradientA slopeB = abs(gradientB) / gradientB minPos = shot.oldPos maxPos = shot.pos if shot.pos < shot.oldPos: minPos = shot.pos maxPos = shot.oldPos for playerRadius in largestRadius: multiplierA = (playerRadius + radius) / (1 + gradientA**2)**(1/2) multiplierB = (playerRadius + radius) / (1 + gradientB**2)**(1/2) distanceBetween[playerRadius] = (multiplierB**2 + (gradientB * multiplierB)**2)**(1/2) * 2 adjustedPos = [[maxPos + slopeA * multiplierA, maxPos + abs(gradientA) * multiplierA], [minPos - slopeA * multiplierA, minPos - abs(gradientA) * multiplierA]] offsetCoords[playerRadius] = [[[adjustedPos + multiplierB, adjustedPos + gradientB * multiplierB], [adjustedPos + multiplierB, adjustedPos + gradientB * multiplierB]], [[adjustedPos - multiplierB, adjustedPos - gradientB * multiplierB], [adjustedPos - multiplierB, adjustedPos - gradientB * multiplierB]]] if shot.oldPos != shot.pos or shot.oldPos != shot.pos: for a in range(2): b = (a + 1) % 2 if shot.oldPos[a] == shot.pos[a] and shot.oldPos[b] != shot.pos[b]: axis = [a, b] hitPlayers = [ p for p in self.players if not (p.dead or p.is_invulnerable() and not p.isFriendsWith(shot.originatingPlayer)) and not p in shot.gracePlayers and p.collision_shape.isNearPath(p.pos, shot.oldPos, shot.pos, radius, delta, gradients, distanceBetween, offsetCoords, axis) and shot.checkCollision(p)] centrePos = [shot.oldPos + (shot.pos - shot.oldPos) / 2, shot.oldPos + (shot.pos - shot.oldPos) / 2] largestRadius = [] circlePlayers = [] for player in self.players: if not (player.dead or player.is_invulnerable() and not player.isFriendsWith(shot.originatingPlayer) and not player in shot.gracePlayers): playerRadius = max(player.collision_shape.rx, player.collision_shape.ry) if ((centrePos - player.pos)**2 + (centrePos - player.pos)**2)**(1/2) - delta / 2 - radius - playerRadius <= 0: if not playerRadius in largestRadius: largestRadius.append(playerRadius) circlePlayers.append(player) hitPlayers = [] if len(largestRadius) > 0: gradients = [] distanceBetween = {} offsetCoords = {} axis = [] if shot.oldPos != shot.pos and shot.oldPos != shot.pos: gradientA = (shot.pos - shot.oldPos) / (shot.pos - shot.oldPos) gradientB = -1 / gradientA gradients = [gradientA, gradientB] slopeA = abs(gradientA) / gradientA slopeB = abs(gradientB) / gradientB minPos = shot.oldPos maxPos = shot.pos if shot.pos < shot.oldPos: minPos = shot.pos maxPos = shot.oldPos for playerRadius in largestRadius: multiplierA = (playerRadius + radius) / (1 + gradientA**2)**(1/2) multiplierB = (playerRadius + radius) / (1 + gradientB**2)**(1/2) distanceBetween[playerRadius] = (multiplierB**2 + (gradientB * multiplierB)**2)**(1/2) * 2 adjustedPos = [[maxPos + slopeA * multiplierA, maxPos + abs(gradientA) * multiplierA], [minPos - slopeA * multiplierA, minPos - abs(gradientA) * multiplierA]] offsetCoords[playerRadius] = [[[adjustedPos + multiplierB, adjustedPos + gradientB * multiplierB], [adjustedPos + multiplierB, adjustedPos + gradientB * multiplierB]], [[adjustedPos - multiplierB, adjustedPos - gradientB * multiplierB], [adjustedPos - multiplierB, adjustedPos - gradientB * multiplierB]]] if shot.oldPos != shot.pos or shot.oldPos != shot.pos: for a in range(2): b = (a + 1) % 2 if shot.oldPos[a] == shot.pos[a] and shot.oldPos[b] != shot.pos[b]: axis = [a, b] hitPlayers = [ p for p in circlePlayers if p.collision_shape.isNearPath(p.pos, shot.oldPos, shot.pos, radius, delta, gradients, distanceBetween, offsetCoords, axis) and shot.checkCollision(p)] if hitPlayers: # If multiple players are hit in the same tick, the server ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment