BALLINT.CPP 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. /******************************************************************************
  2. *******************************************************************************
  3. Ball-Player interaction routines...
  4. ******************************************************************************
  5. *****************************************************************************/
  6. #include <stdio.h>
  7. #include "audio.h"
  8. #include "defines.h"
  9. #include "externs.h"
  10. #include "global.h"
  11. #include "data.h"
  12. #include "3deng.h"
  13. extern capfrm *player_p;
  14. extern mcap *mcaps;
  15. /******************************************************************************
  16. *****************************************************************************/
  17. void out_mcball_coords()
  18. {
  19. char str1[50];
  20. float x,y,z;
  21. short an,cp,frms;
  22. char ball_in;
  23. for (an=0; an<117; an++)
  24. {
  25. frms=mcaps[an].capfrms;
  26. ball_in=0;
  27. for (cp=0; cp<frms; cp++)
  28. {
  29. float *p=&player_p[mcaps[an].cappts+(cp)][(23*3)+1];
  30. if (*(p+1)<0)
  31. {
  32. // Ball not included...
  33. if (ball_in)
  34. {
  35. // Output last pos. of ball...
  36. sprintf(str1,"%d Released frms=%d cp=%d x=%1.3f y=%1.3f z=%1.3f\n",an,frms,cp,x,y,z);
  37. printf(str1);
  38. cp=frms;
  39. }
  40. }
  41. else
  42. {
  43. x=*p++;
  44. z=*p++;
  45. y=-*p++;
  46. if (!ball_in)
  47. {
  48. // Contact...
  49. sprintf(str1,"%d contact frms=%d cp=%d x=%1.3f y=%1.3f z=%1.3f\n",an,frms,cp,x,y,z);
  50. printf(str1);
  51. ball_in=1;
  52. }
  53. }
  54. }
  55. if (!ball_in)
  56. {
  57. // Haven't came across ball yet...
  58. sprintf(str1,"%d Ball not included.\n",an);
  59. printf(str1);
  60. }
  61. }
  62. }
  63. /******************************************************************************
  64. *****************************************************************************/
  65. void get_mcball_coords(match_player *player)
  66. {
  67. short an=player->ls_anim;
  68. float cp=player->ls_frm;
  69. float *p=&player_p[mcaps[an].cappts+(short)(cp*mcaps[an].capfrms)][(23*3)+1];
  70. float z=*(p+1);
  71. if (z>0)
  72. {
  73. float x=*p;
  74. float y=-*(p+2);
  75. float d=calc_dist(x,y);
  76. x=x/d;
  77. y=y/d;
  78. ballx=player->tm_x+d*((x*player->tm_xdis)-(y*player->tm_ydis));
  79. bally=player->tm_y+d*((y*player->tm_xdis)+(x*player->tm_ydis));
  80. ballz=z;
  81. }
  82. else
  83. {
  84. ballx=player->tm_x;
  85. bally=player->tm_y;
  86. ballz=ball_diam/2;
  87. }
  88. }
  89. /******************************************************************************
  90. *****************************************************************************/
  91. void user_header(match_player *player)
  92. {
  93. float power;
  94. if ((uf1) && (!uf2) && (in_header_rng))
  95. {
  96. if (um)
  97. {
  98. // Shoot header in joystick dir.
  99. power=(abs(angle_to_xy(ux,uy,ballxdis,ballydis)))
  100. *player->tm_pow/16+(MIN_HEADER_POW/16);
  101. ballxdis=ux*power;
  102. ballydis=uy*power;
  103. ballzdis=1;
  104. new_shot(player->tm_player);
  105. launch_ball(-1); // Set up spin vector.
  106. }
  107. else
  108. {
  109. // head in dir facing.
  110. power=(abs(angle_to_xy(player->tm_xdis,player->tm_ydis,ballxdis,ballydis)))
  111. *player->tm_pow/16+(MIN_HEADER_POW/16);
  112. ballxdis=player->tm_xdis*power;
  113. ballydis=player->tm_ydis*power;
  114. ballzdis=1;
  115. new_shot(player->tm_player);
  116. launch_ball(1); // Set up spin vector.
  117. }
  118. }
  119. if ((uf1) && (!uf2) && (!in_header_rng))
  120. {
  121. if (um)
  122. {
  123. // punt header in joystick dir.
  124. power=(abs(angle_to_xy(ux,uy,ballxdis,ballydis)))
  125. *player->tm_pow/16+(MIN_HEADER_POW/16);
  126. ballxdis=ux*power;
  127. ballydis=uy*power;
  128. ballzdis=4;
  129. launch_ball(1); // Set up spin vector.
  130. }
  131. else
  132. {
  133. // header vertical.
  134. ballxdis=ballxdis/(player->tm_cont/16);
  135. ballydis=ballydis/(player->tm_cont/16);
  136. ballzdis=4+(ball_speed/(player->tm_cont/12));
  137. launch_ball(0); // Set up spin vector.
  138. }
  139. }
  140. if ((uf2) && (!uf1))
  141. // Header pass...
  142. {
  143. if (um)
  144. {
  145. // head in joystick dir.
  146. float x,y;
  147. x=player->tm_xdis;
  148. y=player->tm_ydis;
  149. player->tm_xdis=ux;
  150. player->tm_ydis=uy; // Force joystick as orientation!
  151. int p=pass_decide(player,in_cross_area);
  152. make_pass(player,p,in_cross_area);
  153. player->tm_xdis=x;
  154. player->tm_ydis=y; // Restore orientation!
  155. launch_ball(1); // Set up spin vector.
  156. }
  157. else
  158. {
  159. // head in dir facing.
  160. heading_ball=1;
  161. int p=pass_decide(player,in_cross_area);
  162. make_pass(player,p,in_cross_area);
  163. launch_ball(1); // Set up spin vector.
  164. }
  165. }
  166. if ((!uf1) && (!uf2))
  167. {
  168. // Head down to grnd...
  169. if (um)
  170. {
  171. // downward header in joystick dir.
  172. ballxdis=ux*(128-player->tm_cont)/16;
  173. ballydis=uy*(128-player->tm_cont)/16;
  174. ballzdis=-1;
  175. launch_ball(-1); // Set up spin vector.
  176. }
  177. else
  178. {
  179. // downward header in dir facing.
  180. ballxdis=player->tm_xdis*(128-player->tm_cont)/16;
  181. ballydis=player->tm_ydis*(128-player->tm_cont)/16;
  182. ballzdis=-1;
  183. launch_ball(-1); // Set up spin vector.
  184. }
  185. }
  186. holder_lose_ball();
  187. ball_inair=TRUE;
  188. stop_ball_spin();
  189. init_anim(player,MC_S_HEAD);
  190. // float bd=calc_dist(ballxdis,ballydis);
  191. // ballx=player->tm_x+(ballxdis*(HEADER_CONTACT+1)/bd);
  192. // bally=player->tm_y+(ballydis*(HEADER_CONTACT+1)/bd);
  193. // ballz=PLAYER_HEIGHT+player->tm_z;
  194. action="Header";
  195. }
  196. /******************************************************************************
  197. *****************************************************************************/
  198. void head_ball(match_player *player)
  199. {
  200. last_touch=player->tm_player;
  201. if (last_touch!=KP_A && last_touch!=KP_B)
  202. pre_kp_touch=last_touch;
  203. reset_shot();
  204. int p=0;
  205. set_pos_flags(player);
  206. if (!player->control)
  207. reselect();
  208. if (player->control)
  209. user_header(player);
  210. else
  211. {
  212. if ((keeper_a_in_box && player->tm_player==KP_A && (cannot_pick_up<1 || cannot_pick_up>11))
  213. || (keeper_b_in_box && player->tm_player==KP_B && (cannot_pick_up<1 || cannot_pick_up<12)))
  214. // Attempt to catch ball...
  215. {
  216. control_ball(player); // attempt to bring ball under control.
  217. before=100;
  218. }
  219. else
  220. {
  221. if (!head_shoot_decide(player))
  222. {
  223. if (!head_punt_decide(player))
  224. {
  225. heading_ball=1;
  226. if (in_cross_area)
  227. {
  228. p=(pass_decide(player,TRUE));
  229. if (p)
  230. make_pass(player,p,TRUE);
  231. }
  232. if (!p)
  233. {
  234. // PASS!
  235. p=(pass_decide(player,FALSE));
  236. if (p)
  237. make_pass(player,p,FALSE);
  238. }
  239. heading_ball=FALSE;
  240. if (!p)
  241. {
  242. if (opp_around(ballx,bally,player->tm_player))
  243. {
  244. ballxdis=-ballxdis/2;
  245. ballydis=-ballydis/2;
  246. ballxdis=ballxdis+(((((float)(seed&15))-7)/16)*ball_speed);
  247. ballydis=ballydis+(((((float)(seed&63))-31)/64)*ball_speed);
  248. }
  249. else
  250. {
  251. // header vertical.
  252. ballxdis=ballxdis/(player->tm_cont/16);
  253. ballydis=ballydis/(player->tm_cont/16);
  254. ballzdis=4+(ball_speed/(player->tm_cont/12));
  255. }
  256. }
  257. }
  258. }
  259. }
  260. if (before!=100)
  261. // Keeper doesn't have ball...
  262. {
  263. holder_lose_ball();
  264. action="Header";
  265. }
  266. }
  267. }
  268. /******************************************************************************
  269. *****************************************************************************/
  270. void ball_at_contact(match_player *player)
  271. {
  272. float cx,cy,cz;
  273. rotate_offs(player->tm_anim,cx,cy,cz,player->tm_xdis,player->tm_ydis);
  274. ballx=player->tm_x+cx;
  275. bally=player->tm_y+cy;
  276. ballz=player->tm_z+cz;
  277. }
  278. /******************************************************************************
  279. *****************************************************************************/
  280. void rebound_off_plr(match_player *player)
  281. {
  282. penalty_shot=FALSE;
  283. last_touch=player->tm_player;
  284. if (last_touch!=KP_A && last_touch!=KP_B)
  285. pre_kp_touch=last_touch;
  286. can_be_offside=TRUE;
  287. if (save_block<0)
  288. {
  289. // Keeper block save...
  290. // How close???
  291. float d=SAVE_CONTACT-calc_dist(ballx-(player->tm_x+save_xoff),bally-(player->tm_y+save_yoff));
  292. float skill=d*player->tm_flair/(SAVE_CONTACT*128);
  293. float bx,by;
  294. // New ball displacement...
  295. bx=(-(1.-skill)*ballxdis)+(skill*player->go_txdis);
  296. by=(-(1.-skill)*ballydis)+(skill*player->go_tydis);
  297. ballxdis=bx;
  298. ballydis=by;
  299. if (ballz>SAVE_HEAD_HGT)
  300. // Up!
  301. ballzdis=3+ballzdis*VERT_BALL_DAMP;
  302. else
  303. // Damp!
  304. ballzdis=ballzdis*VERT_BALL_DAMP;
  305. action="Rebound";
  306. reset_shot();
  307. }
  308. else
  309. {
  310. ballxdis=-ballxdis/2;
  311. ballydis=-ballydis/2;
  312. ballxdis=ballxdis+(((((float)(seed&15))-7)/16)*ball_speed);
  313. ballydis=ballydis+(((((float)(seed&63))-31)/64)*ball_speed);
  314. float bd=calc_dist(ballxdis,ballydis);
  315. ballx=player->tm_x+(ballxdis*(TOUCHB_BOX+1)/bd);
  316. bally=player->tm_y+(ballydis*(TOUCHB_BOX+1)/bd);
  317. ballzdis=ballzdis*VERT_BALL_DAMP;
  318. action="Rebound";
  319. reset_shot();
  320. }
  321. }
  322. /******************************************************************************
  323. *****************************************************************************/
  324. void has_ball(match_player *player)
  325. {
  326. if (comm_pass>=0 && !(seed&(32+16+8)))
  327. {
  328. if ((prev_touch>11 && player->tm_player>11)
  329. || (prev_touch<12 && player->tm_player<12))
  330. {
  331. if (comm_pass_type==1)
  332. // Backheel...
  333. if (comsetp)
  334. {
  335. PlayCommentaryMessage(CP_SETPIECE);
  336. comsetp=0;
  337. }
  338. else
  339. PlayCommentaryMessage(CP_NICEMOVE);
  340. else
  341. if (comm_pass_type==2)
  342. // Cross...
  343. if (comsetp)
  344. {
  345. PlayCommentaryMessage(CP_SETPIECE);
  346. comsetp=0;
  347. }
  348. else
  349. PlayCommentaryMessage(CP_TARGET);
  350. else
  351. // Normal...
  352. {
  353. float prx=teams[prev_touch-1].tm_x;
  354. float pry=teams[prev_touch-1].tm_y;
  355. float tx=player->tm_x;
  356. float ty=player->tm_y;
  357. short d=calc_dist(prx-tx,pry-ty);
  358. if (d>LONG_PASS_DIST)
  359. PlayCommentaryMessage(CP_LONG);
  360. else
  361. PlayCommentaryMessage(CP_SHORT);
  362. }
  363. }
  364. /*
  365. else
  366. {
  367. // Not guy aimed for...
  368. if ((prev_touch>11 && player->tm_player<12)
  369. || (prev_touch<12 && player->tm_player>11))
  370. // Bad pass...
  371. if (comm_pass || comm_pass_type==2)
  372. // Long try...
  373. PlayCommentaryMessage(FP_LONG);
  374. else
  375. if (comm_pass_type==1)
  376. // Backheel...
  377. PlayCommentaryMessage(FP_LOOSE);
  378. else
  379. PlayCommentaryMessage(FP_SHORT);
  380. }
  381. */
  382. comm_pass=-1;
  383. }
  384. else
  385. {
  386. if (say_names && !opponents_really_close)
  387. {
  388. short intone=0;
  389. if (ball_poss<12)
  390. {
  391. intone=ballx/cntspot_x;
  392. }
  393. else
  394. {
  395. intone=(pitch_len-ballx)/cntspot_x;
  396. }
  397. PlayTeamSample(real_player(ball_poss),intone);
  398. }
  399. }
  400. }
  401. /******************************************************************************
  402. *****************************************************************************/
  403. void hold_ball(match_player *player)
  404. {
  405. if (!set_piece_on)
  406. {
  407. // calculate position of ball at feet!
  408. float bx,by;
  409. bx=ballx;
  410. by=bally;
  411. player->tm_poss++;
  412. ballxdis=player->go_txdis;
  413. ballydis=player->go_tydis;
  414. ballzdis=0; // Ground ball.
  415. ballz=ball_diam/2;
  416. float x=player->tm_xdis;
  417. float y=player->tm_ydis;
  418. last_touch=player->tm_player;
  419. if (last_touch!=KP_A && last_touch!=KP_B)
  420. pre_kp_touch=last_touch;
  421. if (ball_in_hands)
  422. {
  423. if (player->tm_act==THROW_ACT)
  424. {
  425. // Ball above player's head!
  426. ballz=player->tm_z+(PLAYER_HEIGHT+4);
  427. ballx=player->tm_x;
  428. bally=player->tm_y;
  429. ball_in_hands=TRUE;
  430. }
  431. else
  432. {
  433. if (player->int_move!=I_GET_UP || !player->int_cnt)
  434. {
  435. if (player->tm_act==SAVE_ACT)
  436. {
  437. ballz=player->tm_z+save_zoff;
  438. ballx=player->tm_x+save_xoff;
  439. bally=player->tm_y+save_yoff;
  440. player->dir_mode=5;
  441. }
  442. else
  443. {
  444. ballz=player->tm_z+(PLAYER_HEIGHT/2);
  445. ballx=player->tm_x+(x*IN_HANDS_DIST);
  446. bally=player->tm_y+(y*IN_HANDS_DIST);
  447. if (player->tm_act!=KPHOLD_ACT)
  448. player->dir_mode=2;
  449. else
  450. player->dir_mode=3;
  451. }
  452. }
  453. }
  454. }
  455. else
  456. {
  457. if (player->tm_poss==HAS_BALL_DELAY)
  458. has_ball(player);
  459. // inc_poss(player->tm_player);
  460. double n;
  461. player->dir_mode=0;
  462. ball_inair=FALSE;
  463. if (player->tm_act==RUN_ACT)
  464. {
  465. bx=player->tm_x+(x*(AT_FEET_DIST+(4.*(modf(player->tm_frm,&n)-.5))));
  466. by=player->tm_y+(y*(AT_FEET_DIST+(4.*(modf(player->tm_frm,&n)-.5))));
  467. }
  468. else
  469. {
  470. if (!dead_ball_cnt)
  471. {
  472. // If player is in a set-piece then no need to move position of ball...
  473. bx=player->tm_x+(x*AT_FEET_DIST);
  474. by=player->tm_y+(y*AT_FEET_DIST);
  475. }
  476. }
  477. if (player->tm_ftime<-1)
  478. {
  479. // Just controlled ball... (so tween to held pos.)
  480. // ftime (-2 to -10)...
  481. if (player->tm_ftime==-2)
  482. get_mcball_coords(player);
  483. else
  484. {
  485. ballx+=((bx-ballx)*(-2-player->tm_ftime)/8);
  486. bally+=((by-bally)*(-2-player->tm_ftime)/8);
  487. }
  488. // ballx=bx;
  489. // bally=by;
  490. if (--player->tm_ftime==-11)
  491. player->tm_ftime=0;
  492. }
  493. else
  494. {
  495. // No tweening...
  496. ballx=bx;
  497. bally=by;
  498. }
  499. }
  500. if (((player->tm_player==KP_A) || (player->tm_player==KP_B))
  501. && (player->tm_act==STAND_ACT) && (ball_in_hands))
  502. init_kphold_act(player);
  503. }
  504. else
  505. {
  506. last_touch=player->tm_player;
  507. if (last_touch!=KP_A && last_touch!=KP_B)
  508. pre_kp_touch=last_touch;
  509. }
  510. }
  511. /******************************************************************************
  512. *****************************************************************************/
  513. void init_specials()
  514. {
  515. spec_kick_type=0;
  516. f1_down=FALSE;
  517. f2_down=FALSE;
  518. }
  519. /******************************************************************************
  520. *****************************************************************************/
  521. void collect_ball(match_player *player)
  522. {
  523. add_comp_pass(player->tm_player);
  524. if (player->tm_act==TACKLE_ACT)
  525. inc_twon(player->tm_player);
  526. if (!player->tm_leave)
  527. reset_leaves();
  528. // comm_pass=-1; //FIX
  529. prev_touch=last_touch;
  530. receiver_a=FALSE;
  531. receiver_b=FALSE;
  532. init_specials();
  533. if ((must_shoot) || (must_punt) || (must_pass))
  534. {
  535. must_shoot=-must_shoot;
  536. must_pass=-must_pass;
  537. must_punt=-must_punt;
  538. }
  539. if ((player->tm_player!=KP_A) && (player->tm_player!=KP_B))
  540. cannot_pick_up=player->tm_player;
  541. // Keeper can pick up ball...
  542. hold_ball(player);
  543. if ((ball_in_hands) && (player->tm_act!=SAVE_ACT))
  544. reset_all_ideas();
  545. stop_ball_spin();
  546. ball_poss=player->tm_player;
  547. player->tm_poss=1;
  548. if ((player->int_cnt) && (player->int_move==I_INTERCEPT))
  549. reset_ideas(player);
  550. action="Collect";
  551. reset_shot();
  552. penalty_shot=FALSE;
  553. if (player->tm_act==CONTROL_ACT)
  554. ball_at_contact(player);
  555. reselect();
  556. }
  557. /******************************************************************************
  558. *****************************************************************************/
  559. void control_difficulty(match_player *player)
  560. // Calculates difficulty factor (0 simple -> 128 impossible)!
  561. {
  562. float x=ballx-ballxdis; //take ball one step back!
  563. float y=bally-ballydis;
  564. x=x-player->tm_x; //offset to player.
  565. y=y-player->tm_y;
  566. int cside=get_dir(x,y); //contact side of player.
  567. cside=cside-player->face_dir;
  568. if (cside<0)
  569. cside=cside+8;
  570. if (cside>4)
  571. cside=8-cside;
  572. difficulty=cside*16; //direction difficulty!
  573. int s=ball_speed*2;
  574. if (player->tm_act==RUN_ACT)
  575. if (want_pass==player->tm_player)
  576. // He is expecting it so better chance of controlling ball!
  577. s+=2;
  578. else
  579. s+=4; // speed factor.
  580. if (player->tm_act==TACKLE_ACT)
  581. s+=8; // speed factor.
  582. if ((player->tm_act==SAVE_ACT) || (((player->tm_player==KP_A) || (player->tm_player==KP_B))
  583. && (ballz>PLAYER_HEIGHT/3)))
  584. s-=4; // Keeper saving!
  585. difficulty+=(6*s); //add speed difficulty!
  586. }
  587. /******************************************************************************
  588. *****************************************************************************/
  589. void active_control(match_player *player)
  590. {
  591. if (player->tm_ftime>=0)
  592. {
  593. float cx,cy,cz;
  594. rotate_offs(player->tm_anim,cx,cy,cz,player->tm_xdis,player->tm_ydis);
  595. ballx=player->tm_x+cx;
  596. bally=player->tm_y+cy;
  597. ballz=player->tm_z+cz;
  598. ballxdis=player->tm_xdis*(2+(ball_speed/(player->tm_cont/32)));
  599. ballydis=player->tm_ydis*(2+(ball_speed/(player->tm_cont/32)));
  600. ballzdis=1;
  601. last_touch=player->tm_player;
  602. if (last_touch!=KP_A && last_touch!=KP_B)
  603. pre_kp_touch=last_touch;
  604. player->tm_ftime=-1; // Continue animation!
  605. }
  606. }
  607. /******************************************************************************
  608. *****************************************************************************/
  609. void standard_fstep(match_player *player)
  610. {
  611. switch(player->tm_anim)
  612. {
  613. case(MC_D_HEAD):
  614. player->tm_fstep=MC_D_HEAD_FS;
  615. break;
  616. case(MC_CHEST):
  617. player->tm_fstep=MC_CHEST_FS;
  618. break;
  619. case(MC_TRAPL):
  620. case(MC_TRAPR):
  621. player->tm_fstep=MC_TRAP_FS;
  622. break;
  623. case(MC_SHOOTL):
  624. case(MC_SHOOTR):
  625. player->tm_fstep=MC_SHOOT_FS;
  626. break;
  627. case(MC_CHIPL):
  628. case(MC_CHIPR):
  629. player->tm_fstep=MC_CHIP_FS;
  630. break;
  631. case(MC_VOLLEYL):
  632. case(MC_VOLLEYR):
  633. player->tm_fstep=MC_VOLLEY_FS;
  634. break;
  635. case(MC_OVERHEAD):
  636. player->tm_fstep=MC_OVERHEAD_FS;
  637. break;
  638. case(MC_DV_HEAD):
  639. player->tm_fstep=MC_DV_HEAD_FS;
  640. break;
  641. case(MC_S_HEAD):
  642. player->tm_fstep=MC_S_HEAD_FS;
  643. break;
  644. case(MC_J_HEAD):
  645. player->tm_fstep=MC_J_HEAD_FS;
  646. break;
  647. }
  648. }
  649. /******************************************************************************
  650. *****************************************************************************/
  651. void control_ball(match_player *player)
  652. // Having made contact with ball,
  653. // the player must attempt to control it!
  654. {
  655. can_be_offside=TRUE;
  656. if (player->tm_act==CONTROL_ACT)
  657. {
  658. // Player has successfully controlled ball.
  659. if (player->tm_anim==MC_U_HEAD)
  660. // Head Control...(Bounce ball upward!)
  661. {
  662. active_control(player);
  663. }
  664. else
  665. {
  666. holder_lose_ball();
  667. collect_ball(player); //bring ball to feet!
  668. player->dir_mode=2;
  669. if (player->tm_anim!=MC_TRAPL && player->tm_anim!=MC_TRAPR)
  670. {
  671. standard_fstep(player); // Normal speed anim...
  672. ball_limbo(player->tm_player,1-player->tm_fstep); // Ball is motion captured to ground!
  673. }
  674. }
  675. }
  676. else
  677. {
  678. if (player->tm_act==TACKLE_ACT)
  679. player->go_step=TRUE; // He has touched the ball (no foul)!
  680. control_difficulty(player);
  681. if ((((player->tm_act!=SAVE_ACT) && (player->tm_z<1))
  682. || ((player->tm_act==SAVE_ACT) || (player->tm_player==KP_A)
  683. || (player->tm_player==KP_B) && (player->tm_z>PLAYER_HEIGHT/3)))
  684. && (seed+player->tm_cont>difficulty))
  685. {
  686. // Assume controlled ball is at feet level.
  687. holder_lose_ball();
  688. collect_ball(player); //bring ball to feet!
  689. }
  690. else
  691. rebound_off_plr(player); //could not control!
  692. }
  693. }
  694. /******************************************************************************
  695. *****************************************************************************/
  696. char control_interact(match_player *player)
  697. {
  698. if (player->tm_frm>=player->contact)
  699. {
  700. // Contact point exceeded...
  701. if (player->tm_anim!=MC_TRAPL && player->tm_anim!=MC_TRAPR)
  702. {
  703. player->tm_anim++;
  704. player->tm_anim--;
  705. }
  706. float px=player->tm_x;
  707. float py=player->tm_y;
  708. float pz=player->tm_z;
  709. float cx,cy,cz;
  710. rotate_offs(player->tm_anim,cx,cy,cz,player->tm_xdis,player->tm_ydis);
  711. px+=cx;
  712. py+=cy;
  713. pz+=cz;
  714. float d=calc_dist(ballx-px,bally-py);
  715. if (d>ball_speed+2 && d>8)
  716. return(FALSE);
  717. if (abs(ballz-pz)>prat/2)
  718. return(FALSE);
  719. // Good contact... (control ball)!
  720. return(TRUE);
  721. }
  722. return(FALSE);
  723. }
  724. /******************************************************************************
  725. *****************************************************************************/
  726. void ball_interact(match_player *player)
  727. {
  728. int act=player->tm_act;
  729. if (player->tm_poss<=0)
  730. {
  731. player->tm_poss=0;
  732. if (!((act==FALL_ACT) ||
  733. (act==RISE_ACT) || (act==RIDE_ACT) || (dead_ball_cnt))) //player not out of game.
  734. {
  735. if ((!((player->int_cnt!=0) && (player->int_move==I_KICKED)))
  736. && (!ball_in_hands))
  737. {
  738. if (act!=SAVE_ACT)
  739. {
  740. // Normal player...
  741. if (!just_scored && ((!ball_poss) || (ball_poss && teams[ball_poss-1].tm_act!=PICKUP_ACT)))
  742. {
  743. if (!ball_poss || (ball_poss && ball_poss<12 && player->tm_player>11)
  744. || (ball_poss>11 && player->tm_player<12))
  745. {
  746. // Ball is free or the opponent has ball...
  747. if (act==CONTROL_ACT && player->tm_ftime>=0 && control_interact(player))
  748. {
  749. // He has successfully controlled the ball!
  750. control_ball(player);
  751. }
  752. if (act==STRIKE_ACT && player->tm_ftime>=0 && control_interact(player))
  753. {
  754. // He has successfully struck the ball!
  755. strike_ball_off(player);
  756. }
  757. if (player->tm_act!=CONTROL_ACT && player->tm_act!=STRIKE_ACT)
  758. {
  759. if (!player->tm_strike && TOUCHB_BOX>=calc_dist(ballx-player->tm_x,bally-player->tm_y)
  760. && ballz<PLAYER_HEIGHT && (!penalty_game || player->tm_player==KP_A || player->tm_player==KP_B))
  761. {
  762. // Contact is made...
  763. receiver_a=FALSE;
  764. receiver_b=FALSE;
  765. if (!practice && (player->tm_leave>0) && (last_touch==player->tm_player))
  766. {
  767. init_foul(player->tm_player,FALSE,TRUE); // Indirect F.K. for touching ball again!
  768. }
  769. if ((ballz<player->tm_z+PLAYER_HEIGHT/2)
  770. && (ballz-ballzdis<player->tm_z+PLAYER_HEIGHT/2))
  771. {
  772. //Contact with ball at feet...
  773. if (act<=TURN_ACT || act==TACKLE_ACT || act==STEAL_ACT)
  774. control_ball(player);
  775. }
  776. else
  777. {
  778. if (ballz<player->tm_z+PLAYER_HEIGHT-3)
  779. {
  780. // At head and body height...
  781. if (act<=TURN_ACT || act==TACKLE_ACT || act==STEAL_ACT)
  782. rebound_off_plr(player);
  783. }
  784. }
  785. }
  786. }
  787. }
  788. }
  789. if (player->tm_leave<0)
  790. player->tm_leave=TRUE;
  791. }
  792. else
  793. {
  794. // Keeper save!
  795. if (player->tm_frm>(keeper_contact-0.00001))
  796. {
  797. // Contact with ball reached...
  798. if (keeper_will_save>0 || keep_dive)
  799. {
  800. // Keeper should connect with ball at contact point...
  801. if (keep_dive || (SAVE_CONTACT>calc_dist(ballx-(player->tm_x+save_xoff),bally-(player->tm_y+save_yoff))
  802. && !ball_in_goal))
  803. // Keeper has judged it well!
  804. {
  805. inc_saves(player->tm_player);
  806. shot_saved=25;
  807. keeper_will_save=-1;
  808. if (save_block && !keep_dive)
  809. {
  810. if (real_shot)
  811. {
  812. PlayCommentaryMessage(PM_BLOCK);
  813. inc_save(last_touch);
  814. }
  815. save_block=-1; // Rebound properly from block!
  816. rebound_off_plr(player); //could not control!
  817. ball_inair=TRUE;
  818. ballz=save_zoff;
  819. ballx=player->tm_x+player->go_txdis+save_xoff;
  820. bally=player->tm_y+player->go_tydis+save_yoff;
  821. save_block=0; // Rebound properly from block!
  822. }
  823. else
  824. {
  825. if (real_shot)
  826. {
  827. PlayCommentaryMessage(PM_CATCH);
  828. inc_save(last_touch);
  829. }
  830. holder_lose_ball();
  831. ball_in_hands=TRUE;
  832. collect_ball(player); //bring ball to feet!
  833. }
  834. keep_dive=FALSE;
  835. }
  836. else
  837. {
  838. // Ball too far!!!
  839. keeper_will_save=0; // Catch will change to block...
  840. if (!save_block)
  841. {
  842. // Must become desperate block instead of catch...
  843. if (ABS(player->tm_anim)<MC_BFOOTBL)
  844. {
  845. // Zone A save...(no right,left)
  846. player->tm_anim--;
  847. }
  848. else
  849. {
  850. player->tm_anim-=2;
  851. }
  852. player->go_cnt=(1-player->tm_frm)/player->tm_fstep;
  853. if (!player->tm_anim) // AFOOTB
  854. keeper_on_grnd=FALSE;
  855. if (keeper_on_grnd)
  856. player->int_cnt=player->go_cnt+2;
  857. else
  858. player->int_cnt=player->go_cnt+2;
  859. }
  860. }
  861. }
  862. }
  863. }
  864. }
  865. }
  866. }
  867. else
  868. {
  869. if ((player->contact>0) && (player->tm_act==KICK_ACT))
  870. {
  871. // Currently awaiting contact point in animation...
  872. // He's kicking the ball just now...
  873. ballx+=((player->tm_x+b_xoff)-ballx)*player->tm_frm/player->contact;
  874. bally+=((player->tm_y+b_yoff)-bally)*player->tm_frm/player->contact;
  875. ballz+=((player->tm_z+b_zoff)-ballz)*player->tm_frm/player->contact;
  876. }
  877. else
  878. {
  879. if (((ballz>=player->tm_z) && (ballz<PLAYER_HEIGHT+player->tm_z))
  880. || (act==THROW_ACT) || (act==SAVE_ACT) || (act=KPHOLD_ACT))
  881. {
  882. if (player->tm_player==ball_poss)
  883. hold_ball(player);
  884. else
  885. player->tm_poss=0; // doesnt have ball any more.
  886. }
  887. else
  888. {
  889. holder_lose_ball();
  890. }
  891. }
  892. }
  893. }
  894. /******************************************************************************
  895. *****************************************************************************/
  896. // Predicts ball coords from now till 50 turns ahead!
  897. void predict_ball()
  898. {
  899. struct stack{
  900. float x; float y; float z;
  901. float xd; float yd; float zd;
  902. int ba; int bs; int sw; float xys; float zs;
  903. float f_xys; float f_zs; int sp_b;};
  904. struct stack sp;
  905. sp.x=ballx;
  906. sp.y=bally;
  907. sp.z=ballz;
  908. sp.xd=ballxdis;
  909. sp.yd=ballydis;
  910. sp.zd=ballzdis;
  911. sp.ba=ball_inair;
  912. sp.bs=ball_still;
  913. sp.sw=swerve;
  914. sp.xys=ball_xyspin;
  915. sp.zs=ball_zspin;
  916. sp.f_xys=full_xyspin;
  917. sp.f_zs=full_zspin;
  918. sp.sp_b=spin_cnt;
  919. ns_ballx=ballx;
  920. ns_bally=bally;
  921. ns_ballz=ballz;
  922. float *ptr1=&ball_pred_tab[0][0];
  923. float *ptr2=&ns_ball_pred_tab[0][0];
  924. first_bounce=-1;
  925. prediction=TRUE;
  926. for (int i=0; i<50; i++)
  927. {
  928. // Ball with swerve!
  929. *ptr1++=ballx;
  930. *ptr1++=bally;
  931. *ptr1++=ballz;
  932. if (first_bounce<0 && ballz<=(ball_diam/2) && i>0)
  933. first_bounce=i;
  934. // Ball without swerve!
  935. *ptr2++=ns_ballx;
  936. *ptr2++=ns_bally;
  937. *ptr2++=ns_ballz;
  938. if (!ball_poss)
  939. ball_trajectory();
  940. else
  941. {
  942. if (teams[ball_poss-1].tm_act==TACKLE_ACT)
  943. {
  944. // Take into account deceleration of tackle action!
  945. ballx+=ballxdis*pow(TACKLE_DECEL,i);
  946. bally+=ballydis*pow(TACKLE_DECEL,i);
  947. ns_ballx+=ballxdis*pow(TACKLE_DECEL,i);
  948. ns_bally+=ballydis*pow(TACKLE_DECEL,i);
  949. }
  950. else
  951. {
  952. ballx+=ballxdis;
  953. bally+=ballydis;
  954. ns_ballx+=ballxdis;
  955. ns_bally+=ballydis;
  956. }
  957. }
  958. }
  959. spin_cnt=sp.sp_b;
  960. full_zspin=sp.f_zs;
  961. full_xyspin=sp.f_xys;
  962. ball_zspin=sp.zs;
  963. ball_xyspin=sp.xys;
  964. swerve=sp.sw;
  965. ball_still=sp.bs;
  966. ball_inair=sp.ba;
  967. ballzdis=sp.zd;
  968. ballydis=sp.yd;
  969. ballxdis=sp.xd;
  970. ballz=sp.z;
  971. bally=sp.y;
  972. ballx=sp.x;
  973. }
  974. /******************************************************************************
  975. *****************************************************************************/
  976. // Find no. of opponents near ball holder.
  977. void get_opp_near_ball(int holder)
  978. {
  979. opponents_near_holder=0; // Initialise count.
  980. opponents_really_close=0;
  981. int p;
  982. if (holder)
  983. {
  984. if (holder>11) // Get opposing team.
  985. p=0;
  986. else
  987. p=11;
  988. for (int i=p; i<p+11; i++)
  989. {
  990. if ((teams[i].guy_on>0) && (teams[i].tm_dist<=DRIB_DANGER_AREA))
  991. {
  992. opponents_near_holder++;
  993. if (teams[i].tm_dist<=MEGA_DANGER_AREA)
  994. opponents_really_close++;
  995. }
  996. }
  997. }
  998. }
  999. /******************************************************************************
  1000. *****************************************************************************/
  1001. void get_dist_pos(int pn)
  1002. {
  1003. float d,lowest;
  1004. int guy=pn;
  1005. for (int pos=2; pos<5; pos++)
  1006. {
  1007. lowest=2000;
  1008. for (int i=pn; i<pn+12; i++)
  1009. {
  1010. if (teams[i-1].guy_on>0)
  1011. {
  1012. d=teams[i-1].tm_dist;
  1013. if ((d<lowest) && (!teams[i-1].tm_pos))
  1014. {
  1015. guy=i;
  1016. lowest=d;
  1017. }
  1018. }
  1019. }
  1020. teams[guy-1].tm_pos=pos;
  1021. }
  1022. }
  1023. /******************************************************************************
  1024. *****************************************************************************/
  1025. // Updates player distances.
  1026. #define SELECTION_CIRCLE (prat*10)
  1027. void player_distances()
  1028. {
  1029. float px,py;
  1030. float ad=2000;
  1031. float bd=2000;
  1032. float d;
  1033. defense_a=cntspot_x;
  1034. defense_b=cntspot_x;
  1035. for (player_num=0; player_num<players; player_num++)
  1036. {
  1037. if (teams[player_num].guy_on>0)
  1038. {
  1039. px=teams[player_num].tm_x;
  1040. if (player_num<11)
  1041. {
  1042. if (px<defense_a && player_num)
  1043. defense_a=px;
  1044. d=calc_dist(pitch_len-teams[player_num].tm_x,cntspot_y-teams[player_num].tm_y);
  1045. if (d<(MIN_SHOOT_DIST+((float)teams[player_num].tm_pow*3)))
  1046. teams[player_num].tm_srng=TRUE;
  1047. else
  1048. teams[player_num].tm_srng=FALSE;
  1049. }
  1050. else
  1051. {
  1052. if ((player_num!=11) && (px>defense_b))
  1053. defense_b=px;
  1054. d=calc_dist(teams[player_num].tm_x,cntspot_y-teams[player_num].tm_y);
  1055. if (d<(MIN_SHOOT_DIST+((float)teams[player_num].tm_pow*3)))
  1056. teams[player_num].tm_srng=TRUE;
  1057. else
  1058. teams[player_num].tm_srng=FALSE;
  1059. }
  1060. px-=ballx;
  1061. py=teams[player_num].tm_y-bally;
  1062. d=calc_dist(px,py);
  1063. teams[player_num].tm_dist=d;
  1064. teams[player_num].tm_pos=0;
  1065. if (player_num>=players/2)
  1066. {
  1067. if (d<bd)
  1068. {
  1069. bd=d;
  1070. nearest_b=player_num+1;
  1071. }
  1072. }
  1073. else
  1074. {
  1075. if (d<ad)
  1076. {
  1077. ad=d;
  1078. nearest_a=player_num+1;
  1079. }
  1080. }
  1081. if (player_num!=(KP_A-1) && player_num!=(KP_B-1))
  1082. sel_circle[player_num]=(d<SELECTION_CIRCLE ? TRUE:FALSE);
  1083. else
  1084. sel_circle[player_num]=FALSE;
  1085. }
  1086. }
  1087. teams[nearest_a-1].tm_pos=1;
  1088. teams[nearest_b-1].tm_pos=1;
  1089. get_dist_pos(1);
  1090. get_dist_pos(12);
  1091. }
  1092. /******************************************************************************
  1093. *****************************************************************************/
  1094. // Return closest guy to the ball (from one team) who is not busy!
  1095. // p_num = first player in team.
  1096. int get_nearest_guy(int p_num)
  1097. {
  1098. int near_guy=0, closest=10000;
  1099. for (int i=p_num; i<p_num+11; i++)
  1100. {
  1101. if (teams[i].tm_act<=TURN_ACT) //player is not busy!
  1102. {
  1103. if (teams[i].tm_dist<closest)
  1104. {
  1105. near_guy=i+1; //This guy is closer!
  1106. closest=teams[i].tm_dist;
  1107. }
  1108. }
  1109. }
  1110. return(near_guy);
  1111. }
  1112. /******************************************************************************
  1113. *****************************************************************************/
  1114. void get_nearest()
  1115. {
  1116. if (receiver_a)
  1117. near_path_a=receiver_a;
  1118. else
  1119. near_path_a=get_near_path(0,TRUE);
  1120. if (receiver_b)
  1121. near_path_b=receiver_b;
  1122. else
  1123. near_path_b=get_near_path(11,TRUE);
  1124. }
  1125. /******************************************************************************
  1126. *****************************************************************************/
  1127. void holder_lose_ball()
  1128. {
  1129. if (ball_poss)
  1130. {
  1131. reset_ideas(&teams[ball_poss-1]);
  1132. if (ball_poss<12)
  1133. ball_released=OFFSIDE_REL_CNT;
  1134. else
  1135. ball_released=-OFFSIDE_REL_CNT;
  1136. short p=teams[ball_poss-1].tm_poss;
  1137. teams[ball_poss-1].tm_posst+=p*p/50; // Good dribbles will adjust performance.
  1138. teams[ball_poss-1].tm_poss=0;
  1139. ball_poss=0;
  1140. in_cross_area=FALSE;
  1141. ball_in_hands=FALSE;
  1142. must_punt=FALSE;
  1143. must_pass=FALSE;
  1144. must_shoot=FALSE;
  1145. }
  1146. }