beam_weapon.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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 "objs/beam_weapon.hh"
  9. #include "objs/shrapnel.hh"
  10. #include "sound/sfx_id.hh"
  11. #include "map.hh"
  12. #include "map_man.hh"
  13. #include "objs/defaults.hh"
  14. #include "lisp/lisp.hh"
  15. #include "math/random.hh"
  16. #include "g1_render.hh"
  17. #include "object_definer.hh"
  18. #include "g1_texture_id.hh"
  19. #include "math/pi.hh"
  20. #include "draw_context.hh"
  21. #include "r1_clip.hh"
  22. #include "tick_count.hh"
  23. li_symbol_ref li_shrapnel("shrapnel"), beam("beam"), plasma("plasma");
  24. g1_beam_weapon_class::g1_beam_weapon_class(g1_object_type id,
  25. g1_loader_class *fp)
  26. : g1_object_class(id,fp)
  27. {
  28. set_flag(AERIAL | HIT_GROUND, 1);
  29. range=0;
  30. idle_ticks=0;
  31. should_draw=0;
  32. }
  33. void g1_beam_weapon_class::setup(const i4_3d_vector &pos,
  34. const i4_3d_vector &direction,
  35. g1_object_class *this_guy_fired_me,
  36. float range)
  37. {
  38. x=pos.x;
  39. y=pos.y;
  40. h=pos.z;
  41. who_fired_me=this_guy_fired_me;
  42. if (this_guy_fired_me)
  43. {
  44. lx=pos.x + (this_guy_fired_me->lx - this_guy_fired_me->x);
  45. ly=pos.y + (this_guy_fired_me->ly - this_guy_fired_me->y);
  46. lh=pos.z + (this_guy_fired_me->lh - this_guy_fired_me->h);
  47. }
  48. else
  49. {
  50. lx=x;
  51. ly=y;
  52. lh=h;
  53. }
  54. if (!get_flag(MAP_OCCUPIED))
  55. occupy_location();
  56. i4_3d_vector dir=direction;
  57. dir.normalize();
  58. // sfxfix
  59. // if (!fire_sound)
  60. // {
  61. // fire_sound=g1_sound_man.alloc_dynamic_3d_sound(g1_sfx_fire_supertank_auto1);
  62. // g1_sound_man.update_dynamic_3d_sound(fire_sound, pos, dir, 1.0);
  63. // }
  64. idle_ticks=0;
  65. should_draw=1;
  66. dir*=range;
  67. g1_object_class *hit=0;
  68. if (g1_get_map()->check_non_player_collision(player_num,pos,dir,hit))
  69. {
  70. if (hit)
  71. g1_apply_damage(this, this_guy_fired_me, hit, dir);
  72. g1_shrapnel_class *shrapnel = NULL;
  73. shrapnel = (g1_shrapnel_class *)g1_create_object(g1_get_object_type(li_shrapnel.get()));
  74. i4_3d_vector pos=i4_3d_vector(x,y,h);
  75. pos+=dir;
  76. if (shrapnel)
  77. {
  78. i4_float rx,ry,rh;
  79. rx = (i4_rand()&0xFFFF)/((i4_float)0xFFFF) * 0.2;
  80. ry = (i4_rand()&0xFFFF)/((i4_float)0xFFFF) * 0.2;
  81. rh = (i4_rand()&0xFFFF)/((i4_float)0xFFFF) * 0.2;
  82. shrapnel->setup(pos.x+rx, pos.y+ry, pos.z + rh,1, i4_F);
  83. }
  84. }
  85. end_point=pos;
  86. end_point+=dir;
  87. request_think();
  88. }
  89. void g1_beam_weapon_class::think()
  90. {
  91. if (idle_ticks>5)
  92. {
  93. unoccupy_location();
  94. request_remove();
  95. }
  96. else
  97. {
  98. request_think();
  99. idle_ticks++;
  100. }
  101. }
  102. void g1_beam_weapon_class::unoccupy_location()
  103. {
  104. // if (fire_sound) sfxfix
  105. // {
  106. // g1_sound_man.free_dynamic_3d_sound(fire_sound);
  107. // fire_sound=0;
  108. // }
  109. g1_object_class::unoccupy_location();
  110. }
  111. i4_bool g1_beam_weapon_class::occupy_location()
  112. {
  113. float w=g1_get_map()->width(), h=g1_get_map()->height();
  114. if (!(x>=0 && x<w && y>=0 && y<h))
  115. {
  116. request_remove();
  117. return i4_F;
  118. }
  119. if (!(end_point.x>=0 && end_point.y>=0 && end_point.x<w && end_point.y<h))
  120. {
  121. request_remove();
  122. return i4_F;
  123. }
  124. g1_map_class *map=g1_get_map();
  125. map->add_object(*new_occupied_square(), i4_f_to_i(x), i4_f_to_i(y));
  126. map->add_object(*new_occupied_square(), i4_f_to_i(end_point.x), i4_f_to_i(end_point.y));
  127. set_flag(MAP_OCCUPIED,1);
  128. return i4_T;
  129. }
  130. static void setup_p(r1_vert &rv, const i4_3d_vector &p, float a, float r, float g, float b)
  131. {
  132. rv.v.x=p.x;
  133. rv.v.y=p.y;
  134. rv.v.z=p.z;
  135. rv.a=a;
  136. rv.r=r;
  137. rv.g=g;
  138. rv.b=b;
  139. }
  140. static void draw_sprite(const i4_3d_vector &p, r1_texture_handle tex, float sprite_scale)
  141. {
  142. if (p.z > r1_near_clip_z)
  143. {
  144. i4_float ooz = 1 / p.z;
  145. i4_float xs = g1_render.center_x * ooz * g1_render.scale_x;
  146. i4_float ys = g1_render.center_y * ooz * g1_render.scale_y;
  147. float cx=g1_render.center_x + p.x*xs;
  148. float cy=g1_render.center_y + p.y*ys;
  149. float w=sprite_scale * g1_render.center_x * 2 * ooz;
  150. r1_clip_render_textured_rect(i4_f_to_i(cx-w/2), i4_f_to_i(cy-w/2),
  151. i4_f_to_i(cx+w/2), i4_f_to_i(cy+w/2), p.z,
  152. 1.0,
  153. i4_f_to_i(g1_render.center_x*2),
  154. i4_f_to_i(g1_render.center_y*2),
  155. tex, 0, g1_render.r_api);
  156. }
  157. }
  158. void g1_beam_weapon_class::draw(g1_draw_context_class *context)
  159. {
  160. if (should_draw)
  161. {
  162. r1_vert points[4];
  163. i4_3d_vector norm;
  164. float fr=g1_render.frame_ratio;
  165. i4_3d_vector start, step, t_start, up, side;
  166. start.interpolate(i4_3d_vector(x,y,h), i4_3d_vector(lx,ly,lh), fr);
  167. up=i4_3d_vector(0,0,1);
  168. step=end_point;
  169. step-=start;
  170. side.cross(up, step);
  171. side.normalize();
  172. side*=0.2;
  173. r1_render_api_class *api=g1_render.r_api;
  174. float cx=g1_render.center_x, cy=g1_render.center_y;
  175. r1_texture_handle texture=g1_get_texture("red_flare");
  176. float theta=g1_tick_counter*3.0 + fr;
  177. float theta_step=2*i4_pi()/10.0;
  178. for (float t=0; t<1; t+=(1.1-t)*0.3)
  179. {
  180. i4_3d_vector s=i4_3d_vector(start.x + step.x*t + side.x*cos(theta),
  181. start.y + step.y*t + side.y*sin(theta),
  182. start.z + step.z*t + side.z*cos(theta+0.5)*0.5);
  183. theta+=theta_step;
  184. context->transform->transform(s, t_start);
  185. draw_sprite(t_start, texture, 0.1);
  186. }
  187. }
  188. }
  189. g1_object_definer<g1_beam_weapon_class>
  190. g1_beam_def("beam", g1_object_definition_class::EDITOR_SELECTABLE);
  191. g1_object_definer<g1_beam_weapon_class>
  192. g1_plasma_def("plasma", g1_object_definition_class::EDITOR_SELECTABLE);