wolf_weapon.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. Copyright (C) 2004 Michael Liebscher
  3. Copyright (C) 2000-2002 by DarkOne the Hacker
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  15. */
  16. #include "../wolfiphone.h"
  17. /*
  18. -----------------------------------------------------------------------------
  19. Function:
  20. Parameters:
  21. Returns:
  22. Notes:
  23. -----------------------------------------------------------------------------
  24. */
  25. PUBLIC void fire_hit( player_t *self )
  26. {
  27. entity_t *closest;
  28. int dist, d1, n, shot_dist, damage;
  29. Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "lsfx/023.wav" ), 1, ATTN_NORM, 0 );
  30. // actually fire
  31. dist = 0x7fffffff;
  32. closest = NULL;
  33. for( n = 0 ; n < NumGuards ; ++n )
  34. {
  35. if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
  36. {
  37. shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
  38. if( shot_dist > (2 * TILEGLOBAL / 3) )
  39. {
  40. continue; // miss
  41. }
  42. d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
  43. if( d1 < 0 || d1 > dist )
  44. {
  45. continue;
  46. }
  47. if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
  48. {
  49. //if( ! CheckLine( &Guards[ n ] ) )
  50. continue; // obscured
  51. }
  52. dist = d1;
  53. closest = &Guards[ n ];
  54. }
  55. }
  56. if( ! closest || dist > TILE2POS( 1 ) )
  57. {
  58. return; // missed if further than 1.5 tiles
  59. }
  60. damage = US_RndT() >> 4;
  61. A_DamageActor( closest, damage ); // hit something
  62. }
  63. /*
  64. -----------------------------------------------------------------------------
  65. Function:
  66. Parameters:
  67. Returns:
  68. Notes:
  69. -----------------------------------------------------------------------------
  70. */
  71. PUBLIC void fire_lead( player_t *self )
  72. {
  73. entity_t *closest;
  74. int damage;
  75. int dx, dy, dist;
  76. int d1, shot_dist, n;
  77. switch( self->weapon )
  78. {
  79. case WEAPON_PISTOL:
  80. Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/012.wav" ), 1, ATTN_NORM, 0 );
  81. break;
  82. case WEAPON_AUTO:
  83. Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/011.wav" ), 1, ATTN_NORM, 0 );
  84. break;
  85. case WEAPON_CHAIN:
  86. Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/013.wav" ), 1, ATTN_NORM, 0 );
  87. break;
  88. }
  89. self->madenoise = true;
  90. dist = 0x7fffffffl;
  91. closest = NULL;
  92. for( n = 0 ; n < NumGuards; ++n )
  93. {
  94. if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
  95. {
  96. shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
  97. if( shot_dist > (2 * TILEGLOBAL / 3) )
  98. {
  99. continue; // miss
  100. }
  101. d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
  102. if( d1 < 0 || d1 > dist )
  103. {
  104. continue;
  105. }
  106. if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
  107. {
  108. //if( ! CheckLine( &Guards[ n ] ) )
  109. continue; // obscured
  110. }
  111. dist = d1;
  112. closest = &Guards[ n ];
  113. }
  114. }
  115. if( ! closest ) // missed
  116. {
  117. r_trace_t trace;
  118. trace.a = NormalizeAngle( self->position.angle - DEG2FINE( 2 ) + rand() % (DEG2FINE( 4 ) ) );
  119. trace.x = self->position.origin[ 0 ];
  120. trace.y = self->position.origin[ 1 ];
  121. trace.flags = TRACE_BULLET;
  122. trace.tile_vis = NULL;
  123. R_Trace( &trace, r_world );
  124. if( trace.flags & TRACE_HIT_DOOR )
  125. {
  126. Sound_StartSound( NULL, 0, CHAN_AUTO, Sound_RegisterSound( "lsfx/028.wav" ), 1, ATTN_NORM, 0 );
  127. }
  128. return;
  129. }
  130. // hit something
  131. dx = ABS( closest->tilex - self->tilex );
  132. dy = ABS( closest->tiley - self->tiley );
  133. dist = max_of_2( dx, dy );
  134. if( dist < 2 )
  135. {
  136. damage = US_RndT() / 4;
  137. }
  138. else if( dist < 4 )
  139. {
  140. damage = US_RndT() / 6;
  141. }
  142. else
  143. {
  144. if( US_RndT() / 12 < dist )
  145. {
  146. return; // missed
  147. }
  148. damage = US_RndT() / 6;
  149. }
  150. A_DamageActor( closest, damage );
  151. }