diff --git a/src/entities/player.js b/src/entities/player.js index d33766b..473d460 100644 --- a/src/entities/player.js +++ b/src/entities/player.js @@ -260,8 +260,15 @@ class Player { } } + // Check if any teammate is closer to goal for a better scoring position + const teammateCloserToGoal = this.findTeammateCloserToGoal(teammates, opponents, enemyGoal, distanceToGoal); + if (teammateCloserToGoal && Math.random() < 0.7) { + this.pass(puck, teammateCloserToGoal); + return; + } + // If under heavy pressure, look for a pass first - if (distanceToNearestOpponent < 60) { + if (distanceToNearestOpponent < 100) { const bestTeammate = this.findBestPassTarget(teammates, opponents); if (bestTeammate && Math.random() < 0.8) { this.pass(puck, bestTeammate); @@ -474,13 +481,13 @@ class Player { baseY = rink.centerY + (puck.position.y > rink.centerY ? -60 : 60); break; case 'LW': - // Left wing positions for cross-ice passes and wraparounds - baseX = attackZone - 30; + // Left wing pushes forward on their side for passing options + baseX = attackZone + 40; // Push forward past attack zone baseY = rink.centerY - 140; break; case 'RW': - // Right wing positions for cross-ice passes and wraparounds - baseX = attackZone - 30; + // Right wing pushes forward on their side for passing options + baseX = attackZone + 40; // Push forward past attack zone baseY = rink.centerY + 140; break; case 'LD': @@ -687,6 +694,58 @@ class Player { return bestTarget; } + /** + * Finds a teammate who is closer to the goal than the current puck carrier + * and has a clear passing lane for better scoring opportunities + * @param {Array} teammates - Array of teammate player objects + * @param {Array} opponents - Array of opponent players that might block the pass + * @param {Vector2} enemyGoal - Position of the opponent's goal + * @param {number} myDistanceToGoal - Current player's distance to goal + * @returns {Object|null} Best teammate closer to goal, or null if no good options + */ + findTeammateCloserToGoal(teammates, opponents, enemyGoal, myDistanceToGoal) { + let bestTarget = null; + let bestScore = -1; + + teammates.forEach(teammate => { + // Skip goalies + if (teammate.role === 'G') return; + + const teammateDistanceToGoal = teammate.position.distance(enemyGoal); + const distanceToTeammate = this.position.distance(teammate.position); + + // Only consider teammates who are closer to goal and within reasonable passing distance + if (teammateDistanceToGoal >= myDistanceToGoal || distanceToTeammate < 50 || distanceToTeammate > 250) { + return; + } + + // Check if pass is blocked by opponents + let blocked = false; + opponents.forEach(opponent => { + const lineToTeammate = teammate.position.subtract(this.position); + const lineToOpponent = opponent.position.subtract(this.position); + const angle = Math.abs(lineToTeammate.angle() - lineToOpponent.angle()); + + if (angle < 0.4 && this.position.distance(opponent.position) < distanceToTeammate) { + blocked = true; + } + }); + + if (!blocked) { + // Score based on how much closer to goal they are and their attributes + const goalAdvantage = myDistanceToGoal - teammateDistanceToGoal; + const score = (goalAdvantage * teammate.attributes.shooting) / distanceToTeammate; + + if (score > bestScore) { + bestScore = score; + bestTarget = teammate; + } + } + }); + + return bestTarget; + } + /** * Determines if this player is the closest non-goalie teammate to the puck * Used to decide who should chase loose pucks