rocktank.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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 "objs/rocktank.hh"
  12. #include "input.hh"
  13. #include "math/pi.hh"
  14. #include "math/trig.hh"
  15. #include "math/angle.hh"
  16. #include "g1_rand.hh"
  17. #include "resources.hh"
  18. #include "saver.hh"
  19. #include "map_cell.hh"
  20. #include "map.hh"
  21. #include "objs/vehic_sounds.hh"
  22. #include "sound/sfx_id.hh"
  23. #include "object_definer.hh"
  24. #include "objs/fire.hh"
  25. S1_SFX(rumble, "rumble/missile_truck_lp.wav", S1_3D, 1);
  26. S1_SFX(raising, "misc/missile_truck_raise.wav", S1_3D, 5);
  27. S1_SFX(lowering, "misc/missile_truck_lower.wav", S1_3D, 5);
  28. enum { DATA_VERSION=1 };
  29. enum eRackState
  30. {
  31. LOWERED,
  32. RAISE,
  33. RAISING,
  34. RAISED,
  35. LOWER,
  36. LOWERING,
  37. };
  38. static g1_model_ref model_ref("rocket_truck"),
  39. shadow_ref("rocket_truck_shadow"),
  40. rack_ref("rocket_truck_top"),
  41. base_lod("rocket_truck_lod"),
  42. top_lod("rocket_truck_top_lod");
  43. static i4_3d_vector rack_attach, rack_offset;
  44. static void g1_rocket_tank_init()
  45. {
  46. rack_attach.set(0,0,0);
  47. model_ref()->get_mount_point("Rack", rack_attach);
  48. rack_offset.set(0,0,0);
  49. rack_ref()->get_mount_point("Rack", rack_offset);
  50. rack_offset.reverse();
  51. }
  52. g1_object_definer<g1_rocket_tank_class>
  53. g1_rocket_tank_def("rocket_tank",
  54. g1_object_definition_class::TO_MAP_PIECE |
  55. g1_object_definition_class::MOVABLE |
  56. g1_object_definition_class::EDITOR_SELECTABLE,
  57. g1_rocket_tank_init);
  58. static char *chunk_list[3]={"chunk_missiletruck_body", "chunk_missiletruck_launcher",
  59. "chunk_missiletruck_tread"};
  60. int g1_rocket_tank_class::get_chunk_names(char **&list) { list=chunk_list; return 3; }
  61. g1_rocket_tank_class::g1_rocket_tank_class(g1_object_type id,
  62. g1_loader_class *fp)
  63. : g1_map_piece_class(id, fp)
  64. {
  65. draw_params.setup(model_ref.id(), shadow_ref.id(), base_lod.id());
  66. allocate_mini_objects(2,"Rocket Tank Mini-objects");
  67. missile_rack = &mini_objects[0];
  68. missile_rack->defmodeltype = rack_ref.id();
  69. missile_rack->lod_model = top_lod.id();
  70. missile_rack->position(rack_attach);
  71. missile_rack->offset = rack_offset;
  72. w16 ver,data_size;
  73. if (fp)
  74. {
  75. fp->get_version(ver,data_size);
  76. switch (ver)
  77. {
  78. case DATA_VERSION:
  79. fp->read_8();
  80. fp->read_format("fff",
  81. &missile_rack->rotation.x,
  82. &missile_rack->rotation.y,
  83. &missile_rack->rotation.z);
  84. missile_rack->grab_old();
  85. break;
  86. case 0:
  87. fp->read_8();
  88. fp->read_8();
  89. fp->read_8();
  90. fp->read_8();
  91. fp->read_16();
  92. missile_rack->rotation.x = fp->read_float();
  93. missile_rack->rotation.y = fp->read_float();
  94. missile_rack->rotation.z = fp->read_float();
  95. missile_rack->lrotation.x = fp->read_float();
  96. missile_rack->lrotation.y = fp->read_float();
  97. missile_rack->lrotation.z = fp->read_float();
  98. break;
  99. default:
  100. fp->seek(fp->tell() + data_size);
  101. missile_rack->rotation.x = 0;
  102. missile_rack->rotation.y = 0;
  103. missile_rack->rotation.z = 0;
  104. missile_rack->lrotation = missile_rack->rotation;
  105. fire_delay = 15;
  106. break;
  107. }
  108. fp->end_version(I4_LF);
  109. }
  110. else
  111. {
  112. missile_rack->rotation.x = 0;
  113. missile_rack->rotation.y = 0;
  114. missile_rack->rotation.z = 0;
  115. missile_rack->lrotation = missile_rack->rotation;
  116. fire_delay = 15;
  117. }
  118. init_rumble_sound(G1_RUMBLE_GROUND);
  119. guard_angle = 0;
  120. guard_pitch = 0;
  121. guard_time = 0;
  122. radar_type=G1_RADAR_VEHICLE;
  123. set_flag(BLOCKING |
  124. SELECTABLE |
  125. TARGETABLE |
  126. GROUND |
  127. HIT_AERIAL |
  128. HIT_GROUND |
  129. DANGEROUS, 1);
  130. }
  131. void g1_rocket_tank_class::save(g1_saver_class *fp)
  132. {
  133. g1_map_piece_class::save(fp);
  134. fp->start_version(DATA_VERSION);
  135. fp->write_8(0);
  136. fp->write_format("fff",
  137. &missile_rack->rotation.x,
  138. &missile_rack->rotation.y,
  139. &missile_rack->rotation.z);
  140. fp->end_version();
  141. }
  142. void g1_rocket_tank_class::fire()
  143. {
  144. g1_object_class *target=attack_target.get();
  145. if (target)
  146. {
  147. i4_float bx,by,bz;
  148. i4_3d_vector pos, dir;
  149. i4_transform_class btrans,tmp1;
  150. btrans.translate(x,y,h);
  151. tmp1.rotate_x(groundroll);
  152. btrans.multiply(tmp1);
  153. tmp1.rotate_y(groundpitch);
  154. btrans.multiply(tmp1);
  155. tmp1.rotate_z(theta);
  156. btrans.multiply(tmp1);
  157. tmp1.translate(missile_rack->x, missile_rack->y, missile_rack->h);
  158. btrans.multiply(tmp1);
  159. tmp1.rotate_z(missile_rack->rotation.z);
  160. btrans.multiply(tmp1);
  161. tmp1.rotate_y(missile_rack->rotation.y);
  162. btrans.multiply(tmp1);
  163. btrans.transform(i4_3d_vector(0.1, 0, 0), pos);
  164. btrans.transform(i4_3d_vector(1.0, 0, 0), dir);
  165. dir-=pos;
  166. g1_fire(defaults->fire_type, this, target, pos, dir);
  167. fire_delay = defaults->fire_delay;
  168. }
  169. }
  170. void g1_rocket_tank_class::think()
  171. {
  172. g1_map_piece_class::think();
  173. if (!alive())
  174. return;
  175. //aim the missile rack
  176. if (attack_target.valid())
  177. {
  178. request_think();
  179. i4_float dx,dy,dangle;
  180. //this will obviously only be true if attack_target.ref != NULL
  181. dx = ((x+missile_rack->x) - attack_target->x);
  182. dy = ((y+missile_rack->y) - attack_target->y);
  183. //aim the vehicle
  184. guard_angle = i4_atan2(dy,dx) + i4_pi() - theta;
  185. i4_normalize_angle(guard_angle);
  186. i4_float dist = dx*dx+dy*dy;
  187. if (dist>25.0)
  188. guard_pitch = -i4_pi()/8;
  189. else if (dist>9.0)
  190. guard_pitch = -(dist - 9.0)*i4_pi()/8/(25.0-9.0);
  191. else
  192. guard_pitch = 0;
  193. i4_normalize_angle(guard_pitch);
  194. i4_bool aimed = i4_F;
  195. dangle = i4_rotate_to(missile_rack->rotation.z, guard_angle, 0.1);
  196. aimed = (dangle<0.1 && dangle>-0.1);
  197. dangle = i4_rotate_to(missile_rack->rotation.y, guard_pitch, 0.1);
  198. aimed &= (dangle<0.1 && dangle>-0.1);
  199. if (aimed && !fire_delay)
  200. fire();
  201. guard_time = 40;
  202. }
  203. else
  204. {
  205. guard_pitch = 0;
  206. guard_angle = 0;
  207. request_think(); // move this to draw function
  208. i4_rotate_to(missile_rack->rotation.z, guard_angle, 0.1);
  209. i4_rotate_to(missile_rack->rotation.y, guard_pitch, 0.1);
  210. }
  211. }