jet.cc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /********************************************************************** <BR>
  2. This file is part of Crack dot Com's free source code release of
  3. Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
  4. information about compiling & licensing issues visit this URL</a>
  5. <PRE> If that doesn't help, contact Jonathan Clark at
  6. golgotha_source@usa.net (Subject should have "GOLG" in it)
  7. ***********************************************************************/
  8. #include "sound_man.hh"
  9. #include "objs/model_id.hh"
  10. #include "objs/model_draw.hh"
  11. #include "input.hh"
  12. #include "math/pi.hh"
  13. #include "math/trig.hh"
  14. #include "math/angle.hh"
  15. #include "resources.hh"
  16. #include "saver.hh"
  17. #include "map_cell.hh"
  18. #include "map.hh"
  19. #include "map_man.hh"
  20. #include "sound/sfx_id.hh"
  21. #include "objs/vehic_sounds.hh"
  22. #include "objs/jet.hh"
  23. #include "objs/fire.hh"
  24. #include "object_definer.hh"
  25. #include "objs/path_object.hh"
  26. #include "image_man.hh"
  27. static g1_team_icon_ref radar_im("bitmaps/radar/plane.tga");
  28. const i4_float FLY_HEIGHT = 1.5f;
  29. enum
  30. {
  31. TAKE_OFF=0,
  32. TAKE_OFF2,
  33. FLYING,
  34. DYING
  35. };
  36. static g1_object_type bomb_type;
  37. void g1_jet_init()
  38. {
  39. bomb_type = g1_get_object_type("dropped_bomb");
  40. }
  41. g1_object_definer<g1_jet_class>
  42. g1_jet_def("jet",
  43. g1_object_definition_class::TO_MAP_PIECE |
  44. g1_object_definition_class::EDITOR_SELECTABLE |
  45. g1_object_definition_class::MOVABLE,
  46. g1_jet_init);
  47. g1_jet_class::g1_jet_class(g1_object_type id,
  48. g1_loader_class *fp)
  49. : g1_map_piece_class(id, fp)
  50. {
  51. allocate_mini_objects(1,"Jet Mini-Objects");
  52. engines = &mini_objects[0];
  53. engines->h = engines->lh = 0.05;
  54. engines->x = engines->lx = 0.01;
  55. engines->y = engines->ly = 0;
  56. w16 ver,data_size;
  57. if (fp)
  58. fp->get_version(ver,data_size);
  59. else
  60. ver =0;
  61. switch (ver)
  62. {
  63. case DATA_VERSION:
  64. fp->read_format("1ffff4",
  65. &mode,
  66. &engines->rotation.x, &engines->rotation.y, &engines->rotation.z,
  67. &vspeed,
  68. &sway);
  69. engines->grab_old();
  70. break;
  71. case 2:
  72. mode = fp->read_8();
  73. engines->rotation.x = fp->read_float();
  74. engines->rotation.y = fp->read_float();
  75. engines->rotation.z = fp->read_float();
  76. engines->lrotation.x = fp->read_float();
  77. engines->lrotation.y = fp->read_float();
  78. engines->lrotation.z = fp->read_float();
  79. vspeed = fp->read_float();
  80. sway = fp->read_32();
  81. break;
  82. case 1:
  83. mode = 0;
  84. if (fp->read_8()) mode=TAKE_OFF; // take_off
  85. if (fp->read_8()) mode=TAKE_OFF; // taking_off
  86. if (fp->read_8()) mode=FLYING; // flying
  87. fp->read_8();
  88. fp->read_8();
  89. engines->rotation.x = fp->read_float();
  90. engines->rotation.y = fp->read_float();
  91. engines->rotation.z = fp->read_float();
  92. engines->lrotation.x = fp->read_float();
  93. engines->lrotation.y = fp->read_float();
  94. engines->lrotation.z = fp->read_float();
  95. vspeed = fp->read_float();
  96. fp->read_float();
  97. sway = 0;
  98. break;
  99. default:
  100. if (fp) fp->seek(fp->tell() + data_size);
  101. mode = 0;
  102. engines->rotation.x = engines->lrotation.x = 0;
  103. engines->rotation.y = engines->lrotation.y = 0;
  104. engines->rotation.z = engines->lrotation.z = 0;
  105. vspeed = 0;
  106. sway = 0;
  107. break;
  108. }
  109. if (fp)
  110. fp->end_version(I4_LF);
  111. engines->defmodeltype = g1_model_list_man.find_handle("jet_engines");
  112. draw_params.setup("jet_body","jet_shadow","jet_lod");
  113. init_rumble_sound(G1_RUMBLE_JET);
  114. damping_fraction = 0.02;
  115. radar_image=&radar_im;
  116. radar_type=G1_RADAR_VEHICLE;
  117. set_flag(BLOCKING |
  118. TARGETABLE |
  119. AERIAL |
  120. HIT_AERIAL |
  121. DANGEROUS, 1);
  122. }
  123. void g1_jet_class::save(g1_saver_class *fp)
  124. {
  125. g1_map_piece_class::save(fp);
  126. fp->start_version(DATA_VERSION);
  127. fp->write_format("1ffff4",
  128. &mode,
  129. &engines->rotation.x, &engines->rotation.y, &engines->rotation.z,
  130. &vspeed,
  131. &sway);
  132. fp->end_version();
  133. }
  134. void g1_jet_class::fire()
  135. {
  136. fire_delay = g1_jet_def.defaults->fire_delay;
  137. i4_3d_vector p(x,y,h), dir(attack_target->x, attack_target->y, attack_target->h);
  138. dir -= p;
  139. g1_fire(defaults->fire_type,
  140. this, attack_target.get(), p, dir);
  141. }
  142. i4_bool g1_jet_class::move(i4_float x_amount, i4_float y_amount)
  143. {
  144. unoccupy_location();
  145. x+=x_amount;
  146. y+=y_amount;
  147. if (occupy_location())
  148. {
  149. g1_add_to_sound_average(rumble_type, i4_3d_vector(x,y,h));
  150. return i4_T;
  151. }
  152. return i4_F;
  153. }
  154. /* DLL stuff */
  155. void g1_jet_class::think()
  156. {
  157. if (!check_life())
  158. return;
  159. find_target();
  160. if (fire_delay>0)
  161. fire_delay--;
  162. h += vspeed;
  163. switch (mode)
  164. {
  165. case TAKE_OFF:
  166. {
  167. // rotate engines
  168. if (i4_rotate_to(engines->rotation.y,3*i4_pi()/2,0.1)==0.0)
  169. mode = TAKE_OFF2;
  170. } break;
  171. case TAKE_OFF2:
  172. {
  173. if (next_path.valid())
  174. {
  175. dest_x = next_path->x - path_cos*path_len;
  176. dest_y = next_path->y - path_sin*path_len;
  177. dest_z = next_path->h - path_tan_phi*path_len;
  178. }
  179. //then raise the jet
  180. i4_float dist_to_go = dest_z - h;
  181. if (dist_to_go>0.05)
  182. {
  183. //if he is more than halfway away, accelerate down
  184. //otherwise accelerate up
  185. if (dist_to_go > (FLY_HEIGHT * 0.5))
  186. vspeed = (vspeed<0.05) ? vspeed+0.005 : vspeed;
  187. }
  188. else
  189. {
  190. //lock these in case there were any small errors
  191. h = dest_z;
  192. vspeed = 0;
  193. //think one more time so the l* variables catch up
  194. //(otherwise he'll bob up and down)
  195. if (h == lh)
  196. mode = FLYING;
  197. }
  198. } break;
  199. case FLYING:
  200. {
  201. i4_3d_vector d;
  202. i4_float angle,t;
  203. // sway over terrain
  204. sway++;
  205. if (attack_target.valid())
  206. if (fire_delay==0)
  207. fire();
  208. if (next_path.valid())
  209. {
  210. dest_x = next_path->x;
  211. dest_y = next_path->y;
  212. dest_z = next_path->h;
  213. }
  214. i4_float roll_to = 0.02*sin(i4_pi()*sway/17.0);
  215. i4_float pitch_to = 0.02*sin(i4_pi()*sway/13.0);
  216. i4_float dist, dtheta;
  217. suggest_air_move(dist, dtheta, d);
  218. move(d.x,d.y);
  219. h += d.z + 0.02*sin(i4_pi()*sway/15.0);
  220. if (dist<speed)
  221. advance_path();
  222. i4_normalize_angle(roll_to);
  223. if (speed>0.001 || dtheta!=0.0)
  224. {
  225. roll_to = -i4_pi()/4 * dtheta;
  226. pitch_to = -i4_pi()/8 * speed;
  227. }
  228. i4_rotate_to(roll,roll_to,defaults->turn_speed/4);
  229. i4_rotate_to(pitch,pitch_to,defaults->turn_speed/4);
  230. groundpitch = 0; //no ground in the air (duh)
  231. groundroll = 0;
  232. } break;
  233. case DYING:
  234. {
  235. i4_float &roll_speed = dest_x;
  236. i4_float &pitch_speed = dest_y;
  237. pitch_speed += 0.004;
  238. pitch += pitch_speed;
  239. roll_speed -= 0.012;
  240. roll += roll_speed;
  241. vspeed -= (g1_resources.gravity * 0.1);
  242. i4_float dx,dy;
  243. dx = speed*cos(theta);
  244. dy = speed*sin(theta);
  245. move(dx,dy);
  246. if (h<=terrain_height)
  247. g1_map_piece_class::damage(0,health,i4_3d_vector(0,0,1)); // die somehow!!!
  248. } break;
  249. }
  250. // have to keep thinking to sway
  251. request_think();
  252. }
  253. void g1_jet_class::damage(g1_object_class *obj, int hp, i4_3d_vector _damage_dir)
  254. {
  255. //we dont want to explode if ppl shoot us while we're dying.. we want to
  256. //smash into the ground and create a nice explosion
  257. if (mode != DYING)
  258. {
  259. g1_map_piece_class::damage(obj,hp,_damage_dir);
  260. if (health<20)
  261. {
  262. i4_float &roll_speed = dest_x;
  263. i4_float &pitch_speed = dest_y;
  264. health = 20;
  265. set_flag(DANGEROUS,0);
  266. roll_speed = 0;
  267. pitch_speed = 0;
  268. mode = DYING;
  269. }
  270. }
  271. }