def __canHit(self, x, y, startX, startY, destX, destY, orientation): if(not self._Entity__isVisible): return False if orientation is None: orientation = self.__orientation canHit = False ux = x - startX uy = y - startY dotP = maths.getDotProduct(orientation.x, orientation.y, ux, uy) / pow(maths.getEuclidianDistance(0, 0, orientation.x, orientation.y), 2) if dotP >= 0: px = startX + dotP*orientation.x py = startY + dotP*orientation.y #px py should be on the line if (px >= min(startX, destX) and px <= max(startX, destX) and py >= min(startY, destY) and py <= max(startY, destY) and (not self.__world.map.isCrossingWall(startX, startY, px, py)) and maths.getEuclidianDistance(px, py, x, y) <= actions.ThrowAction.MIN_HIT_DISTANCE): canHit = True elif(maths.getEuclidianDistance(destX, destY, x, y) <= actions.ThrowAction.MIN_HIT_DISTANCE and (not self.__world.map.isCrossingWall(startX, startY, destX, destY)) and (not self.__world.map.isCrossingWall(x, y, destX, destY))): canHit = True return canHit
def wouldHitPlayer(self, player, destination): ''' Returns whether the player can hit the specified player if he shoots at the specified destination. It doesn't check for collisions with other players along the way, but checks for collisions with walls. Returns false if one of the players isn't currently visible. :param player: Player object :param destination: Point object :returns: bool variable ''' if (not self.isVisible) or (not player.isVisible) or (destination.x == self.x and destination.y == self.y): return False startX = self.x startY = self.y dist = maths.getEuclidianDistance(destination, self.point) oriX = (destination.x - self.x) / dist oriY = (destination.y - self.y) / dist if(dist > actions.ThrowAction.MAX_DISTANCE): endX = (startX + oriX - startX) * (actions.ThrowAction.MAX_DISTANCE) + startX endY = (startY + oriY - startY) * (actions.ThrowAction.MAX_DISTANCE) + startY else: endX = destination.x endY = destination.y return player._Entity__canHit(player.x, player.y, startX, startY, endX, endY, Point(oriX, oriY))
def isInHitRange(self, player): ''' Returns whether the current player is within the specified player hit range (according to ThrowAction.MAX_DISTANCE, ThrowAction.MIN_HIT_DISTANCE, self.canSee). :param player: Player object :returns: bool variable ''' if (not self.canSee(player)) or (not player.isVisible): return False return (maths.getEuclidianDistance(self.x, self.y, player.x, player.y) <= actions.ThrowAction.MAX_DISTANCE + actions.ThrowAction.MIN_HIT_DISTANCE) and self.canSee(player)
def canBeHitBy(self, *args): ''' args[0] is a Snowball: Returns whether the player can be hit by the snowball. Snowball hits if it travels close to the point (<= ThrowAction.MIN_HIT_DISTANCE). It doesn't check for collisions with other players along the way, but checks for collisions with walls. Returns false if the snowball or player isn't currently visible. args[0] is a Player: Returns whether the player can be hit by the specified player. The specified player has to be currently throwing. If the specified player is not in the current team, the throwing distance is assumed to be ThrowAction.MAX_DISTANCE. The specified player orientation is used to determine the snowball trajectory. Snowball hits if it travels close to the point (<= ThrowAction.MIN_HIT_DISTANCE). It doesn't check for collisions with other players along the way, but checks for collisions with walls. Returns false if one of the players isn't currently visible. :returns: bool variable ''' if(isinstance(args[0], Snowball)): snowball = args[0] if (not self.isVisible) or (not snowball.isVisible): return False return snowball.canHit(self) elif(isinstance(args[0], Player)): player = args[0] if (not self.isVisible) or (not player.isVisible): return False if player.playerState.stateType == StateType.Throwing: startX = player.x startY = player.y dist = maths.getEuclidianDistance(0, 0, player.orientation.x, player.orientation.y) endX = 0.0 endY = 0.0 action = player.playerState.currentAction if(action is not None): endX = action.destination.x endY = action.destination.y else: endX = (startX + player.orientation.x - startX) * (actions.ThrowAction.MAX_DISTANCE / dist) + startX endY = (startY + player.orientation.y - startY) * (actions.ThrowAction.MAX_DISTANCE / dist) + startY startX = (startX + player.orientation.x - startX) * (20.0 / dist) + startX startY = (startY + player.orientation.y - startY) * (20.0 / dist) + startY return player._Entity__canHit(self.x, self.y, startX, startY, endX, endY, None) return False