HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. /* Formatright © 2010, ConnorMcLeod
  2.  
  3. Bubble Trails is free software;
  4. you can redistribute it and/or modify it under the terms of the
  5. GNU General Public License as published by the Free Software Foundation.
  6.  
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11.  
  12. You should have received a copy of the GNU General Public License
  13. along with Bubble Trails; if not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17.  
  18. #include <amxmodx>
  19. #include <fakemeta>
  20. #include <hamsandwich>
  21.  
  22. #define VERSION "0.0.1"
  23.  
  24. #define IsPlayer(%1) ( 1 <= %1 <= g_iMaxPlayers )
  25. #define write_coord_f(%1) engfunc(EngFunc_WriteCoord,%1)
  26.  
  27. const DONT_CHECK_WEAPONS_BITSUM = (1<<CSW_XM1014)|(1<<CSW_M3)|(1<<CSW_KNIFE)
  28.  
  29. new g_iMaxPlayers
  30. new Trie:g_tClassNames
  31.  
  32. new g_sModelIndexBubbles
  33.  
  34. public plugin_precache()
  35. {
  36. g_tClassNames = TrieCreate()
  37.  
  38. RegisterHam(Ham_TraceAttack, "worldspawn", "TraceAttack", 1)
  39. TrieSetCell(g_tClassNames, "worldspawn", 1)
  40. RegisterHam(Ham_TraceAttack, "player", "TraceAttack", 1)
  41. TrieSetCell(g_tClassNames, "player", 1)
  42.  
  43. register_forward(FM_Spawn, "Spawn", 1)
  44.  
  45. g_sModelIndexBubbles = precache_model("sprites/bubble.spr")
  46. }
  47.  
  48. public Spawn( iEnt )
  49. {
  50. if( pev_valid(iEnt) )
  51. {
  52. static szClassName[32]
  53. pev(iEnt, pev_classname, szClassName, charsmax(szClassName))
  54. if( !TrieKeyExists(g_tClassNames, szClassName) )
  55. {
  56. RegisterHam(Ham_TraceAttack, szClassName, "TraceAttack", 1)
  57. TrieSetCell(g_tClassNames, szClassName, 1)
  58. }
  59. }
  60. }
  61.  
  62. public plugin_init()
  63. {
  64. register_plugin("Bubble Trails", VERSION, "ConnorMcLeod")
  65.  
  66. g_iMaxPlayers = get_maxplayers()
  67. }
  68.  
  69. public plugin_end()
  70. {
  71. TrieDestroy(g_tClassNames)
  72. }
  73.  
  74. public TraceAttack(iEnt, iAttacker, Float:flDamage, Float:fDir[3], ptr, iDamageType)
  75. {
  76. if( !IsPlayer(iAttacker) || !is_user_alive(iAttacker) || DONT_CHECK_WEAPONS_BITSUM & (1<<get_user_weapon(iAttacker)) )
  77. {
  78. return
  79. }
  80.  
  81. new Float:vecOrigin[3], Float:vecEnd[3]
  82.  
  83. pev(iAttacker, pev_origin, vecOrigin)
  84. vecOrigin[2] += ((pev(iAttacker, pev_flags) & FL_DUCKING) ? 12.0 : 18.0)
  85. get_tr2(ptr, TR_vecEndPos, vecEnd)
  86.  
  87. new Float:vecTemp[3]
  88. vecTemp[0] = vecEnd[0] - vecOrigin[0]
  89. vecTemp[1] = vecEnd[1] - vecOrigin[1]
  90. vecTemp[2] = vecEnd[2] - vecOrigin[2]
  91.  
  92. UTIL_BubbleTrail(vecOrigin, vecEnd, floatround(vector_length(vecTemp) / 64.0) )
  93. }
  94.  
  95. UTIL_BubbleTrail(Float:vecSource[3], Float:vecTo[3], iCount )
  96. {
  97. new Float:flHeight = UTIL_WaterLevel(vecSource, vecSource[2], vecSource[2] + 256.0 )
  98. flHeight = flHeight - vecSource[2]
  99.  
  100. if(flHeight < 8.0)
  101. {
  102. flHeight = UTIL_WaterLevel( vecTo, vecTo[2], vecTo[2] + 256.0 )
  103. flHeight = flHeight - vecTo[2]
  104. if(flHeight < 8.0)
  105. return
  106.  
  107. flHeight = flHeight + vecTo[2] - vecSource[2]
  108. }
  109.  
  110. if(iCount > 255)
  111. {
  112. iCount = 255
  113. }
  114.  
  115. message_begin( MSG_BROADCAST, SVC_TEMPENTITY )
  116. {
  117. write_byte( TE_BUBBLETRAIL )
  118. write_coord_f( vecSource[0] ) // mins
  119. write_coord_f( vecSource[1] )
  120. write_coord_f( vecSource[2] )
  121. write_coord_f( vecTo[0] ) // maxz
  122. write_coord_f( vecTo[1] )
  123. write_coord_f( vecTo[2] )
  124. write_coord_f( flHeight ) // height
  125. write_short( g_sModelIndexBubbles )
  126. write_byte( iCount ) // count
  127. write_coord( 8 ) // speed
  128. }
  129. message_end()
  130. }
  131.  
  132. Float:UTIL_WaterLevel( Float:position[3], Float:minz, Float:maxz )
  133. {
  134. new Float:midUp[3]
  135. midUp[0] = position[0]
  136. midUp[1] = position[1]
  137. midUp[2] = minz
  138.  
  139. if (engfunc(EngFunc_PointContents, midUp) != CONTENTS_WATER)
  140. return minz
  141.  
  142. midUp[2] = maxz
  143. if (engfunc(EngFunc_PointContents, midUp) == CONTENTS_WATER)
  144. return maxz
  145.  
  146. new Float:diff = maxz - minz
  147. while(diff > 1.0)
  148. {
  149. midUp[2] = minz + diff/2.0
  150. if (engfunc(EngFunc_PointContents, midUp) == CONTENTS_WATER)
  151. {
  152. minz = midUp[2]
  153. }
  154. else
  155. {
  156. maxz = midUp[2]
  157. }
  158. diff = maxz - minz
  159. }
  160.  
  161. return midUp[2]
  162. }