Advertisement
Guest User

Untitled

a guest
Jul 27th, 2011
633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.98 KB | None | 0 0
  1. #pragma semicolon 1
  2.  
  3. #include <sourcemod>
  4. #include <sdktools>
  5. #include <tf2>
  6. #include <tf2_stocks>
  7. #include <sdkhooks>
  8. //#include <stocklib>
  9.  
  10. #define PLUGIN_VERSION "1.0.2.4"
  11.  
  12. public Plugin:myinfo = {
  13.  
  14. name = "TF2CoolRocket",
  15. author = "javalia",
  16. description = "based on idea and work of predcrab`s extension, sidewinder",
  17. version = PLUGIN_VERSION,
  18. url = "http://www.sourcemod.net/"
  19.  
  20. };
  21.  
  22. #define HOME_SENTRYROCKET (1 << 0) //1
  23. #define HOME_ROCKET (1 << 1) //2
  24. #define HOME_PIPE (1 << 2) //4
  25. #define HOME_STICKY (1 << 3) //8
  26. #define HOME_SYRINGE (1 << 4) //16
  27. #define HOME_FLARE (1 << 5) //32
  28. #define HOME_JARATE (1 << 6) //64
  29. #define HOME_ARROW (1 << 7) //128
  30. #define HOME_FLAMEROCKET (1 << 8) //256
  31. #define HOME_MILK (1 << 9) //512
  32. #define HOME_HEALINGBOLT (1 << 10) //1024
  33. #define HOME_MANGLERROCKET (1 << 11) //2048
  34. #define HOME_BISONSHOT (1 << 12) //4096
  35. #define HOME_STUNBALL (1 << 13) //8192
  36.  
  37. new Handle:g_cvarInduceWeaponList = INVALID_HANDLE;
  38. new Handle:g_cvarArrowToHead = INVALID_HANDLE;
  39. new Handle:g_cvarSentryCritChance = INVALID_HANDLE;
  40. new Handle:g_cvarHomeChance = INVALID_HANDLE;
  41.  
  42. new g_iInduceWeaponList = 1;
  43. new g_bArrowToHead = true;
  44. new g_iSentryCritChance = 0;
  45. new g_iHomeChance = 0;
  46.  
  47. new g_iTarget[2048];
  48. new bool:g_bToHead[2048];
  49.  
  50. public OnPluginStart(){
  51.  
  52. CreateConVar("TF2CoolRocket_version", PLUGIN_VERSION, "TF2CoolRocket plugin version cvar", FCVAR_REPLICATED | FCVAR_NOTIFY |FCVAR_SPONLY|FCVAR_PLUGIN);
  53.  
  54. g_cvarInduceWeaponList = CreateConVar("TF2CoolRocket_InduceWeaponList", "1", "See plugin thread for info on what to change here. All - 16383", FCVAR_PLUGIN, true, 0.0, true, 16383.0);
  55. g_cvarArrowToHead = CreateConVar("TF2CoolRocket_ArrowToHead", "1", "1 or 0", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  56. g_cvarSentryCritChance = CreateConVar("TF2CoolRocket_SentryCritChance", "0", "Set 1 to 100 to turn on Sentry crits", FCVAR_PLUGIN, true, 0.0, true, 100.0);
  57. g_cvarHomeChance = CreateConVar("TF2CoolRocket_HomeChance", "50", "Set 1 to 100 to turn on Homing", FCVAR_PLUGIN, true, 0.0, true, 100.0);
  58.  
  59. HookConVarChange(g_cvarInduceWeaponList, Cvar_Change);
  60. HookConVarChange(g_cvarArrowToHead, Cvar_Change);
  61. HookConVarChange(g_cvarSentryCritChance, Cvar_Change);
  62. HookConVarChange(g_cvarHomeChance, Cvar_Change);
  63. AutoExecConfig();
  64. g_iInduceWeaponList = GetConVarInt(g_cvarInduceWeaponList);
  65. g_bArrowToHead = GetConVarBool(g_cvarArrowToHead);
  66. g_iSentryCritChance = GetConVarBool(g_cvarSentryCritChance);
  67. g_iHomeChance = GetConVarBool(g_cvarHomeChance);
  68.  
  69. }
  70. public Cvar_Change(Handle:convar, const String:oldValue[], const String:newValue[])
  71. {
  72. if (convar == g_cvarInduceWeaponList)
  73. g_iInduceWeaponList = GetConVarInt(convar);
  74. else if (convar == g_cvarSentryCritChance)
  75. g_iSentryCritChance = GetConVarInt(convar);
  76. else if (convar == g_cvarHomeChance)
  77. g_iHomeChance = GetConVarInt(convar);
  78. else if (convar == g_cvarArrowToHead)
  79. g_bArrowToHead = GetConVarBool(convar);
  80. }
  81. public OnEntityCreated(entity, const String:classname[]){
  82.  
  83. //lets save cpu. at this will avoid long string compare compute that can execute for EVERY entitys that are created on server.
  84. if(strncmp(classname, "tf_projectile_", 14, false) == 0 && ((GetURandomInt() % 100) < g_iHomeChance))
  85. {
  86. // decl String:cvarstring[2048];
  87. // GetConVarString(g_cvarInduceWeaponList, cvarstring, 2048);
  88.  
  89. if(IsTrackingProjectile(classname))
  90. {
  91.  
  92. //hook think, create dynamic array, init thinkcount...
  93. g_iTarget[entity] = INVALID_ENT_REFERENCE;
  94.  
  95. if(strcmp(classname, "tf_projectile_arrow", false) == 0)
  96. {
  97. if (g_bArrowToHead)
  98. {
  99. g_bToHead[entity] = true;
  100. }
  101. else
  102. {
  103. g_bToHead[entity] = false;
  104. }
  105. }
  106. SDKHook(entity, SDKHook_Think, RocketThinkHook);
  107. // PrintToChatAll("%d", GetEntityMoveType(entity));
  108. // if (GetEntityMoveType(entity) != MOVETYPE_FLY)
  109. // SetEntityMoveType(entity, MOVETYPE_FLY);
  110. if (strcmp(classname, "tf_projectile_sentryrocket", false) == 0) SDKHook(entity, SDKHook_Spawn, SentryRocketSpawn);
  111. }
  112.  
  113. }
  114.  
  115. }
  116. public SentryRocketSpawn(entity)
  117. {
  118. if ((GetURandomInt() % 100) < g_iSentryCritChance) SetEntProp(entity, Prop_Send, "m_bCritical", 1);
  119. }
  120. stock bool:IsTrackingProjectile(const String:classname[])
  121. {
  122. if ((g_iInduceWeaponList & HOME_SENTRYROCKET) && strcmp(classname, "tf_projectile_sentryrocket", false) == 0) return true;
  123. if ((g_iInduceWeaponList & HOME_ROCKET) && strcmp(classname, "tf_projectile_rocket", false) == 0) return true;
  124. if ((g_iInduceWeaponList & HOME_PIPE) && strcmp(classname, "tf_projectile_pipe", false) == 0) return true;
  125. if ((g_iInduceWeaponList & HOME_STICKY) && strcmp(classname, "tf_projectile_pipe_remote", false) == 0) return true;
  126. if ((g_iInduceWeaponList & HOME_SYRINGE) && strcmp(classname, "tf_projectile_syringe", false) == 0) return true;
  127. if ((g_iInduceWeaponList & HOME_FLARE) && strcmp(classname, "tf_projectile_flare", false) == 0) return true;
  128. if ((g_iInduceWeaponList & HOME_JARATE) && strcmp(classname, "tf_projectile_jar", false) == 0) return true;
  129. if ((g_iInduceWeaponList & HOME_ARROW) && strcmp(classname, "tf_projectile_arrow", false) == 0) return true;
  130. if ((g_iInduceWeaponList & HOME_FLAMEROCKET) && strcmp(classname, "tf_projectile_flame_rocket", false) == 0) return true;
  131. if ((g_iInduceWeaponList & HOME_MILK) && strcmp(classname, "tf_projectile_jar_milk", false) == 0) return true;
  132. if ((g_iInduceWeaponList & HOME_HEALINGBOLT) && strcmp(classname, "tf_projectile_healing_bolt", false) == 0) return true;
  133. if ((g_iInduceWeaponList & HOME_MANGLERROCKET) && strcmp(classname, "tf_projectile_energy_ball", false) == 0) return true;
  134. if ((g_iInduceWeaponList & HOME_BISONSHOT) && strcmp(classname, "tf_projectile_energy_ring", false) == 0) return true;
  135. if ((g_iInduceWeaponList & HOME_STUNBALL) && strcmp(classname, "tf_projectile_stunball", false) == 0) return true;
  136.  
  137. return false;
  138. }
  139. public RocketThinkHook(entity)
  140. {
  141. //is rocket has target?
  142. if(isValidTarget(entity, g_iTarget[entity]) && isTargetTraceable(entity, g_iTarget[entity]))
  143. {
  144.  
  145. new target = EntRefToEntIndex(g_iTarget[entity]);
  146.  
  147. decl Float:rocketposition[3], Float:targetpos[3], Float:vecangle[3], Float:angle[3];
  148. GetEntPropVector(entity, Prop_Send, "m_vecOrigin", rocketposition);
  149.  
  150. //로켓포지션에서 추적 위치로 가는 벡터를 구한다 To position the rocket on the track where the vector is obtained
  151. GetClientEyePosition(target, targetpos);
  152. if(!g_bToHead[entity]){
  153.  
  154. targetpos[2] = targetpos[2] - 25.0;
  155.  
  156. }
  157. MakeVectorFromPoints(rocketposition, targetpos, vecangle);
  158. NormalizeVector(vecangle, vecangle);
  159. GetVectorAngles(vecangle, angle);
  160. decl Float:speed[3];
  161. GetEntPropVector(entity, Prop_Data, "m_vecVelocity", speed);
  162. ScaleVector(vecangle, GetVectorLength(speed));
  163. TeleportEntity(entity, NULL_VECTOR, angle, vecangle);
  164.  
  165. // decl Float:rocketposition[3], Float:targetpos[3], Float:vecangle[3], Float:angle[3], Float:speed[3];
  166. // new Float:speedmul = 1100.0;
  167. // GetEntPropVector(entity, Prop_Send, "m_vecOrigin", rocketposition);
  168. // GetEntPropVector(entity, Prop_Data, "m_vecVelocity", speed);
  169. // speedmul = GetVectorLength(speed);
  170.  
  171. //로켓포지션에서 추적 위치로 가는 벡터를 구한다 To position the rocket on the track where the vector is obtained
  172. // GetClientEyePosition(target, targetpos);
  173. // if(!g_bToHead[entity])
  174. // {
  175. // targetpos[2] = targetpos[2] - 25.0;
  176. // }
  177. // MakeVectorFromPoints(rocketposition, targetpos, vecangle);
  178. // NormalizeVector(vecangle, vecangle);
  179. // GetVectorAngles(vecangle, angle);
  180. // ScaleVector(vecangle, speedmul);
  181. // TeleportEntity(entity, NULL_VECTOR, angle, vecangle);
  182. }
  183. else
  184. {
  185. g_iTarget[entity] = findNewTarget(entity);
  186. }
  187. }
  188. // void CTrackingProjectile::TurnToTarget(CEntity *pEntity)
  189. // {
  190. // Retrieve rocket info.
  191. // Vector fRocketPosition = GetLocalOrigin();
  192. // Vector fRocketOrientation = GetAbsVelocity();
  193. // vec_t fCurrentSpeed;
  194.  
  195. // Calculate speed and orientation.
  196. // fCurrentSpeed = /*fRocketOrientation.Length()*/ 1100.0 * RocketSpeedMul.GetFloat();
  197. // fCurrentSpeed *= (ReflectSpeedInk.GetFloat() * (*m_iDeflected/* - 1*/)) + 1.0;
  198. // fRocketOrientation.NormalizeInPlace();
  199.  
  200. // Retrieve client position and calculate new orientation.
  201. // Vector fOrientation = pEntity->GetLocalOrigin();
  202. // fOrientation[0] -= fRocketPosition[0];
  203. // fOrientation[1] -= fRocketPosition[1];
  204. // fOrientation[2] -= fRocketPosition[2] - 50.0;
  205. // fOrientation.NormalizeInPlace();
  206.  
  207. // Lerp from the current orientation to the new one.
  208. // fRocketOrientation[0] = Lerp<vec_t>(RocketTurnRate.GetFloat(), fRocketOrientation[0], fOrientation[0]);
  209. // fRocketOrientation[1] = Lerp<vec_t>(RocketTurnRate.GetFloat(), fRocketOrientation[1], fOrientation[1]);
  210. // fRocketOrientation[2] = Lerp<vec_t>(RocketTurnRate.GetFloat(), fRocketOrientation[2], fOrientation[2]);
  211. // fRocketOrientation.NormalizeInPlace();
  212.  
  213. // Calculate angles and final speed.
  214. // QAngle fRocketAngles;
  215. // VectorAngles(fRocketOrientation, fRocketAngles);
  216. // Vector fRocketSpeed;
  217. // fRocketSpeed[0] = fRocketOrientation[0] * fCurrentSpeed;
  218. // fRocketSpeed[1] = fRocketOrientation[1] * fCurrentSpeed;
  219. // fRocketSpeed[2] = fRocketOrientation[2] * fCurrentSpeed;
  220.  
  221. // Done
  222. // Teleport(NULL, &fRocketAngles, &fRocketSpeed);
  223. // }
  224. stock bool:IsValidClient(client)
  225. {
  226. if (client <= 0) return false;
  227. if (client > MaxClients) return false;
  228. // if (!IsClientConnected(client)) return false;
  229. return IsClientInGame(client);
  230. }
  231. findNewTarget(entity){
  232.  
  233. new targetlist[MaxClients];
  234. new targetcount = 0;
  235.  
  236. //makes list of valid client
  237. for(new i = 0; i < MaxClients; i++){
  238.  
  239. if(isValidTarget(entity, EntIndexToEntRef(i)) && isTargetTraceable(entity, EntIndexToEntRef(i)))
  240. {
  241.  
  242. targetlist[targetcount] = i;
  243. targetcount++;
  244. }
  245. }
  246.  
  247. if(targetcount != 0)
  248. {
  249.  
  250. //make list of all valid client`s distance from rocket
  251. new Float:distance[MaxClients];
  252.  
  253. for(new i = 0; i < targetcount; i++)
  254. {
  255. new Float:entorigin[3], Float:targetorigin[3];
  256. GetEntPropVector(entity, Prop_Send, "m_vecOrigin", entorigin);
  257. GetClientEyePosition(targetlist[i], targetorigin);
  258. distance[i] = GetVectorDistance(entorigin, targetorigin);
  259. }
  260.  
  261. //find lowest distance of that distancelist
  262. new Float:lowestdistance = distance[0];
  263.  
  264. for(new i = 0; i < targetcount; i++)
  265. {
  266. if(lowestdistance > distance[i])
  267. {
  268. lowestdistance = distance[i];
  269. }
  270. }
  271.  
  272. //make list of clients that thier distance is same as lowestdistance
  273. //at most of time, there will actually only 1 client on this list
  274. new finaltargetlist[MaxClients];
  275. new finaltargetcount = 0;
  276.  
  277. for(new i = 0; i < targetcount; i++)
  278. {
  279. if(lowestdistance == distance[i])
  280. {
  281. finaltargetlist[finaltargetcount] = targetlist[i];
  282. finaltargetcount++;
  283. }
  284. }
  285.  
  286. //get and return randome client.
  287. return EntIndexToEntRef(finaltargetlist[GetRandomInt(0, finaltargetcount - 1)]);
  288. }
  289. return INVALID_ENT_REFERENCE;
  290. }
  291.  
  292. bool:isValidTarget(entity, targetentref)
  293. {
  294. new target = EntRefToEntIndex(targetentref);
  295.  
  296. if(IsValidClient(target) && IsPlayerAlive(target))
  297. {
  298. if(GetEntProp(entity, Prop_Data, "m_iTeamNum") != GetClientTeam(target))
  299. {
  300. return true;
  301. }
  302. }
  303.  
  304. return false;
  305.  
  306. }
  307.  
  308. bool:isTargetTraceable(entity, targetentref){
  309.  
  310. new target = EntRefToEntIndex(targetentref);
  311.  
  312. //타겟까지 트레이스가 가능한가 Is it possible to trace the target
  313. new bool:traceable = false;
  314. decl Float:entityposition[3];
  315. GetEntPropVector(entity, Prop_Send, "m_vecOrigin", entityposition);
  316. decl Float:clientpos[3];
  317. GetClientEyePosition(target, clientpos);
  318. if(!g_bToHead[entity]){
  319.  
  320. clientpos[2] = clientpos[2] - 25.0;
  321.  
  322. }
  323.  
  324. new Handle:traceresult = TR_TraceRayFilterEx(entityposition, clientpos, MASK_SOLID, RayType_EndPoint, TraceRayDontHitSelf, entity);
  325.  
  326. if(TR_GetEntityIndex(traceresult) == target)
  327. {
  328. traceable = true;
  329. }
  330. CloseHandle(traceresult);
  331.  
  332. new bool:targetvalid = false;
  333.  
  334. //은폐를 사용중인가? cloaked?
  335. if(TF2_IsPlayerInCondition(target, TFCond_Cloaked))
  336. {
  337. //보이는 상황인가? exceptions?
  338. if(TF2_IsPlayerInCondition(target, TFCond_CloakFlicker)
  339. || TF2_IsPlayerInCondition(target, TFCond_OnFire)
  340. || TF2_IsPlayerInCondition(target, TFCond_Jarated)
  341. || TF2_IsPlayerInCondition(target, TFCond_Milked)
  342. || TF2_IsPlayerInCondition(target, TFCond_Bleeding)
  343. // || TF2_IsPlayerInCondition(target, TFCond_Disguising)
  344. )
  345. {
  346. targetvalid = true;
  347. }
  348. else
  349. {
  350. targetvalid = false;
  351. }
  352. }
  353. else
  354. {
  355. //변장을 했고, 변장이 끝났는가? disguise has ended?
  356. if(!TF2_IsPlayerInCondition(target, TFCond_Disguising) && TF2_IsPlayerInCondition(target, TFCond_Disguised) && GetEntProp(target, Prop_Send, "m_nDisguiseTeam") == GetEntProp(entity, Prop_Data, "m_iTeamNum"))
  357. {
  358. targetvalid = false;
  359. }
  360. else
  361. {
  362. targetvalid = true;
  363. }
  364.  
  365. }
  366. return traceable && targetvalid;
  367. }
  368. public bool:TraceRayDontHitSelf(entity, mask, any:data)
  369. {
  370. return (entity != data);
  371. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement