Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma semicolon 1
- #include <sourcemod>
- #include <sdktools>
- #include <tf2>
- #include <tf2_stocks>
- #include <sdkhooks>
- //#include <stocklib>
- #define PLUGIN_VERSION "1.0.2.4"
- public Plugin:myinfo = {
- name = "TF2CoolRocket",
- author = "javalia",
- description = "based on idea and work of predcrab`s extension, sidewinder",
- version = PLUGIN_VERSION,
- url = "http://www.sourcemod.net/"
- };
- #define HOME_SENTRYROCKET (1 << 0) //1
- #define HOME_ROCKET (1 << 1) //2
- #define HOME_PIPE (1 << 2) //4
- #define HOME_STICKY (1 << 3) //8
- #define HOME_SYRINGE (1 << 4) //16
- #define HOME_FLARE (1 << 5) //32
- #define HOME_JARATE (1 << 6) //64
- #define HOME_ARROW (1 << 7) //128
- #define HOME_FLAMEROCKET (1 << 8) //256
- #define HOME_MILK (1 << 9) //512
- #define HOME_HEALINGBOLT (1 << 10) //1024
- #define HOME_MANGLERROCKET (1 << 11) //2048
- #define HOME_BISONSHOT (1 << 12) //4096
- #define HOME_STUNBALL (1 << 13) //8192
- new Handle:g_cvarInduceWeaponList = INVALID_HANDLE;
- new Handle:g_cvarArrowToHead = INVALID_HANDLE;
- new Handle:g_cvarSentryCritChance = INVALID_HANDLE;
- new Handle:g_cvarHomeChance = INVALID_HANDLE;
- new g_iInduceWeaponList = 1;
- new g_bArrowToHead = true;
- new g_iSentryCritChance = 0;
- new g_iHomeChance = 0;
- new g_iTarget[2048];
- new bool:g_bToHead[2048];
- public OnPluginStart(){
- CreateConVar("TF2CoolRocket_version", PLUGIN_VERSION, "TF2CoolRocket plugin version cvar", FCVAR_REPLICATED | FCVAR_NOTIFY |FCVAR_SPONLY|FCVAR_PLUGIN);
- 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);
- g_cvarArrowToHead = CreateConVar("TF2CoolRocket_ArrowToHead", "1", "1 or 0", FCVAR_PLUGIN, true, 0.0, true, 1.0);
- g_cvarSentryCritChance = CreateConVar("TF2CoolRocket_SentryCritChance", "0", "Set 1 to 100 to turn on Sentry crits", FCVAR_PLUGIN, true, 0.0, true, 100.0);
- g_cvarHomeChance = CreateConVar("TF2CoolRocket_HomeChance", "50", "Set 1 to 100 to turn on Homing", FCVAR_PLUGIN, true, 0.0, true, 100.0);
- HookConVarChange(g_cvarInduceWeaponList, Cvar_Change);
- HookConVarChange(g_cvarArrowToHead, Cvar_Change);
- HookConVarChange(g_cvarSentryCritChance, Cvar_Change);
- HookConVarChange(g_cvarHomeChance, Cvar_Change);
- AutoExecConfig();
- g_iInduceWeaponList = GetConVarInt(g_cvarInduceWeaponList);
- g_bArrowToHead = GetConVarBool(g_cvarArrowToHead);
- g_iSentryCritChance = GetConVarBool(g_cvarSentryCritChance);
- g_iHomeChance = GetConVarBool(g_cvarHomeChance);
- }
- public Cvar_Change(Handle:convar, const String:oldValue[], const String:newValue[])
- {
- if (convar == g_cvarInduceWeaponList)
- g_iInduceWeaponList = GetConVarInt(convar);
- else if (convar == g_cvarSentryCritChance)
- g_iSentryCritChance = GetConVarInt(convar);
- else if (convar == g_cvarHomeChance)
- g_iHomeChance = GetConVarInt(convar);
- else if (convar == g_cvarArrowToHead)
- g_bArrowToHead = GetConVarBool(convar);
- }
- public OnEntityCreated(entity, const String:classname[]){
- //lets save cpu. at this will avoid long string compare compute that can execute for EVERY entitys that are created on server.
- if(strncmp(classname, "tf_projectile_", 14, false) == 0 && ((GetURandomInt() % 100) < g_iHomeChance))
- {
- // decl String:cvarstring[2048];
- // GetConVarString(g_cvarInduceWeaponList, cvarstring, 2048);
- if(IsTrackingProjectile(classname))
- {
- //hook think, create dynamic array, init thinkcount...
- g_iTarget[entity] = INVALID_ENT_REFERENCE;
- if(strcmp(classname, "tf_projectile_arrow", false) == 0)
- {
- if (g_bArrowToHead)
- {
- g_bToHead[entity] = true;
- }
- else
- {
- g_bToHead[entity] = false;
- }
- }
- SDKHook(entity, SDKHook_Think, RocketThinkHook);
- // PrintToChatAll("%d", GetEntityMoveType(entity));
- // if (GetEntityMoveType(entity) != MOVETYPE_FLY)
- // SetEntityMoveType(entity, MOVETYPE_FLY);
- if (strcmp(classname, "tf_projectile_sentryrocket", false) == 0) SDKHook(entity, SDKHook_Spawn, SentryRocketSpawn);
- }
- }
- }
- public SentryRocketSpawn(entity)
- {
- if ((GetURandomInt() % 100) < g_iSentryCritChance) SetEntProp(entity, Prop_Send, "m_bCritical", 1);
- }
- stock bool:IsTrackingProjectile(const String:classname[])
- {
- if ((g_iInduceWeaponList & HOME_SENTRYROCKET) && strcmp(classname, "tf_projectile_sentryrocket", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_ROCKET) && strcmp(classname, "tf_projectile_rocket", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_PIPE) && strcmp(classname, "tf_projectile_pipe", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_STICKY) && strcmp(classname, "tf_projectile_pipe_remote", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_SYRINGE) && strcmp(classname, "tf_projectile_syringe", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_FLARE) && strcmp(classname, "tf_projectile_flare", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_JARATE) && strcmp(classname, "tf_projectile_jar", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_ARROW) && strcmp(classname, "tf_projectile_arrow", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_FLAMEROCKET) && strcmp(classname, "tf_projectile_flame_rocket", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_MILK) && strcmp(classname, "tf_projectile_jar_milk", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_HEALINGBOLT) && strcmp(classname, "tf_projectile_healing_bolt", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_MANGLERROCKET) && strcmp(classname, "tf_projectile_energy_ball", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_BISONSHOT) && strcmp(classname, "tf_projectile_energy_ring", false) == 0) return true;
- if ((g_iInduceWeaponList & HOME_STUNBALL) && strcmp(classname, "tf_projectile_stunball", false) == 0) return true;
- return false;
- }
- public RocketThinkHook(entity)
- {
- //is rocket has target?
- if(isValidTarget(entity, g_iTarget[entity]) && isTargetTraceable(entity, g_iTarget[entity]))
- {
- new target = EntRefToEntIndex(g_iTarget[entity]);
- decl Float:rocketposition[3], Float:targetpos[3], Float:vecangle[3], Float:angle[3];
- GetEntPropVector(entity, Prop_Send, "m_vecOrigin", rocketposition);
- //로켓포지션에서 추적 위치로 가는 벡터를 구한다 To position the rocket on the track where the vector is obtained
- GetClientEyePosition(target, targetpos);
- if(!g_bToHead[entity]){
- targetpos[2] = targetpos[2] - 25.0;
- }
- MakeVectorFromPoints(rocketposition, targetpos, vecangle);
- NormalizeVector(vecangle, vecangle);
- GetVectorAngles(vecangle, angle);
- decl Float:speed[3];
- GetEntPropVector(entity, Prop_Data, "m_vecVelocity", speed);
- ScaleVector(vecangle, GetVectorLength(speed));
- TeleportEntity(entity, NULL_VECTOR, angle, vecangle);
- // decl Float:rocketposition[3], Float:targetpos[3], Float:vecangle[3], Float:angle[3], Float:speed[3];
- // new Float:speedmul = 1100.0;
- // GetEntPropVector(entity, Prop_Send, "m_vecOrigin", rocketposition);
- // GetEntPropVector(entity, Prop_Data, "m_vecVelocity", speed);
- // speedmul = GetVectorLength(speed);
- //로켓포지션에서 추적 위치로 가는 벡터를 구한다 To position the rocket on the track where the vector is obtained
- // GetClientEyePosition(target, targetpos);
- // if(!g_bToHead[entity])
- // {
- // targetpos[2] = targetpos[2] - 25.0;
- // }
- // MakeVectorFromPoints(rocketposition, targetpos, vecangle);
- // NormalizeVector(vecangle, vecangle);
- // GetVectorAngles(vecangle, angle);
- // ScaleVector(vecangle, speedmul);
- // TeleportEntity(entity, NULL_VECTOR, angle, vecangle);
- }
- else
- {
- g_iTarget[entity] = findNewTarget(entity);
- }
- }
- // void CTrackingProjectile::TurnToTarget(CEntity *pEntity)
- // {
- // Retrieve rocket info.
- // Vector fRocketPosition = GetLocalOrigin();
- // Vector fRocketOrientation = GetAbsVelocity();
- // vec_t fCurrentSpeed;
- // Calculate speed and orientation.
- // fCurrentSpeed = /*fRocketOrientation.Length()*/ 1100.0 * RocketSpeedMul.GetFloat();
- // fCurrentSpeed *= (ReflectSpeedInk.GetFloat() * (*m_iDeflected/* - 1*/)) + 1.0;
- // fRocketOrientation.NormalizeInPlace();
- // Retrieve client position and calculate new orientation.
- // Vector fOrientation = pEntity->GetLocalOrigin();
- // fOrientation[0] -= fRocketPosition[0];
- // fOrientation[1] -= fRocketPosition[1];
- // fOrientation[2] -= fRocketPosition[2] - 50.0;
- // fOrientation.NormalizeInPlace();
- // Lerp from the current orientation to the new one.
- // fRocketOrientation[0] = Lerp<vec_t>(RocketTurnRate.GetFloat(), fRocketOrientation[0], fOrientation[0]);
- // fRocketOrientation[1] = Lerp<vec_t>(RocketTurnRate.GetFloat(), fRocketOrientation[1], fOrientation[1]);
- // fRocketOrientation[2] = Lerp<vec_t>(RocketTurnRate.GetFloat(), fRocketOrientation[2], fOrientation[2]);
- // fRocketOrientation.NormalizeInPlace();
- // Calculate angles and final speed.
- // QAngle fRocketAngles;
- // VectorAngles(fRocketOrientation, fRocketAngles);
- // Vector fRocketSpeed;
- // fRocketSpeed[0] = fRocketOrientation[0] * fCurrentSpeed;
- // fRocketSpeed[1] = fRocketOrientation[1] * fCurrentSpeed;
- // fRocketSpeed[2] = fRocketOrientation[2] * fCurrentSpeed;
- // Done
- // Teleport(NULL, &fRocketAngles, &fRocketSpeed);
- // }
- stock bool:IsValidClient(client)
- {
- if (client <= 0) return false;
- if (client > MaxClients) return false;
- // if (!IsClientConnected(client)) return false;
- return IsClientInGame(client);
- }
- findNewTarget(entity){
- new targetlist[MaxClients];
- new targetcount = 0;
- //makes list of valid client
- for(new i = 0; i < MaxClients; i++){
- if(isValidTarget(entity, EntIndexToEntRef(i)) && isTargetTraceable(entity, EntIndexToEntRef(i)))
- {
- targetlist[targetcount] = i;
- targetcount++;
- }
- }
- if(targetcount != 0)
- {
- //make list of all valid client`s distance from rocket
- new Float:distance[MaxClients];
- for(new i = 0; i < targetcount; i++)
- {
- new Float:entorigin[3], Float:targetorigin[3];
- GetEntPropVector(entity, Prop_Send, "m_vecOrigin", entorigin);
- GetClientEyePosition(targetlist[i], targetorigin);
- distance[i] = GetVectorDistance(entorigin, targetorigin);
- }
- //find lowest distance of that distancelist
- new Float:lowestdistance = distance[0];
- for(new i = 0; i < targetcount; i++)
- {
- if(lowestdistance > distance[i])
- {
- lowestdistance = distance[i];
- }
- }
- //make list of clients that thier distance is same as lowestdistance
- //at most of time, there will actually only 1 client on this list
- new finaltargetlist[MaxClients];
- new finaltargetcount = 0;
- for(new i = 0; i < targetcount; i++)
- {
- if(lowestdistance == distance[i])
- {
- finaltargetlist[finaltargetcount] = targetlist[i];
- finaltargetcount++;
- }
- }
- //get and return randome client.
- return EntIndexToEntRef(finaltargetlist[GetRandomInt(0, finaltargetcount - 1)]);
- }
- return INVALID_ENT_REFERENCE;
- }
- bool:isValidTarget(entity, targetentref)
- {
- new target = EntRefToEntIndex(targetentref);
- if(IsValidClient(target) && IsPlayerAlive(target))
- {
- if(GetEntProp(entity, Prop_Data, "m_iTeamNum") != GetClientTeam(target))
- {
- return true;
- }
- }
- return false;
- }
- bool:isTargetTraceable(entity, targetentref){
- new target = EntRefToEntIndex(targetentref);
- //타겟까지 트레이스가 가능한가 Is it possible to trace the target
- new bool:traceable = false;
- decl Float:entityposition[3];
- GetEntPropVector(entity, Prop_Send, "m_vecOrigin", entityposition);
- decl Float:clientpos[3];
- GetClientEyePosition(target, clientpos);
- if(!g_bToHead[entity]){
- clientpos[2] = clientpos[2] - 25.0;
- }
- new Handle:traceresult = TR_TraceRayFilterEx(entityposition, clientpos, MASK_SOLID, RayType_EndPoint, TraceRayDontHitSelf, entity);
- if(TR_GetEntityIndex(traceresult) == target)
- {
- traceable = true;
- }
- CloseHandle(traceresult);
- new bool:targetvalid = false;
- //은폐를 사용중인가? cloaked?
- if(TF2_IsPlayerInCondition(target, TFCond_Cloaked))
- {
- //보이는 상황인가? exceptions?
- if(TF2_IsPlayerInCondition(target, TFCond_CloakFlicker)
- || TF2_IsPlayerInCondition(target, TFCond_OnFire)
- || TF2_IsPlayerInCondition(target, TFCond_Jarated)
- || TF2_IsPlayerInCondition(target, TFCond_Milked)
- || TF2_IsPlayerInCondition(target, TFCond_Bleeding)
- // || TF2_IsPlayerInCondition(target, TFCond_Disguising)
- )
- {
- targetvalid = true;
- }
- else
- {
- targetvalid = false;
- }
- }
- else
- {
- //변장을 했고, 변장이 끝났는가? disguise has ended?
- if(!TF2_IsPlayerInCondition(target, TFCond_Disguising) && TF2_IsPlayerInCondition(target, TFCond_Disguised) && GetEntProp(target, Prop_Send, "m_nDisguiseTeam") == GetEntProp(entity, Prop_Data, "m_iTeamNum"))
- {
- targetvalid = false;
- }
- else
- {
- targetvalid = true;
- }
- }
- return traceable && targetvalid;
- }
- public bool:TraceRayDontHitSelf(entity, mask, any:data)
- {
- return (entity != data);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement