repairer.cc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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/repairer.hh"
  12. #include "input.hh"
  13. #include "math/pi.hh"
  14. #include "math/angle.hh"
  15. #include "math/trig.hh"
  16. #include "math/random.hh"
  17. #include "resources.hh"
  18. #include "saver.hh"
  19. #include "map_cell.hh"
  20. #include "map.hh"
  21. #include "map_man.hh"
  22. #include "object_definer.hh"
  23. enum {DATA_VERSION=1};
  24. g1_object_definer<g1_repairer_class>
  25. g1_repairer_def("repairer", g1_object_definition_class::EDITOR_SELECTABLE);
  26. g1_repairer_class::g1_repairer_class(g1_object_type id,
  27. g1_loader_class *fp)
  28. : g1_map_piece_class(id,fp)
  29. {
  30. draw_params.setup("repair_base");
  31. defaults = g1_repairer_def.defaults;
  32. allocate_mini_objects(3,"repair_objects");
  33. turret = &mini_objects[0];
  34. turret->x = turret->lx = 0;
  35. turret->y = turret->ly = 0;
  36. turret->h = turret->lh = 0;
  37. turret->rotation.set(0,0,0);
  38. turret->defmodeltype = g1_model_list_man.find_handle("repair_turret");
  39. turret->grab_old();
  40. boom = &mini_objects[1];
  41. boom->x = turret->lx = turret->x;
  42. boom->y = turret->ly = turret->y;
  43. boom->h = turret->lh = turret->h;
  44. boom->rotation.set(0,0,0);
  45. boom->defmodeltype = g1_model_list_man.find_handle("repair_boom");
  46. boom->grab_old();
  47. tip = &mini_objects[2];
  48. tip->x = tip->lx = g1_resources.repairer_tip_attach.x;
  49. tip->y = tip->ly = g1_resources.repairer_tip_attach.y;
  50. tip->h = tip->lh = g1_resources.repairer_tip_attach.z;
  51. tip->rotation.set(0,-i4_pi()/2.0,0);
  52. tip->defmodeltype = g1_model_list_man.find_handle("repair_tip");
  53. tip->grab_old();
  54. w16 ver,data_size;
  55. if (fp)
  56. fp->get_version(ver,data_size);
  57. else
  58. ver =0;
  59. switch (ver)
  60. {
  61. case DATA_VERSION:
  62. break;
  63. default:
  64. if (fp) fp->seek(fp->tell() + data_size);
  65. health = defaults->health;
  66. break;
  67. }
  68. if (fp)
  69. fp->end_version(I4_LF);
  70. length = g1_resources.repairer_boom_offset;
  71. set_flag(BLOCKING |
  72. SHADOWED,
  73. 1);
  74. }
  75. void g1_repairer_class::save(g1_saver_class *fp)
  76. {
  77. g1_map_piece_class::save(fp);
  78. fp->start_version(DATA_VERSION);
  79. fp->end_version();
  80. }
  81. i4_bool g1_repairer_class::can_attack(g1_object_class *who) const
  82. {
  83. if (who->player_num == player_num)
  84. {
  85. g1_map_piece_class *mp = g1_map_piece_class::cast(who);
  86. return (mp && mp->get_flag(GROUND) && mp->health>0 && mp->health<mp->defaults->health);
  87. }
  88. return i4_F;
  89. }
  90. void g1_repairer_class::think()
  91. {
  92. find_target();
  93. if (health < defaults->health)
  94. health++;
  95. if (fire_delay>0)
  96. fire_delay--;
  97. pitch = 0;
  98. roll = 0;
  99. h = terrain_height;
  100. if (attack_target.valid())
  101. {
  102. i4_float dx,dy;
  103. //this will obviously only be true if attack_target.ref != NULL
  104. dx = (attack_target->x - x);
  105. dy = (attack_target->y - y);
  106. //aim the turet
  107. repair_angle = i4_atan2(dy,dx);
  108. i4_normalize_angle(repair_angle);
  109. repair_length = sqrt(dx*dx + dy*dy);
  110. }
  111. else
  112. {
  113. repair_angle = 0;
  114. repair_length = 1.5;
  115. }
  116. int aimed;
  117. i4_float dangle;
  118. aimed = (i4_rotate_to(turret->rotation.z,repair_angle,defaults->turn_speed)==0.0);
  119. if (length<repair_length)
  120. {
  121. length += speed;
  122. if (length>repair_length) length=repair_length;
  123. }
  124. else
  125. {
  126. length -= speed;
  127. if (length<repair_length) length=repair_length;
  128. }
  129. i4_float
  130. cs = cos(turret->rotation.z),
  131. sn = sin(turret->rotation.z),
  132. ex = length - g1_resources.repairer_boom_offset;
  133. boom->rotation.z = turret->rotation.z;
  134. tip->rotation.z = turret->rotation.z;
  135. boom->x = cs*ex;
  136. boom->y = sn*ex;
  137. ex += g1_resources.repairer_tip_attach.x;
  138. tip->x = cs*ex;
  139. tip->y = sn*ex;
  140. if (attack_target.valid() && aimed)
  141. {
  142. if (i4_rotate_to(tip->rotation.y,-i4_pi()/6.0,0.1)==0.0 && fire_delay==0)
  143. {
  144. g1_map_piece_class *mp = g1_map_piece_class::cast(attack_target.get());
  145. if (mp->health<mp->defaults->health && mp->health>0)
  146. {
  147. fire_delay = defaults->fire_delay;
  148. mp->health+=get_type()->get_damage_map()->get_damage_for(mp->id);
  149. if (mp->health>mp->defaults->health)
  150. mp->health = mp->defaults->health;
  151. }
  152. else
  153. attack_target = 0;
  154. }
  155. }
  156. else
  157. // return to stopped position
  158. i4_rotate_to(tip->rotation.y,-i4_pi()/2.0,0.1);
  159. // don't rethink if i'm not healing or moving
  160. if (attack_target.valid() ||
  161. tip->rotation.y != tip->lrotation.y ||
  162. tip->rotation.z != tip->lrotation.z ||
  163. tip->x != tip->lx ||
  164. tip->y != tip->ly)
  165. request_think();
  166. }
  167. void g1_repairer_class::draw(g1_draw_context_class *context)
  168. {
  169. g1_model_draw(this, draw_params, context);
  170. }