📄 memaction.c
字号:
my_error("Calling BallPathInterceptionDistance when I can't get get there"); return BPIdist;}/*****************************************************************************************/int ActionInfo::BallPathInterceptCyclesForBall(){ VerifyBPIInfo(); if (!BPIable) my_error("Calling BallPathInterceptionCyclesForBall when I can't get get there"); return (int)ceil(BPIballcyc);}/*****************************************************************************************/Bool ActionInfo::BallPathInterceptCanIGetThere(float max_pow){ VerifyBPIInfo(); if (!BPIable) return FALSE; AngleDeg targAng = AngleToFromBody(BPIpoint); Vector myEnd; if (fabs(GetNormalizeAngleDeg(MyBodyAng() - targAng)) > CP_max_go_to_point_angle_err) { myEnd = MyPredictedPosition((int)ceil(BPIballcyc), max_pow); } else { myEnd = MyPredictedPositionWithTurn(targAng - MyBodyAng(), (int)ceil(BPIballcyc), max_pow); } return ( (myEnd - MyPos()).mod() >= (BPIpoint - MyPos()).mod() ) ? TRUE : FALSE;}/*****************************************************************************************//*****************************************************************************************//*****************************************************************************************/float ActionInfo::VelAtPt2VelAtFoot(Vector pt, float targ_vel_at_pt){ if (targ_vel_at_pt < FLOAT_EPS) { return SolveForFirstTermInfGeomSeries(SP_ball_decay, (pt - MyPos()).mod() ); } else { float ball_steps = SolveForLengthGeomSeries(targ_vel_at_pt, 1/SP_ball_decay, (pt - MyPos()).mod() ); return targ_vel_at_pt * pow(1/SP_ball_decay, ball_steps); } }/*****************************************************************************************//* looks at closeest opponent or teamless player *//* SMURF: the teamless part is a hack */KickMode ActionInfo::BestKickModeAbs(AngleDeg abs_ang){ Unum closest = ClosestOpponent(); if (NumTeamlessPlayers() > 0) { Vector teamless_pos = ClosestTeamlessPlayerPosition(); if (closest == Unum_Unknown || DistanceTo(teamless_pos) < OpponentDistance(closest)) closest = Unum_Teamless; } if (closest == Unum_Unknown) return KM_HardestKick; int cyc_to_steal = EstimatedCyclesToSteal(closest); float targ_ang = abs_ang + signf(GetNormalizeAngleDeg(BallAngleFromBody()-abs_ang)) * (90 + CP_hardest_kick_ball_ang); float ang_diff = GetNormalizeAngleDeg(BallAngleFromBody() - targ_ang); NormalizeAngleDeg(&ang_diff); if (cyc_to_steal > fabs(ang_diff)/CP_time_for_full_rotation + CP_cycles_to_kick) return KM_HardestKick; //if (OpponentWithBall() != Unum_Unknown) if (cyc_to_steal <= 1) return KM_QuickestRelease; if (cyc_to_steal < CP_cycles_to_kick) return KM_Quickly; if (cyc_to_steal < CP_cycles_to_kick + 1) // time for a dash in KM_Hard return KM_Moderate; return KM_Hard;}/*****************************************************************************************//* returns estimated cycles for opponent to get the ball into his kickable area *//* can handle Unum_Teamless SMURF: it's kind of a hack though */int ActionInfo::EstimatedCyclesToSteal(Unum opp, Vector ball_pos){ if (!BallKickable()) my_error("EstimatedCyclesToSteal: shouldn't use this if the ball is not kickable"); if (BallKickableForOpponent(opp)) { LogAction2(110, "EstimatedCyclesToSteal: already kickable for opponent"); return 0; } Vector targ = ball_pos; Vector pos; int cyc; if (opp == Unum_Teamless) { if (NumTeamlessPlayers() < 1) my_error("EstimatedCyclesToSteal: can't estimate teamless if there aren't any"); pos = ClosestTeamlessPlayerPosition(); targ -= (ball_pos - pos).SetLength(SP_kickable_area); cyc = (int)ceil(targ.dist(pos) / SP_player_speed_max); } else { if (!OpponentPositionValid(opp)) my_error("EstimateCyclesToSteal: can't estimate if I don;t know where opponent is"); pos = OpponentAbsolutePosition(opp); targ -= (ball_pos - pos).SetLength(SP_kickable_area); cyc = OpponentPredictedCyclesToPoint(opp, targ); } /* now decide if the player will have to dodge */ if (!pos.ApproxEqual(targ)) { Line oppLine = LineFromTwoPoints(pos, targ); Vector dodge_pos = oppLine.ProjectPoint(MyPos()); dodge_pos += (pos - dodge_pos).SetLength(2.0* SP_player_size); float dodge_dist = oppLine.dist(MyPos()); if (dodge_dist < 2.0 * SP_player_size && oppLine.InBetween(dodge_pos, pos, targ)) { /* need to take into account a dodge */ cyc += 2; //have to turn twice if (dodge_dist > 2 * SP_player_size - SP_player_speed_max) cyc += 1; // one dash will dodge us else cyc += 2; // it takes two dashes to dodge us } } return cyc; }/*****************************************************************************************//*****************************************************************************************//*****************************************************************************************/Bool ActionInfo::KickInProgress(){ /* need to have kicked last cycle. Updates kick_in_progress_time */ if ( kick_in_progress && kick_in_progress_time == LastActionOpTime ){ kick_in_progress_time = CurrentTime; return TRUE; } return FALSE;}/*****************************************************************************************/void ActionInfo::StartKick(AngleDeg target_angle, KickMode mode, float target_vel, TurnDir rot){ kick_in_progress = TRUE; start_kick_time = kick_in_progress_time = CurrentTime; kick_in_progress_abs_angle = GetNormalizeAngleDeg(target_angle + MyBodyAng()); kick_in_progress_mode = mode; kick_in_progress_target_vel = target_vel; kick_in_progress_rotation = rot;}/*****************************************************************************************/void ActionInfo::StartShot(AngleDeg target_angle, KickMode mode, TurnDir rot){ StartKick(target_angle,mode,2*SP_ball_speed_max, rot);}/*****************************************************************************************/void ActionInfo::StartPass(Unum target, float target_vel_at_dest, TurnDir rot){ if ( target == Unum_Unknown || !TeammatePositionValid(target) ) my_error("can't start this pass"); team_passer = MyNumber; team_receiver = target; team_pass_time = CurrentTime; float target_vel = VelAtPt2VelAtFoot(TeammateAbsolutePosition(target),target_vel_at_dest); StartKick(TeammateAngleFromBody(target),KM_Moderate,target_vel,rot);}/*****************************************************************************************//*****************************************************************************************//*****************************************************************************************//* No reasoning about players being tired yet: if so, need to add dash_pow to the interception calls *//* These functions are very computationally intensive *//* the stored value does not include the goalie */Unum ActionInfo::FastestTeammateToBall(){ if ( !BallPositionValid() ) my_error("Need to know ball position to know fastest to it\n"); Unum closest = ClosestTeammateToBall(); if ( !BallMoving() && !TeammateTired(closest) ) return closest; if ( CurrentTime == Stored_Fastest_Teammate_Time ) return Stored_Fastest_Teammate; ResetInterceptionMinCyc(); SetInterceptionLookahead(LA_BestSoFar); Unum FastestPlayer = Unum_Unknown; int cycles, min_cycles = CP_max_int_lookahead+1; for (int i=1; i<=SP_team_size; i++){ if ( TeammatePositionValid(i) && TeammateInterceptionAble(i) == TRUE && (cycles=TeammateInterceptionNumberCycles(i)) < min_cycles && (i != FP_goalie_number || CP_goalie) ){ min_cycles = cycles; FastestPlayer = i; } } Stored_Fastest_Teammate = FastestPlayer; Stored_Fastest_Teammate_Time = CurrentTime; return Stored_Fastest_Teammate;}/*****************************************************************************************/Unum ActionInfo::FastestOpponentToBall(){ if ( !BallPositionValid() ) my_error("Need to know ball position to know fastest to it\n"); if ( !BallMoving() ) return ClosestOpponentToBall(); if ( CurrentTime == Stored_Fastest_Opponent_Time ) return Stored_Fastest_Opponent; ResetInterceptionMinCyc(); SetInterceptionLookahead(LA_BestSoFar); Unum FastestPlayer = Unum_Unknown; int cycles, min_cycles = CP_max_int_lookahead+1; for (int i=1; i<=SP_team_size; i++){ if ( OpponentPositionValid(i) && OpponentInterceptionAble(i) == TRUE && (cycles=OpponentInterceptionNumberCycles(i)) < min_cycles ){ min_cycles = cycles; FastestPlayer = i; } } Stored_Fastest_Opponent = FastestPlayer; Stored_Fastest_Opponent_Time = CurrentTime; return FastestPlayer;}/*****************************************************************************************/Unum ActionInfo::BallPossessor(){ if (!BallPositionValid()) { //my_error("BallPossesor: ball position not valid"); return Unum_Unknown; } Unum num_with_ball = PlayerWithBall(); if (num_with_ball != Unum_Unknown) return num_with_ball; Unum fastestTeammate, fastestOpponent; if (BallMoving()) { int teamCycles, oppCycles; fastestOpponent = FastestOpponentToBall(); fastestTeammate = FastestTeammateToBall(); if (fastestTeammate == Unum_Unknown || fastestOpponent == Unum_Unknown) return (fastestTeammate == Unum_Unknown ? -fastestOpponent : fastestTeammate); teamCycles = TeammateInterceptionNumberCycles(fastestTeammate); oppCycles = OpponentInterceptionNumberCycles(fastestOpponent); if (teamCycles + CP_possessor_intercept_space < oppCycles) return fastestTeammate; else if (oppCycles + CP_possessor_intercept_space < teamCycles) return -fastestOpponent; } else { fastestTeammate = ClosestTeammateToBall(); fastestOpponent = ClosestOpponentToBall(); if (fastestTeammate == Unum_Unknown || fastestOpponent == Unum_Unknown) return (fastestTeammate == Unum_Unknown ? -fastestOpponent : fastestTeammate); /* we'll just ignore facing angles because they probably aren't right anwyay */; if (TeammateAbsolutePosition(fastestTeammate).dist(BallAbsolutePosition()) < OpponentAbsolutePosition(fastestOpponent).dist(BallAbsolutePosition())) return fastestTeammate; else return -fastestOpponent; } return Unum_Unknown;} /*****************************************************************************************/char ActionInfo::TeamInPossession(){ switch ( PlayMode ){ case PM_Play_On: break; case PM_My_Kick_In: case PM_My_Corner_Kick: case PM_My_Kick_Off: case PM_My_Free_Kick: case PM_My_Goalie_Free_Kick: case PM_My_Offside_Kick: case PM_My_Goal_Kick: return MySide; case PM_Their_Kick_In: case PM_Their_Corner_Kick: case PM_Their_Goal_Kick: case PM_Their_Kick_Off: case PM_Their_Offside_Kick: case PM_Their_Free_Kick: case PM_Their_Goalie_Free_Kick: return TheirSide; default: break; } Unum player = BallPossessor(); if ( player > 0 ) return MySide; else if (player < 0) return TheirSide; else return '?';}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -