Rev 1 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | #include "oppoproc.h" |
| 18 | pmbaty | 2 | #include "brender.h" |
| 1 | pmbaty | 3 | #include "errors.h" |
| 4 | #include "globvars.h" |
||
| 5 | #include "harness/trace.h" |
||
| 6 | #include "opponent.h" |
||
| 7 | #include "pd/sys.h" |
||
| 8 | #include <math.h> |
||
| 9 | #include <stdlib.h> |
||
| 10 | |||
| 11 | // IDA: int __usercall StraightestArcForCorner2D@<EAX>(br_vector2 *pCent@<EAX>, br_scalar *pRadius@<EDX>, br_scalar *pEntry_length@<EBX>, int *pLeft_not_right@<ECX>, br_vector2 *p1, br_vector2 *p2, br_vector2 *p3, br_scalar pWidth12, br_scalar pWidth23) |
||
| 12 | int StraightestArcForCorner2D(br_vector2* pCent, br_scalar* pRadius, br_scalar* pEntry_length, int* pLeft_not_right, br_vector2* p1, br_vector2* p2, br_vector2* p3, br_scalar pWidth12, br_scalar pWidth23) { |
||
| 13 | //br_vector2 rel1; // Pierre-Marie Baty -- unused variable |
||
| 14 | //br_vector2 rel3; // Pierre-Marie Baty -- unused variable |
||
| 15 | //br_vector2 rot1; // Pierre-Marie Baty -- unused variable |
||
| 16 | //br_vector2 rot1u; // Pierre-Marie Baty -- unused variable |
||
| 17 | //br_scalar len12_squared; // Pierre-Marie Baty -- unused variable |
||
| 18 | //br_scalar len23_squared; // Pierre-Marie Baty -- unused variable |
||
| 19 | //br_scalar c; // Pierre-Marie Baty -- unused variable |
||
| 20 | //br_scalar numerator; // Pierre-Marie Baty -- unused variable |
||
| 21 | //br_scalar x; // Pierre-Marie Baty -- unused variable |
||
| 22 | //br_scalar __block0___scale; // Pierre-Marie Baty -- unused variable |
||
| 23 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %f, %f)", pCent, pRadius, pEntry_length, pLeft_not_right, p1, p2, p3, pWidth12, pWidth23); |
||
| 24 | NOT_IMPLEMENTED(); |
||
| 25 | } |
||
| 26 | |||
| 27 | // There appears to be two different implementations of this function in different binaries. |
||
| 28 | // One does calculations in 2d space, this one calculates in 3d space. |
||
| 29 | static void StraightestArcForCorner(float* p1, float* p2, float* p3, br_vector3* p4, br_vector3* p5, br_vector3* p6, br_vector3* p7, br_vector3* p8, float p9, float p10) { |
||
| 30 | br_vector3 rel1; |
||
| 31 | br_vector3 rel3; |
||
| 32 | br_vector3 rot1; |
||
| 33 | br_scalar tmp; |
||
| 34 | br_scalar tmp2; |
||
| 35 | br_scalar tmp3; |
||
| 36 | br_scalar tmp4; |
||
| 37 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %p, %f, %f)", p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); |
||
| 38 | |||
| 39 | BrVector3Sub(&rel1, p6, p5); |
||
| 40 | rel1.v[1] = 0.f; |
||
| 41 | BrVector3Sub(&rel3, p4, p5); |
||
| 42 | rel3.v[1] = 0.f; |
||
| 43 | *p3 = BrVector3Length(&rel3); |
||
| 44 | if (*p3 <= BR_SCALAR_EPSILON) { |
||
| 45 | *p2 = 0.001f; |
||
| 46 | *p3 = 0.001f; |
||
| 47 | } |
||
| 48 | tmp = BrVector3Dot(&rel1, &rel3); |
||
| 49 | BrVector3Cross(&rot1, &rel1, &rel3); |
||
| 50 | tmp2 = sqrtf(tmp * tmp + rot1.v[1] * rot1.v[1]); |
||
| 51 | tmp3 = fabsf(rot1.v[1] / tmp2); |
||
| 52 | tmp4 = p10 * tmp / tmp2 + p9; |
||
| 53 | if ((tmp3 < 1.f && fabsf(tmp4) > tmp3 * 1000.f) || tmp3 < 0.001f) { |
||
| 54 | *p1 = 1000.f; |
||
| 55 | *p2 = 1000.f; |
||
| 56 | } else { |
||
| 57 | tmp4 = tmp4 / tmp3; |
||
| 58 | tmp3 = tmp3 / (tmp / tmp2 + 1.f); |
||
| 59 | *p2 = tmp3 * p10 + sqrtf(tmp3 * p10) + tmp4; |
||
| 60 | *p1 = *p2 * tmp3; |
||
| 61 | } |
||
| 62 | } |
||
| 63 | |||
| 64 | // IDA: br_scalar __usercall CornerFudge@<ST0>(tCar_spec *pCar_spec@<EAX>) |
||
| 65 | br_scalar CornerFudge(tCar_spec* pCar_spec) { |
||
| 66 | LOG_TRACE("(%p)", pCar_spec); |
||
| 67 | |||
| 68 | return 1.4f; |
||
| 69 | } |
||
| 70 | |||
| 71 | // IDA: br_scalar __usercall MaxCurvatureForCarSpeed@<ST0>(tCar_spec *pCar@<EAX>, br_scalar pSpeed) |
||
| 72 | br_scalar MaxCurvatureForCarSpeed(tCar_spec* pCar, br_scalar pSpeed) { |
||
| 73 | br_scalar curv; |
||
| 74 | LOG_TRACE("(%p, %f)", pCar, pSpeed); |
||
| 75 | |||
| 76 | if (pSpeed >= 12.5f) { |
||
| 77 | curv = pCar->maxcurve * 12.5f / pSpeed; |
||
| 78 | } else { |
||
| 79 | curv = pCar->maxcurve; |
||
| 80 | } |
||
| 81 | return curv; |
||
| 82 | } |
||
| 83 | |||
| 84 | // IDA: br_scalar __usercall Vector2Cross@<ST0>(br_vector2 *pA@<EAX>, br_vector2 *pB@<EDX>) |
||
| 85 | br_scalar Vector2Cross(br_vector2* pA, br_vector2* pB) { |
||
| 86 | LOG_TRACE("(%p, %p)", pA, pB); |
||
| 87 | NOT_IMPLEMENTED(); |
||
| 88 | } |
||
| 89 | |||
| 90 | // IDA: tFollow_path_result __usercall EndOfPath@<EAX>(tOpponent_spec *pOpponent_spec@<EAX>) |
||
| 91 | tFollow_path_result EndOfPath(tOpponent_spec* pOpponent_spec) { |
||
| 92 | //tCar_spec* car_spec; // Pierre-Marie Baty -- unused variable |
||
| 93 | LOG_TRACE("(%p)", pOpponent_spec); |
||
| 94 | NOT_IMPLEMENTED(); |
||
| 95 | } |
||
| 96 | |||
| 97 | // IDA: int __usercall RoughlyColinear@<EAX>(br_vector2 *p1@<EAX>, br_vector2 *p2@<EDX>, br_vector2 *p3@<EBX>) |
||
| 98 | int RoughlyColinear(br_vector2* p1, br_vector2* p2, br_vector2* p3) { |
||
| 99 | //br_vector2 rel1; // Pierre-Marie Baty -- unused variable |
||
| 100 | //br_vector2 rel2; // Pierre-Marie Baty -- unused variable |
||
| 101 | //br_vector2 sum; // Pierre-Marie Baty -- unused variable |
||
| 102 | //br_scalar cross; // Pierre-Marie Baty -- unused variable |
||
| 103 | //br_scalar dot; // Pierre-Marie Baty -- unused variable |
||
| 104 | //br_scalar wibble; // Pierre-Marie Baty -- unused variable |
||
| 105 | LOG_TRACE("(%p, %p, %p)", p1, p2, p3); |
||
| 106 | NOT_IMPLEMENTED(); |
||
| 107 | } |
||
| 108 | |||
| 109 | // IDA: int __usercall GetStraight@<EAX>(br_vector2 *pStart@<EAX>, br_vector2 *pFinish@<EDX>, br_scalar *pWidth@<EBX>, int section1@<ECX>, tOpponent_spec *pOpponent_spec, tFollow_path_data *data) |
||
| 110 | int GetStraight(br_vector2* pStart, br_vector2* pFinish, br_scalar* pWidth, int section1, tOpponent_spec* pOpponent_spec, tFollow_path_data* data) { |
||
| 111 | //int section; // Pierre-Marie Baty -- unused variable |
||
| 112 | //br_vector2 next; // Pierre-Marie Baty -- unused variable |
||
| 113 | //br_scalar next_width; // Pierre-Marie Baty -- unused variable |
||
| 114 | LOG_TRACE("(%p, %p, %p, %d, %p, %p)", pStart, pFinish, pWidth, section1, pOpponent_spec, data); |
||
| 115 | NOT_IMPLEMENTED(); |
||
| 116 | } |
||
| 117 | |||
| 118 | // IDA: tFollow_path_result __usercall ProcessFollowPath@<EAX>(tOpponent_spec *pOpponent_spec@<EAX>, tProcess_objective_command pCommand@<EDX>, int pPursuit_mode@<EBX>, int pIgnore_end@<ECX>, int pNever_struggle) |
||
| 119 | tFollow_path_result ProcessFollowPath(tOpponent_spec* pOpponent_spec, tProcess_objective_command pCommand, int pPursuit_mode, int pIgnore_end, int pNever_struggle) { |
||
| 120 | tS16 real_section_no; |
||
| 121 | tFollow_path_data* data; |
||
| 122 | br_vector3 wank; |
||
| 123 | br_vector3 wank2; |
||
| 124 | br_vector3* not_our_dir; |
||
| 125 | br_vector3 section_dir; |
||
| 126 | br_vector3 section_v; |
||
| 127 | br_vector3 start; |
||
| 128 | //br_vector3 corner; // Pierre-Marie Baty -- unused variable |
||
| 129 | br_vector3 next; |
||
| 130 | br_vector3 goal_dir; |
||
| 131 | //br_vector3 intersect; // Pierre-Marie Baty -- unused variable |
||
| 132 | br_vector3 a; |
||
| 133 | br_vector3 p; |
||
| 134 | br_vector3 car_to_end; |
||
| 135 | br_actor* car_master_actor; |
||
| 136 | br_scalar stopped_speed; |
||
| 137 | br_scalar dist_to_end; |
||
| 138 | br_scalar t; |
||
| 139 | br_scalar acc; |
||
| 140 | br_scalar speed; |
||
| 141 | br_scalar dist_to_goal; |
||
| 142 | br_scalar section_width; |
||
| 143 | br_scalar goal_width; |
||
| 144 | br_scalar desired_speed; |
||
| 145 | br_scalar dist_along; |
||
| 146 | br_scalar acc_factor; |
||
| 147 | br_scalar max_acc; |
||
| 148 | //br_scalar speed_to_goal; // Pierre-Marie Baty -- unused variable |
||
| 149 | br_scalar error; |
||
| 150 | br_scalar radius; |
||
| 151 | //br_scalar entry_len; // Pierre-Marie Baty -- unused variable |
||
| 152 | br_scalar corner_speed2; |
||
| 153 | //br_scalar distance; // Pierre-Marie Baty -- unused variable |
||
| 154 | br_scalar stopping_distance; |
||
| 155 | br_scalar corner_speed; |
||
| 156 | br_scalar dot_a; |
||
| 157 | br_scalar dot_d; |
||
| 158 | //br_scalar further_along; // Pierre-Marie Baty -- unused variable |
||
| 159 | tCar_spec* car_spec; |
||
| 160 | int engine_damage; |
||
| 161 | int trans_damage; |
||
| 162 | int section_no; |
||
| 163 | int sx; |
||
| 164 | int just_fucking_brake; |
||
| 165 | //br_vector2 oppo_pos2d; // Pierre-Marie Baty -- unused variable |
||
| 166 | //br_vector2 start2d; // Pierre-Marie Baty -- unused variable |
||
| 167 | //br_vector2 finish2d; // Pierre-Marie Baty -- unused variable |
||
| 168 | //br_vector2 next2d; // Pierre-Marie Baty -- unused variable |
||
| 169 | //br_vector2 oppo_pos_rel; // Pierre-Marie Baty -- unused variable |
||
| 170 | //br_vector2 oppo_pos_rel_next; // Pierre-Marie Baty -- unused variable |
||
| 171 | //br_vector2 section_rel; // Pierre-Marie Baty -- unused variable |
||
| 172 | //br_vector2 section_rel_next; // Pierre-Marie Baty -- unused variable |
||
| 173 | //br_vector2 v2d; // Pierre-Marie Baty -- unused variable |
||
| 174 | //br_vector2 corner2d; // Pierre-Marie Baty -- unused variable |
||
| 175 | //br_vector2 after_corner2d; // Pierre-Marie Baty -- unused variable |
||
| 176 | //br_vector2 next_turning_cent; // Pierre-Marie Baty -- unused variable |
||
| 177 | //br_vector2 temp2d; // Pierre-Marie Baty -- unused variable |
||
| 178 | //br_scalar section_len; // Pierre-Marie Baty -- unused variable |
||
| 179 | //br_scalar section_len_next; // Pierre-Marie Baty -- unused variable |
||
| 180 | //br_scalar pos_error; // Pierre-Marie Baty -- unused variable |
||
| 181 | //br_scalar pos_error_next; // Pierre-Marie Baty -- unused variable |
||
| 182 | //br_scalar pos_error_factor; // Pierre-Marie Baty -- unused variable |
||
| 183 | //br_scalar sin_error; // Pierre-Marie Baty -- unused variable |
||
| 184 | //br_scalar corner_radius; // Pierre-Marie Baty -- unused variable |
||
| 185 | //br_scalar corner_entry_length; // Pierre-Marie Baty -- unused variable |
||
| 186 | //br_scalar corner_distance; // Pierre-Marie Baty -- unused variable |
||
| 187 | br_scalar speed2d; |
||
| 188 | //br_scalar stemp1; // Pierre-Marie Baty -- unused variable |
||
| 189 | br_scalar width; |
||
| 190 | br_scalar next_width; |
||
| 191 | br_scalar next_turning_radius; |
||
| 192 | br_scalar next_corner_size; |
||
| 193 | //br_scalar later_width; // Pierre-Marie Baty -- unused variable |
||
| 194 | br_scalar effective_speed_factor; |
||
| 195 | //int first_straight; // Pierre-Marie Baty -- unused variable |
||
| 196 | //int next_straight; // Pierre-Marie Baty -- unused variable |
||
| 197 | //int left_not_right; // Pierre-Marie Baty -- unused variable |
||
| 198 | //int later_straight; // Pierre-Marie Baty -- unused variable |
||
| 199 | //int next_left_not_right; // Pierre-Marie Baty -- unused variable |
||
| 200 | LOG_TRACE("(%p, %d, %d, %d, %d)", pOpponent_spec, pCommand, pPursuit_mode, pIgnore_end, pNever_struggle); |
||
| 201 | |||
| 202 | car_spec = pOpponent_spec->car_spec; |
||
| 203 | engine_damage = car_spec->damage_units[0].damage_level; |
||
| 204 | trans_damage = car_spec->damage_units[1].damage_level; |
||
| 205 | data = &pOpponent_spec->follow_path_data; |
||
| 206 | car_master_actor = car_spec->car_master_actor; |
||
| 207 | |||
| 208 | if (pCommand == ePOC_start) { |
||
| 209 | data->first_section_no = GetOpponentsFirstSection(pOpponent_spec); |
||
| 210 | data->section_no = data->first_section_no; |
||
| 211 | dr_dprintf("%s: ProcessFollowPath() - new task started, first real section #%d", pOpponent_spec->car_spec->driver_name, GetOpponentsRealSection(pOpponent_spec, data->first_section_no)); |
||
| 212 | data->has_moved_during_this_task = 0; |
||
| 213 | data->struggle_time = 0; |
||
| 214 | data->last_finished_struggle_time = gTime_stamp_for_this_munging; |
||
| 215 | data->prev_acc = 0.f; |
||
| 216 | data->prev_acc_error = 0.f; |
||
| 217 | data->borrowed_time_start = gTime_stamp_for_this_munging; |
||
| 218 | data->last_struggle_section = -1; |
||
| 219 | data->made_it = 1; |
||
| 220 | data->cheating = 0; |
||
| 221 | data->cornering = 0; |
||
| 222 | if (!pOpponent_spec->cheating && !pOpponent_spec->physics_me) { |
||
| 223 | dr_dprintf("%s: Rematerialising from ePOC_start in ProcessFollowPath()...", pOpponent_spec->car_spec->driver_name); |
||
| 224 | RematerialiseOpponentOnNearestSection(pOpponent_spec, BrVector3Length(&car_spec->v)); |
||
| 225 | } |
||
| 226 | return eFPR_OK; |
||
| 227 | } else if (pCommand == ePOC_run) { |
||
| 228 | if (pOpponent_spec->follow_path_data.cheating || pOpponent_spec->cheating) { |
||
| 229 | return FollowCheatyPath(pOpponent_spec); |
||
| 230 | } |
||
| 231 | if (!pIgnore_end && !data->made_it && data->borrowed_time_start + 1000 < gTime_stamp_for_this_munging && gTime_stamp_for_this_munging < data->borrowed_time_start + 10000) { |
||
| 232 | BrVector3Sub(§ion_dir, GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no), GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); |
||
| 233 | BrVector3Sub(&goal_dir, &car_master_actor->t.t.translate.t, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); |
||
| 234 | dist_along = BrVector3LengthSquared(&goal_dir) / BrVector3LengthSquared(§ion_dir); |
||
| 235 | BrVector3Scale(§ion_v, §ion_dir, dist_along); |
||
| 236 | BrVector3Sub(&wank, &goal_dir, §ion_v); |
||
| 237 | goal_width = BrVector3Length(&wank); |
||
| 238 | if (GetOpponentsSectionWidth(pOpponent_spec, data->section_no) >= goal_width) { |
||
| 239 | data->made_it = 1; |
||
| 240 | } |
||
| 241 | } |
||
| 242 | if (data->borrowed_time_start + 10000 < gTime_stamp_for_this_munging && !data->made_it) { |
||
| 243 | dr_dprintf("%s: ProcessFollowPath() giving up due to not making the corner", pOpponent_spec->car_spec->driver_name); |
||
| 244 | return eFPR_given_up; |
||
| 245 | } |
||
| 246 | car_spec->keys.acc = 1; |
||
| 247 | speed = BrVector3Length(&car_spec->v); |
||
| 248 | if (speed > 0.2f) { |
||
| 249 | data->has_moved_during_this_task = 1; |
||
| 250 | pOpponent_spec->has_moved_at_some_point = 1; |
||
| 251 | } |
||
| 252 | if (data->struggle_time) { |
||
| 253 | if (data->struggle_time + 150 * (5 * data->number_of_struggles - 5) + 2750 >= gTime_stamp_for_this_munging) { |
||
| 254 | if (data->struggle_time + 150 * (5 * data->number_of_struggles - 5) + 2000 >= gTime_stamp_for_this_munging) { |
||
| 255 | car_spec->brake_force = 0.0f; |
||
| 256 | car_spec->acc_force = car_spec->M * -6.0f; |
||
| 257 | } else { |
||
| 258 | car_spec->acc_force = 0.0f; |
||
| 259 | car_spec->brake_force = car_spec->M * 15.0f; |
||
| 260 | } |
||
| 261 | car_spec->curvature = 0.0f; |
||
| 262 | return eFPR_OK; |
||
| 263 | } |
||
| 264 | dr_dprintf("%s: done struggling. speed = %.2f m/s", pOpponent_spec->car_spec->driver_name, speed); |
||
| 265 | data->made_it = 0; |
||
| 266 | data->borrowed_time_start = gTime_stamp_for_this_munging; |
||
| 267 | data->struggle_time = 0; |
||
| 268 | data->last_finished_struggle_time = gTime_stamp_for_this_munging; |
||
| 269 | car_spec->brake_force = 0.0f; |
||
| 270 | car_spec->acc_force = 0.0f; |
||
| 271 | } else { |
||
| 272 | if (pIgnore_end) { |
||
| 273 | stopped_speed = 0.06666667f; |
||
| 274 | } else { |
||
| 275 | stopped_speed = 0.2f; |
||
| 276 | } |
||
| 277 | if (!pNever_struggle && stopped_speed >= speed && data->last_finished_struggle_time + 2000 < gTime_stamp_for_this_munging && (pPursuit_mode || data->has_moved_during_this_task != 0)) { |
||
| 278 | dr_dprintf("%s: 'Stopped,' section #%d, speed = %.2f m/s, about to start a-strugglin'", pOpponent_spec->car_spec->driver_name, data->section_no, speed); |
||
| 279 | data->struggle_time = gTime_stamp_for_this_munging; |
||
| 280 | if (pIgnore_end || data->section_no != data->last_struggle_section) { |
||
| 281 | data->last_struggle_section = data->section_no; |
||
| 282 | data->number_of_struggles = 0; |
||
| 283 | } else { |
||
| 284 | if (data->number_of_struggles >= 3) { |
||
| 285 | car_spec->acc_force = 0.0f; |
||
| 286 | car_spec->brake_force = 0.0f; |
||
| 287 | dr_dprintf("%s: Giving up trying to follow path 'cos we've struggled too much", pOpponent_spec->car_spec->driver_name); |
||
| 288 | return eFPR_given_up; |
||
| 289 | } |
||
| 290 | data->number_of_struggles++; |
||
| 291 | } |
||
| 292 | } |
||
| 293 | } |
||
| 294 | BrVector3Sub(&car_to_end, GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no), &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 295 | car_to_end.v[1] = 0.0f; |
||
| 296 | dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; |
||
| 297 | dist_to_goal = dist_to_end; |
||
| 298 | if (dist_to_end > 15.0f) { |
||
| 299 | BrVector3Sub(&wank, GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no), GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); |
||
| 300 | BrVector3Normalise(&a, &wank); |
||
| 301 | BrVector3Sub(&wank, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no)); |
||
| 302 | |||
| 303 | dot_a = BrVector3Dot(&a, &wank); // v62.v[2] * wank.v[2] + v62.v[1] * wank.v[1] + v62.v[0] * wank.v[0]; |
||
| 304 | wank2.v[0] = a.v[0] * dot_a; |
||
| 305 | wank2.v[2] = a.v[2] * dot_a; |
||
| 306 | car_to_end.v[0] = wank2.v[0] - wank.v[0]; |
||
| 307 | car_to_end.v[2] = wank2.v[2] - wank.v[2]; |
||
| 308 | car_to_end.v[1] = 0.0f; |
||
| 309 | dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; |
||
| 310 | if (dist_to_end < 15.0f) { |
||
| 311 | t = sqrtf(225.0f - dist_to_end * dist_to_end) / WORLD_SCALE; |
||
| 312 | if (t + dot_a >= 0.0) { |
||
| 313 | wank.v[0] = a.v[0] * t; |
||
| 314 | wank.v[2] = a.v[2] * t; |
||
| 315 | wank.v[1] = 0.0f; |
||
| 316 | BrVector3Accumulate(&car_to_end, &wank); |
||
| 317 | } else { |
||
| 318 | BrVector3Sub(&car_to_end, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no), &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 319 | dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; |
||
| 320 | BrVector3Scale(&car_to_end, &car_to_end, 15.0f / dist_to_end); |
||
| 321 | } |
||
| 322 | dist_to_end = 15.0f; |
||
| 323 | } else if (dot_a < 0.0f) { |
||
| 324 | BrVector3Sub(&car_to_end, GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no), &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 325 | dist_to_end = BrVector3Length(&car_to_end) * WORLD_SCALE; |
||
| 326 | BrVector3Scale(&car_to_end, &car_to_end, 15.0f / dist_to_end); |
||
| 327 | } |
||
| 328 | } |
||
| 329 | section_width = GetOpponentsSectionWidth(pOpponent_spec, data->section_no) * WORLD_SCALE; |
||
| 330 | if (!pIgnore_end && speed * 1.5f > dist_to_goal) { |
||
| 331 | dr_dprintf("%s: ProcessFollowPath() - *** CHANGING SECTIONS ***", pOpponent_spec->car_spec->driver_name); |
||
| 332 | dr_dprintf("%s: ProcessFollowPath() - current section %d(#%d)", pOpponent_spec->car_spec->driver_name, data->section_no, GetOpponentsRealSection(pOpponent_spec, data->section_no)); |
||
| 333 | data->section_no = GetOpponentsNextSection(pOpponent_spec, data->section_no); |
||
| 334 | if (data->section_no == -1) { |
||
| 335 | car_spec->acc_force = 0.0f; |
||
| 336 | car_spec->brake_force = 0.0f; |
||
| 337 | dr_dprintf("%s: ProcessFollowPath() - reached end of path", pOpponent_spec->car_spec->driver_name); |
||
| 338 | return eFPR_end_of_path; |
||
| 339 | } |
||
| 340 | car_to_end.v[1] = 0.0f; |
||
| 341 | real_section_no = GetOpponentsRealSection(pOpponent_spec, data->section_no); |
||
| 342 | dr_dprintf("%s: ProcessFollowPath() - next section %d(#%d)", pOpponent_spec->car_spec->driver_name, data->section_no, GetOpponentsRealSection(pOpponent_spec, data->section_no)); |
||
| 343 | data->last_struggle_section = -1; |
||
| 344 | data->borrowed_time_start = gTime_stamp_for_this_munging; |
||
| 345 | data->made_it = 1; |
||
| 346 | data->last_distance = 0.0f; |
||
| 347 | } |
||
| 348 | not_our_dir = (br_vector3*)&car_master_actor->t.t.mat.m[2]; |
||
| 349 | |||
| 350 | BrVector3Cross(&wank, &car_to_end, not_our_dir); |
||
| 351 | |||
| 352 | radius = GetOpponentsSectionWidth(pOpponent_spec, data->section_no) * 0.5f; |
||
| 353 | just_fucking_brake = 0; |
||
| 354 | dot_d = BrVector3Dot(&car_to_end, not_our_dir); |
||
| 355 | if (dot_d > 0.0f && speed > 10.0f) { |
||
| 356 | data->desired_speed = 6.0f; |
||
| 357 | car_spec->curvature = 0.0f; |
||
| 358 | just_fucking_brake = 1; |
||
| 359 | } else { |
||
| 360 | if ((wank.v[1] > 0.0f && dot_d > 0.0f) || GetOpponentsSectionWidth(pOpponent_spec, data->section_no) < wank.v[1]) { |
||
| 361 | car_spec->curvature = MaxCurvatureForCarSpeed(car_spec, speed); |
||
| 362 | data->desired_speed = 6.0f; |
||
| 363 | } else if ((wank.v[1] < 0.0f && dot_d > 0.0) || -GetOpponentsSectionWidth(pOpponent_spec, data->section_no) > wank.v[1]) { |
||
| 364 | car_spec->curvature = -MaxCurvatureForCarSpeed(car_spec, speed); |
||
| 365 | data->desired_speed = 6.0f; |
||
| 366 | } else if (wank.v[1] > radius) { |
||
| 367 | car_spec->curvature = MaxCurvatureForCarSpeed(car_spec, speed) * 0.05f; |
||
| 368 | data->desired_speed = 80.0f; |
||
| 369 | } else if (-radius > wank.v[1]) { |
||
| 370 | car_spec->curvature = -(MaxCurvatureForCarSpeed(car_spec, speed) * 0.05f); |
||
| 371 | data->desired_speed = 80.0f; |
||
| 372 | } else { |
||
| 373 | car_spec->curvature = 0.0f; |
||
| 374 | data->desired_speed = 80.0f; |
||
| 375 | } |
||
| 376 | } |
||
| 377 | if (just_fucking_brake) { |
||
| 378 | car_spec->brake_force = car_spec->M * 15.0f; |
||
| 379 | car_spec->acc_force = 0.0f; |
||
| 380 | } else { |
||
| 381 | if (GetOpponentsNextSection(pOpponent_spec, data->section_no) != -1) { |
||
| 382 | next_turning_radius = pOpponent_spec->car_spec->car_master_actor->t.t.translate.t.v[0] * -wank.v[2] + pOpponent_spec->car_spec->car_master_actor->t.t.translate.t.v[2] * wank.v[0]; |
||
| 383 | next_corner_size = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[0] * -wank.v[2]; |
||
| 384 | next_turning_radius = next_turning_radius - (GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no)->v[2] * wank.v[0] + next_corner_size); |
||
| 385 | // FIXME: added temporary variable |
||
| 386 | float v104 = -wank.v[2] * not_our_dir->v[0] + not_our_dir->v[2] * wank.v[0]; |
||
| 387 | if (v104 * next_turning_radius > 0.0f) { |
||
| 388 | goal_width = 0.0f; |
||
| 389 | speed2d = speed * speed / 24.0f + speed * 1.5f; |
||
| 390 | BrVector3Copy(&p, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 391 | BrVector3Scale(&start, not_our_dir, -(next_turning_radius / v104)); |
||
| 392 | BrVector3Accumulate(&start, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 393 | section_no = data->section_no; |
||
| 394 | for (sx = 0; GetOpponentsNextSection(pOpponent_spec, section_no) != -1 && sx < 4; sx++) { |
||
| 395 | BrVector3Copy(&next, GetOpponentsSectionFinishNodePoint(pOpponent_spec, GetOpponentsNextSection(pOpponent_spec, section_no))); |
||
| 396 | next_width = GetOpponentsSectionWidth(pOpponent_spec, GetOpponentsNextSection(pOpponent_spec, section_no)); |
||
| 397 | width = GetOpponentsSectionWidth(pOpponent_spec, data->section_no); |
||
| 398 | StraightestArcForCorner(&corner_speed, &corner_speed2, &dot_a, &p, &start, &next, &p, &start, width, next_width); |
||
| 399 | dot_a *= WORLD_SCALE; |
||
| 400 | goal_width += dot_a; |
||
| 401 | if (goal_width > speed2d) { |
||
| 402 | break; |
||
| 403 | } |
||
| 404 | corner_speed *= WORLD_SCALE; |
||
| 405 | corner_speed2 *= WORLD_SCALE; |
||
| 406 | stopping_distance = CornerFudge(car_spec) * CornerFudge(car_spec) * (corner_speed * 10.0); |
||
| 407 | desired_speed = sqrtf(stopping_distance); |
||
| 408 | if (GetOpponentsSectionMaxSpeed(pOpponent_spec, data->section_no, 1) < desired_speed) { |
||
| 409 | desired_speed = GetOpponentsSectionMaxSpeed(pOpponent_spec, data->section_no, 1); |
||
| 410 | stopping_distance = desired_speed * desired_speed; |
||
| 411 | } |
||
| 412 | if (goal_width - corner_speed2 < (speed * speed - stopping_distance) / 24.0f + desired_speed * 1.5f && data->desired_speed > desired_speed) { |
||
| 413 | data->desired_speed = desired_speed; |
||
| 414 | } |
||
| 415 | BrVector3Copy(&p, &start); |
||
| 416 | BrVector3Copy(&start, &next); |
||
| 417 | section_no = GetOpponentsNextSection(pOpponent_spec, section_no); |
||
| 418 | } |
||
| 419 | } |
||
| 420 | } |
||
| 421 | effective_speed_factor = CAR_SPEC_GET_SPEED_FACTOR(car_spec); |
||
| 422 | acc_factor = MAX(1.0f, effective_speed_factor); |
||
| 423 | if (engine_damage > 50 && engine_damage < 98) { |
||
| 424 | acc_factor -= (engine_damage - 50) * 0.0125f; |
||
| 425 | } else if (engine_damage >= 98) { |
||
| 426 | acc_factor -= 0.6f; |
||
| 427 | } |
||
| 428 | if (trans_damage > 50 && trans_damage < 98) { |
||
| 429 | acc_factor -= (trans_damage - 50) * 0.00625f; |
||
| 430 | } else if (trans_damage >= 98) { |
||
| 431 | acc_factor -= 0.3f; |
||
| 432 | } |
||
| 433 | if (engine_damage >= 99 || trans_damage >= 99) { |
||
| 434 | acc_factor = 0.0f; |
||
| 435 | } |
||
| 436 | max_acc = acc_factor * 10.0f; |
||
| 437 | // TODO: ?? corner_speed2[10] = v30; |
||
| 438 | error = data->desired_speed * effective_speed_factor - speed; |
||
| 439 | acc = (error - data->prev_acc_error) * 1000.0f / gFrame_period_for_this_munging * 0.1f + error + data->prev_acc; |
||
| 440 | if (acc > max_acc) { |
||
| 441 | acc = max_acc; |
||
| 442 | } |
||
| 443 | if (acc < -max_acc) { |
||
| 444 | acc = -max_acc; |
||
| 445 | } |
||
| 446 | data->prev_acc = acc; |
||
| 447 | data->prev_acc_error = error; |
||
| 448 | acc = car_spec->M * acc; |
||
| 449 | if (acc <= 0.0f) { |
||
| 450 | car_spec->acc_force = 0.0f; |
||
| 451 | car_spec->brake_force = -acc; |
||
| 452 | } else { |
||
| 453 | car_spec->acc_force = acc; |
||
| 454 | car_spec->brake_force = 0.0f; |
||
| 455 | } |
||
| 456 | } |
||
| 457 | return eFPR_OK; |
||
| 458 | } |
||
| 459 | |||
| 460 | BrFatal("C:\\Msdev\\Projects\\DethRace\\OPPOPROC.C", 1420, "C:\\Msdev\\Projects\\DethRace\\OPPOPROC.C line %d", 140); |
||
| 461 | return eFPR_OK; |
||
| 462 | } |
||
| 463 | |||
| 464 | // IDA: tFollow_path_result __usercall FollowCheatyPath@<EAX>(tOpponent_spec *pOpponent_spec@<EAX>) |
||
| 465 | tFollow_path_result FollowCheatyPath(tOpponent_spec* pOpponent_spec) { |
||
| 466 | tFollow_path_data* data; |
||
| 467 | br_vector3 a; |
||
| 468 | br_vector3 p; |
||
| 469 | br_vector3 section_v; |
||
| 470 | br_vector3 car_to_end; |
||
| 471 | br_vector3 car_to_intersect; |
||
| 472 | br_vector3* start; |
||
| 473 | br_vector3* finish; |
||
| 474 | br_scalar t; |
||
| 475 | br_scalar frame_period_in_secs; |
||
| 476 | //br_scalar distance_left; // Pierre-Marie Baty -- unused variable |
||
| 477 | br_scalar distance_to_end; |
||
| 478 | br_scalar distance_to_intersect; |
||
| 479 | br_scalar section_min; |
||
| 480 | br_scalar section_max; |
||
| 481 | br_scalar desired_speed_BRU; |
||
| 482 | LOG_TRACE("(%p)", pOpponent_spec); |
||
| 483 | |||
| 484 | data = &pOpponent_spec->follow_path_data; |
||
| 485 | start = GetOpponentsSectionStartNodePoint(pOpponent_spec, pOpponent_spec->follow_path_data.section_no); |
||
| 486 | finish = GetOpponentsSectionFinishNodePoint(pOpponent_spec, pOpponent_spec->follow_path_data.section_no); |
||
| 487 | if ((pOpponent_spec->follow_path_data.cheating ^ pOpponent_spec->cheating) != 0) { |
||
| 488 | data->cheating = pOpponent_spec->cheating; |
||
| 489 | if (data->cheating) { |
||
| 490 | dr_dprintf("%s: Dematerialising", pOpponent_spec->car_spec->driver_name); |
||
| 491 | BrVector3Sub(§ion_v, finish, start); |
||
| 492 | BrVector3Sub(&car_to_end, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, start); |
||
| 493 | t = BrVector3Dot(§ion_v, &car_to_end) / BrVector3LengthSquared(§ion_v); |
||
| 494 | if (t < 0.0f) { |
||
| 495 | BrVector3Copy(&data->cheaty_intersect, start); |
||
| 496 | } else if (t > 1.f) { |
||
| 497 | BrVector3Copy(&data->cheaty_intersect, finish); |
||
| 498 | } else { |
||
| 499 | BrVector3Scale(&data->cheaty_intersect, §ion_v, t); |
||
| 500 | BrVector3Accumulate(&data->cheaty_intersect, start); |
||
| 501 | } |
||
| 502 | BrVector3Sub(&car_to_intersect, &data->cheaty_intersect, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 503 | distance_to_intersect = BrVector3Length(&car_to_intersect); |
||
| 504 | frame_period_in_secs = gFrame_period_for_this_munging / 1000.0f * 20.0f; |
||
| 505 | TurnOpponentPhysicsOff(pOpponent_spec); |
||
| 506 | if (distance_to_intersect >= frame_period_in_secs) { |
||
| 507 | data->moving_to_intersect = 1; |
||
| 508 | BrVector3Normalise(&car_to_intersect, &car_to_intersect); |
||
| 509 | BrVector3Scale(&car_to_intersect, &car_to_intersect, frame_period_in_secs); |
||
| 510 | BrVector3Accumulate(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &car_to_intersect); |
||
| 511 | return eFPR_OK; |
||
| 512 | } else { |
||
| 513 | data->moving_to_intersect = 0; |
||
| 514 | BrVector3Copy(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &data->cheaty_intersect); |
||
| 515 | return eFPR_OK; |
||
| 516 | } |
||
| 517 | } |
||
| 518 | BrVector3Sub(&p, finish, start); |
||
| 519 | PointActorAlongThisBloodyVector(pOpponent_spec->car_spec->car_master_actor, &p); |
||
| 520 | BrVector3Sub(&a, finish, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 521 | distance_to_end = BrVector3Length(&a); |
||
| 522 | dr_dprintf("%s: Rematerialising from FollowCheatyPath()...", pOpponent_spec->car_spec->driver_name); |
||
| 523 | if (data->section_no < 0) { |
||
| 524 | PDEnterDebugger("No useful section number in ProcessCheatyPath()"); |
||
| 525 | } |
||
| 526 | |||
| 527 | section_max = GetOpponentsSectionMaxSpeed(pOpponent_spec, data->section_no, 1); |
||
| 528 | section_min = GetOpponentsSectionMinSpeed(pOpponent_spec, data->section_no, 1); |
||
| 529 | |||
| 530 | if (section_max < 255) { |
||
| 531 | desired_speed_BRU = section_max / WORLD_SCALE; |
||
| 532 | } else if (section_min > 0) { |
||
| 533 | desired_speed_BRU = section_min / WORLD_SCALE; |
||
| 534 | } else { |
||
| 535 | desired_speed_BRU = MIN(7.0f, MAX(1.0f, distance_to_end * 2.0f)); |
||
| 536 | } |
||
| 537 | if (RematerialiseOpponentOnNearestSection(pOpponent_spec, desired_speed_BRU)) { |
||
| 538 | pOpponent_spec->car_spec->brake_force = 0.0f; |
||
| 539 | pOpponent_spec->car_spec->acc_force = 0.0f; |
||
| 540 | if (distance_to_end >= 5.0f) { |
||
| 541 | pOpponent_spec->car_spec->acc_force = pOpponent_spec->car_spec->M / 2.0f; |
||
| 542 | } else { |
||
| 543 | pOpponent_spec->car_spec->brake_force = pOpponent_spec->car_spec->M * 15.0f; |
||
| 544 | } |
||
| 545 | return eFPR_OK; |
||
| 546 | } |
||
| 547 | data->cheating = 1; |
||
| 548 | } |
||
| 549 | frame_period_in_secs = gFrame_period_for_this_munging / 1000.0f * 20.0f; |
||
| 550 | if (data->moving_to_intersect) { |
||
| 551 | BrVector3Sub(&car_to_intersect, &data->cheaty_intersect, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 552 | distance_to_intersect = BrVector3Length(&car_to_intersect); |
||
| 553 | if (distance_to_intersect < frame_period_in_secs) { |
||
| 554 | data->moving_to_intersect = 0; |
||
| 555 | BrVector3Copy(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &data->cheaty_intersect); |
||
| 556 | } else { |
||
| 557 | BrVector3Normalise(&car_to_intersect, &car_to_intersect); |
||
| 558 | BrVector3Scale(&car_to_intersect, &car_to_intersect, frame_period_in_secs); |
||
| 559 | BrVector3Accumulate(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &car_to_intersect); |
||
| 560 | } |
||
| 561 | return eFPR_OK; |
||
| 562 | } |
||
| 563 | |||
| 564 | BrVector3Sub(&p, finish, start); |
||
| 565 | BrVector3Normalise(&p, &p); |
||
| 566 | while (frame_period_in_secs > 0.0f) { |
||
| 567 | BrVector3Sub(&a, finish, &pOpponent_spec->car_spec->car_master_actor->t.t.translate.t); |
||
| 568 | distance_to_end = BrVector3Length(&a); |
||
| 569 | if (distance_to_end < frame_period_in_secs) { |
||
| 570 | BrVector3Accumulate(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &a); |
||
| 571 | frame_period_in_secs -= distance_to_end; |
||
| 572 | dr_dprintf("%s: ProcessFollowPath() - current section %d(#%d) (cheating)", pOpponent_spec->car_spec->driver_name, data->section_no, GetOpponentsRealSection(pOpponent_spec, data->section_no)); |
||
| 573 | data->section_no = GetOpponentsNextSection(pOpponent_spec, data->section_no); |
||
| 574 | if (data->section_no == -1) { |
||
| 575 | pOpponent_spec->car_spec->acc_force = 0.0f; |
||
| 576 | pOpponent_spec->car_spec->brake_force = 0.0f; |
||
| 577 | dr_dprintf("%s: ProcessFollowPath() - reached end of path while cheating", pOpponent_spec->car_spec->driver_name); |
||
| 578 | return eFPR_end_of_path; |
||
| 579 | } |
||
| 580 | dr_dprintf("%s: ProcessFollowPath() - next section %d(#%d) (cheating)", pOpponent_spec->car_spec->driver_name, data->section_no, GetOpponentsRealSection(pOpponent_spec, data->section_no)); |
||
| 581 | start = GetOpponentsSectionStartNodePoint(pOpponent_spec, data->section_no); |
||
| 582 | finish = GetOpponentsSectionFinishNodePoint(pOpponent_spec, data->section_no); |
||
| 583 | BrVector3Sub(&p, finish, start); |
||
| 584 | BrVector3Normalise(&p, &p); |
||
| 585 | } else { |
||
| 586 | BrVector3Scale(&p, &p, frame_period_in_secs); |
||
| 587 | BrVector3Accumulate(&pOpponent_spec->car_spec->car_master_actor->t.t.translate.t, &p); |
||
| 588 | frame_period_in_secs = 0.0; |
||
| 589 | } |
||
| 590 | } |
||
| 591 | return eFPR_OK; |
||
| 592 | } |