Raised This Month: $120 Target: $400
 30% 

[CSGO] Unfinished TF2 sentry


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Pelipoika
Veteran Member
Join Date: May 2012
Location: Inside
Old 03-16-2018 , 16:12   [CSGO] Unfinished TF2 sentry
Reply With Quote #1

Finish me

csgo.sentry.txt
Code:
"Games"
{
	"csgo"
	{
		"Signatures"
		{
			"CBaseAnimating::LookupSequence" //int ( const char *label )
			{
				"windows"	"\x55\x8B\xEC\x51\x56\x57\x8B\xF9\x83\xBF\x9C\x04\x00\x00\x00\x75\x2A\xA1\x2A\x2A\x2A\x2A\x8B\x30\x8B\x07\xFF\x50\x18\x8B\x0D\x2A\x2A\x2A\x2A\x50\xFF\x56\x04\x85\xC0\x74\x2A\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x8B\xB7\x9C\x04\x00\x00\x85\xF6\x74\x2A\x83\x3E\x00\x74\x2A\x8B\xCE"
			}
			"CBaseAnimating::ResetSequence"		//(int nSequence) | STR: "ResetSequence : %s: %s -> %s\n"
			{
				"windows"	"\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x08\x53\x56\x8B\xD9"
			}
			"CBaseAnimating::StudioFrameAdvance"
			{
			//	"windows"	"\x55\x8B\xEC\x83\xE4\xC0\x83\xEC\x34\x53\x56\x57\x8B\xF9\x83\xBF\x9C\x04\x00\x00\x00"
				"windows"	"\x55\x8B\xEC\x83\xE4\xC0\xA1\x2A\x2A\x2A\x2A\x83\xEC\x34\xF3\x0F\x10\x48\x10" //CBaseAnimatingOverlay::StudioFrameAdvance ()
			}
			
			"CBaseAnimating::LookupPoseParameter" //( CStudioHdr *pStudioHdr, const char *szName )
			{
				"windows"	"\x55\x8B\xEC\x57\x8B\x7D\x08\x85\xFF\x75\x2A"
			}
			
			//int	CBaseAnimatingOverlay::AddLayeredSequence( int sequence, int iPriority )
			"CBaseAnimatingOverlay::AddLayeredSequence" //
			{
				"windows"	"\x55\x8B\xEC\x83\xE4\xC0\x83\xEC\x34\x53\x56\x57\xFF\x75\x0C"
			}
			
			"CBaseAnimating::GetAttachment" //bool ( char iAttachment, Vector &absOrigin, QAngle &absAngles ) | STR: "vehicle_driver_eyes"
			{
				"windows"	"\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x30\x56\x57\x8B\xF9\x83\xBF\x9C\x04\x00\x00\x00\x75\x2A\xA1\x2A\x2A\x2A\x2A\x8B\x30\x8B\x07\xFF\x50\x18\x8B\x0D\x2A\x2A\x2A\x2A\x50\xFF\x56\x04\x85\xC0\x74\x2A\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x8B\x8F\x9C\x04\x00\x00\x85\xC9\x74\x2A\x83\x39\x00\x74\x2A\x8B\x55\x08"
			}
			
			"CBaseAnimatingOverlay::AddGesture" // int CBaseAnimatingOverlay::AddGesture( Activity activity, bool autokill /*= true*/ ) | STR: "CBaseAnimatingOverlay::AddGesture:  model %s missing activity %s\n"
			{
				"windows"	"\x55\x8B\xEC\x51\x53\x8B\x5D\x08\x56\x57\x53\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x83\xF8\xFF"
			}
			
			"CBaseAnimatingOverlay::FindGestureLayer" // int CBaseAnimatingOverlay::FindGestureLayer( Activity activity ) | STR: "CBaseAnimatingOverlay::AddGesture:  model %s missing activity %s\n"
			{
				"windows"	"\x55\x8B\xEC\x56\x8B\xB1\xBC\x04\x00\x00"
			}
			
			
			
			"CBaseAnimating::SelectWeightedSequence"
			{
				"windows"	"\x55\x8B\xEC\x53\x56\x57\x8B\xF9\x83\xBF\x9C\x04\x00\x00\x00"
			}
		//	"CBaseAnimating::SetSequence"
		//	{
		//		"windows"	"\x55\x8B\xEC\x8B\x45\x08\x53\x56\x57\x8B\xF9\x8B\x9F\xD4\x03\x00\x00"
		//	}
			"CBaseAnimating::ResetSequenceInfo"
			{
				"windows"	"\x55\x8B\xEC\x83\xE4\xF8\xA1\x2A\x2A\x2A\x2A\x83\xEC\x0C\x53\x56\x57\x8B\xF9\xB9\x2A\x2A\x2A\x2A\xFF\x50\x34\x85\xC0"
			}
		}
	}
}
May contain gamedata this plugin doesn't use

PHP Code:
#pragma semicolon 1

#define DEBUG

#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <cstrike>
#include <emitsoundany>
//#include <CBaseAnimatingOverlay>

#pragma newdecls required

#define EF_BONEMERGE       (1 << 0)
#define EF_PARENT_ANIMATES (1 << 9)

/*
for animating:
    LookupSequence //Lookup attachment index by name
    CBaseAnimating::GetAttachment //Get attachment positon with the index
    
    CBaseAnimating::StudioFrameAdvance //Advance animation
    CBaseAnimating::ResetSequence    //Set animation
    
    CBaseAnimating::LookupPoseParameter //Get a poseparameter index by name
    CBaseAnimating::GetPoseParameter //Get sentry gun rotation and stuff
    CBaseAnimating::SetPoseParameter //Set sentry gun rotation and stuff

for layered anims:
    CBaseAnimatingOverlay::AddGestureSequence

for firing:
to get muzzle attachment position
    Studio_FindAttachment
and
    CBaseAnimating::GetAttachment
*/

public Plugin myinfo 
{
    
name "[CSGO] Sentry Gun",
    
author "Pelipoika",
    
description "",
    
version "1.0",
    
url ""
};

Handle g_hResetSequence;
Handle g_hLookupSequence;
Handle g_hLookupActivity;

//Layered anims
Handle g_hAddLayeredSequence;

Handle g_hStudioFrameAdvance;

Handle g_hLookupPoseParameter;

Handle g_hGetAttachment;

//static int m_fFlags    = 0x5C;
static int m_fFlags    0x0;
static 
int m_nSequence 0x8;

public 
void OnPluginStart()
{
    
Handle hConf LoadGameConfigFile("csgo.sentry");

    
//LookupPoseParameter(CStudioHdr *pStudioHdr, const char *szName);
    
StartPrepSDKCall(SDKCall_Entity);
    
PrepSDKCall_SetFromConf(hConfSDKConf_Signature"CBaseAnimating::LookupPoseParameter");
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain); //pStudioHdr
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);     //szName
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain);
    if((
g_hLookupPoseParameter EndPrepSDKCall()) == INVALID_HANDLESetFailState("Failed to create Call for CBaseAnimating::LookupPoseParameter");
    
    
//-----------------------------------------------------------------------------
    // Purpose: Looks up a sequence by sequence name first, then by activity name.
    // Input  : label - The sequence name or activity name to look up.
    // Output : Returns the sequence index of the matching sequence, or ACT_INVALID.
    //-----------------------------------------------------------------------------
    //LookupSequence(const char *label);
    
StartPrepSDKCall(SDKCall_Entity);
    
PrepSDKCall_SetFromConf(hConfSDKConf_Signature"CBaseAnimating::LookupSequence");
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);        //label
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain);    //return index
    
if((g_hLookupSequence EndPrepSDKCall()) == INVALID_HANDLESetFailState("Failed to create Call for CBaseAnimating::LookupSequence");
    
    
//ResetSequence(int nSequence);
    
StartPrepSDKCall(SDKCall_Entity);
    
PrepSDKCall_SetFromConf(hConfSDKConf_Signature"CBaseAnimating::ResetSequence");
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain);
    if ((
g_hResetSequence EndPrepSDKCall()) == INVALID_HANDLESetFailState("Failed to create SDKCall for CBaseAnimating::ResetSequence signature!"); 

    
//int CBaseAnimatingOverlay::AddLayeredSequence( int sequence, int iPriority )
    
StartPrepSDKCall(SDKCall_Entity);
    
PrepSDKCall_SetFromConf(hConfSDKConf_Signature"CBaseAnimatingOverlay::AddLayeredSequence");
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain);  //sequence
    
PrepSDKCall_AddParameter(SDKType_PlainOldDataSDKPass_Plain);    //priority
    
PrepSDKCall_SetReturnInfo(SDKType_PlainOldDataSDKPass_Plain); //return layer
    
if((g_hAddLayeredSequence EndPrepSDKCall()) == INVALID_HANDLESetFailState("Failed to create Call for CBaseAnimatingOverlay::AddLayeredSequence");
    
    
//=========================================================
    // StudioFrameAdvance - advance the animation frame up some interval (default 0.1) into the future
    //=========================================================
    
StartPrepSDKCall(SDKCall_Entity);
    
PrepSDKCall_SetFromConf(hConfSDKConf_Signature"CBaseAnimating::StudioFrameAdvance");
    if ((
g_hStudioFrameAdvance EndPrepSDKCall()) == INVALID_HANDLESetFailState("Failed to create SDKCall for CBaseAnimating::StudioFrameAdvance signature!");     
    
    
//-----------------------------------------------------------------------------
    // Purpose: Returns the world location and world angles of an attachment
    // Input  : attachment name
    // Output :    location and angles
    //-----------------------------------------------------------------------------
    
StartPrepSDKCall(SDKCall_Entity);
    
PrepSDKCall_SetFromConf(hConfSDKConf_Signature"CBaseAnimating::GetAttachment");
    
PrepSDKCall_AddParameter(SDKType_StringSDKPass_Pointer);        //Attachment name
    
PrepSDKCall_AddParameter(SDKType_VectorSDKPass_ByRef_VENCODE_FLAG_COPYBACK); //absOrigin
    
PrepSDKCall_AddParameter(SDKType_QAngleSDKPass_ByRef_VENCODE_FLAG_COPYBACK); //absAngles
    
if((g_hGetAttachment EndPrepSDKCall()) == INVALID_HANDLESetFailState("Failed to create Call for CBaseAnimating::GetAttachment");
    
    
delete hConf;
    
    
RegAdminCmd("sm_sentry"Command_SentryADMFLAG_ROOT);
}

public 
void OnMapStart()
{
    
PrecacheSoundAny("sentrymp3/sentry_empty.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_finish.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_scan.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_scan2.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_scan3.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_shoot.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_shoot_mini.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_shoot2.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_shoot3.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_spot.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_spot_client.mp3");
    
PrecacheSoundAny("sentrymp3/sentry_rocket.mp3");
    
    
PrecacheEffect("ParticleEffect");
    
PrecacheParticleEffect("weapon_tracers_50cal");
    
PrecacheParticleEffect("weapon_muzzle_flash_awp");
    
PrecacheParticleEffect("impact_dirt");
    
PrecacheParticleEffect("blood_impact_heavy");
    
    
PrecacheModel("models/buildables/sentry1.mdl");
    
PrecacheModel("models/buildables/sentry2.mdl");
    
PrecacheModel("models/buildables/sentry3.mdl");
    
PrecacheModel("models/buildables/sentry3_rockets.mdl");
}

#define SENTRY_THINK_DELAY 0.05

#define SENTRYGUN_EYE_OFFSET_LEVEL_1    32.0
#define SENTRYGUN_EYE_OFFSET_LEVEL_2    40.0
#define SENTRYGUN_EYE_OFFSET_LEVEL_3    46.0

#define ANIM_LAYER_ACTIVE        0x0001
#define ANIM_LAYER_AUTOKILL        0x0002
#define ANIM_LAYER_KILLME        0x0004
#define ANIM_LAYER_DONTRESTORE    0x0008
#define ANIM_LAYER_CHECKACCESS    0x0010
#define ANIM_LAYER_DYING        0x0020

enum
{
    
SENTRY_STATE_INACTIVE 0,
    
SENTRY_STATE_SEARCHING,
    
SENTRY_STATE_ATTACKING,
    
SENTRY_STATE_UPGRADING,

    
SENTRY_NUM_STATES,
};

float m_flNextAttack;
float m_flNextRocketAttack;

// Rotation
int m_iRightBound;
int m_iLeftBound;

bool m_bTurningRight;

float m_vecCurAngles[3];
float m_vecGoalAngles[3];

float m_flTurnRate;

// Target player / object
int m_hEnemy INVALID_ENT_REFERENCE;

int m_iState SENTRY_STATE_INACTIVE;

int m_iAmmoRockets 99999999999;
int m_iAmmoShells 99999999999;
int m_iUpgradeLevel 1;

methodmap SentryGun
{
    public 
SentryGun(int ownerfloat vecPos[3], float vecAng[3], int iUpgradeLevel 1)
    {
        
int index = -1;
        while ((
index FindEntityByClassname(index"monster_generic")) != -1)
        {
            
AcceptEntityInput(index"Kill");
        }
    
        
int ent CreateEntityByName("monster_generic");
        
DispatchKeyValueVector(ent"origin"vecPos);
        
DispatchKeyValueVector(ent"angles"vecAng);
        
        if(
GetClientTeam(owner) == CS_TEAM_CT)
            
DispatchKeyValue(ent"skin""1");
        else
            
DispatchKeyValue(ent"skin""0");
        
        switch(
iUpgradeLevel)
        {
            case 
1DispatchKeyValue(ent"model""models/buildables/sentry1.mdl");
            case 
2DispatchKeyValue(ent"model""models/buildables/sentry2.mdl");
            case 
3DispatchKeyValue(ent"model""models/buildables/sentry3.mdl");
        }
        
        
DispatchSpawn(ent);
            
        
m_iUpgradeLevel iUpgradeLevel;
        
        
SetEntPropEnt(entProp_Send"m_hOwnerEntity"owner);
        
SetEntProp(entProp_Send"m_iTeamNum"GetClientTeam(owner));
        
        
// Orient it
        
float angles[3]; angles GetAbsAngles(ent);
    
        
m_vecCurAngles[1] = UTIL_AngleMod(angles[1]);
        
m_iRightBound RoundToNearest(UTIL_AngleMod(angles[1] - 50.0));
        
m_iLeftBound  RoundToNearest(UTIL_AngleMod(angles[1] + 50.0));
        
        if (
m_iRightBound m_iLeftBound)
        {
            
m_iRightBound m_iLeftBound;
            
m_iLeftBound RoundToNearest(UTIL_AngleMod(angles[1] - 50));
        }
        
        
// Start it rotating
        
m_vecGoalAngles[1] = float(m_iRightBound);
        
m_vecGoalAngles[0] = m_vecCurAngles[0] = 0.0;
        
m_bTurningRight true;        
        
        
m_iState SENTRY_STATE_SEARCHING;
        
m_hEnemy INVALID_ENT_REFERENCE;
        
        
SDKHook(entSDKHook_SetTransmitOnSentryThink);
        
        return 
view_as<SentryGun>(ent);
    }
    
    
property int index {
        public 
get() { 
            return 
view_as<int>(this); 
        }
    }
    public 
int GetOwner() {
        return 
GetEntPropEnt(this.indexProp_Send"m_hOwnerEntity");
    }
    public 
int GetTeam() {
        return 
GetEntProp(this.indexProp_Send"m_iTeamNum");
    }
    public 
Address GetStudioHdr() {
        return 
view_as<Address>(GetEntData(this.indexview_as<int>(0x49C)));
    }
    public 
Address CBaseAnimatingOverlay() {
        
int iOffset = (view_as<int>(GetEntityAddress(this.index)) + FindDataMapInfo(this.index"m_AnimOverlay"));
        return 
view_as<Address>(LoadFromAddress(view_as<Address>(iOffset), NumberType_Int32));
    }
    public 
void SetPoseParameter(int iParameterfloat flStartfloat flEndfloat flValue)    {
        
float ctlValue = (flValue flStart) / (flEnd flStart);
        if (
ctlValue 0ctlValue 0.0;
        if (
ctlValue 1ctlValue 1.0;
        
        
SetEntPropFloat(this.indexProp_Send"m_flPoseParameter"ctlValueiParameter);
    }
    public 
int LookupPoseParameter(const char[] szName)    {
        
Address pStudioHdr this.GetStudioHdr();
        if(
pStudioHdr == Address_Null)
            return -
1;
            
        return 
SDKCall(g_hLookupPoseParameterthis.indexpStudioHdrszName);
    }
    public 
void GetAttachment(const char[] szNamefloat absOrigin[3], float absAngles[3])    {
        
SDKCall(g_hGetAttachmentthis.indexszNameabsOriginabsAngles);
    }
    public 
int LookupSequence(const char[] anim) {
        return 
SDKCall(g_hLookupSequencethis.indexanim);
    }
    public 
int LookupActivity(const char[] anim) {
        return 
SDKCall(g_hLookupActivitythis.indexanim);
    }
    public 
void SetAnimation(const char[] anim)    {
        
int iSequence this.LookupSequence(anim);
        if(
iSequence 0)
            return;
            
        
SDKCall(g_hResetSequencethis.indexiSequence);
    }
    public 
int FindGestureLayer(const char[] anim) {
        
int iSequence this.LookupSequence(anim);
        if(
iSequence 0)
            return -
1;
        
        
Address overlay this.CBaseAnimatingOverlay();
        
    
//    PrintToServer("Overlay count = %i %i", GetEntData(this.index, 1212) );
        
        
for (int i 0GetEntData(this.index1212); i++)
        {
            
//Offset to a layers m_fFlags.
            
int fFlags LoadFromAddress(overlay view_as<Address>(m_fFlags i), NumberType_Int32);
            
            if (!(
fFlags ANIM_LAYER_ACTIVE))
                continue;
            
            if (
fFlags ANIM_LAYER_KILLME)
                continue;
            
            
int sequence LoadFromAddress(overlay view_as<Address>(m_nSequence i), NumberType_Int32);
            if(
sequence == iSequence)
                return 
i;
        }
        
        return -
1;
    }
    public 
void AddGesture(const char[] animbool bAutokill  true) {
        
int iSequence this.LookupSequence(anim);
        if(
iSequence 0)
            return;
        
        
//1212 = m_AnimOverlay.Count(), if this offset ever breaks; repalce it with 15 because it doesn't really matter. All you will be doing is accessing unallocated memory :o
        
int iCount GetEntData(this.index1212);
        
        
int iLayer SDKCall(g_hAddLayeredSequencethis.indexiSequence0);
        if(
iLayer >= && iLayer <= iCount && bAutokill)
        {
            
Address overlay this.CBaseAnimatingOverlay();
            
            
//Offset to a layers m_fFlags.
            
int iOffsetFlags    m_fFlags    iLayer;
            
int iOffsetSequence m_nSequence iLayer;
            
            
int fFlags LoadFromAddress(overlay view_as<Address>(iOffsetFlags), NumberType_Int32);
            
StoreToAddress(overlay view_as<Address>(iOffsetFlags), fFlags |= (ANIM_LAYER_AUTOKILL|ANIM_LAYER_KILLME), NumberType_Int32);
            
            
//Needed because valve is incompetent.
            
StoreToAddress(overlay view_as<Address>(iOffsetSequence), iSequenceNumberType_Int32);
        }
        
        
#if defined DEBUG
        
PrintToChatAll("AddGesture %s %i layer %i autokill %s"animiSequenceiLayerbAutokill "YES" "NO");
        
#endif
    
}
    public 
bool IsPlayingGesture(const char[] anim)    {
        return 
this.FindGestureLayer(anim) != -true false;
    }
    public 
void RemoveGesture(const char[] anim) {
        
int iLayer this.FindGestureLayer(anim);
        if (
iLayer == -1)
            return;
        
        
Address overlay this.CBaseAnimatingOverlay();
        
        
int iOffset m_fFlags iLayer;
        
int fFlags LoadFromAddress(overlay view_as<Address>(iOffset), NumberType_Int32);
        
        
StoreToAddress(overlay view_as<Address>(iOffset), fFlags |= (ANIM_LAYER_KILLME|ANIM_LAYER_AUTOKILL|ANIM_LAYER_DYING), NumberType_Int32);
        
        
#if defined DEBUG
        
PrintToChatAll("RemoveGesture %s layer %i"animiLayer);
        
#endif
    
}
    public 
int GetBaseTurnRate() { return 2; }
    
    public 
void AttachTrail(int entityfloat vecSrc[3], float vecAimDir[3], const char[] attachment)
    {
        
int index CreateEntityByName("env_rockettrail");
        
DispatchKeyValueVector(index"origin"vecSrc);
        
DispatchKeyValueVector(index"angles"vecAimDir);
        
SetEntPropFloat(indexProp_Send"m_Opacity"0.5);
        
SetEntPropFloat(indexProp_Send"m_SpawnRate"100.0);
        
SetEntPropFloat(indexProp_Send"m_ParticleLifetime"0.3);
        
SetEntPropVector(indexProp_Send"m_StartColor"view_as<float>({0.50.50.5}));
        
SetEntPropFloat(indexProp_Send"m_StartSize"3.0);
        
SetEntPropFloat(indexProp_Send"m_EndSize"15.0);
        
SetEntPropFloat(indexProp_Send"m_SpawnRadius"0.0);
        
SetEntPropFloat(indexProp_Send"m_MinSpeed"0.0);
        
SetEntPropFloat(indexProp_Send"m_MaxSpeed"100.0);
        
SetEntPropFloat(indexProp_Send"m_flFlareScale"1.0);
        
DispatchSpawn(index);
        
ActivateEntity(index);
        
        
SetVariantString("!activator");
        
AcceptEntityInput(index"SetParent"entity);
        
        
SetVariantString(attachment);
        
AcceptEntityInput(index"SetParentAttachment");
    }
    
    public 
void SentryRocketCreate(float vecSrc[3], float vecAimDir[3])
    {
        
//return; 
        
int rocket CreateEntityByName("monster_generic");
        
DispatchKeyValue(rocket"model""models/buildables/sentry3_rockets.mdl");
        
DispatchKeyValueVector(rocket"origin"vecSrc);
        
DispatchKeyValueVector(rocket"angles"vecAimDir);
        
DispatchSpawn(rocket);
        
        
SetEntityMoveType(rocketMOVETYPE_FLY);
        
        
SetEntPropEnt(rocketProp_Send"m_hOwnerEntity"this.GetOwner());

        
this.AttachTrail(rocketvecSrcvecAimDir"rocket1");
        
this.AttachTrail(rocketvecSrcvecAimDir"rocket2");
        
this.AttachTrail(rocketvecSrcvecAimDir"rocket3");
        
this.AttachTrail(rocketvecSrcvecAimDir"rocket4");
        
        
SetEntPropFloat(rocketProp_Data"m_flNextDodgeTime"GetGameTime());
        
        
SDKHook(rocketSDKHook_SetTransmitOnRocketThink);
        
SDKHook(rocketSDKHook_StartTouch,  OnRocketTouch);
        
//SDKHook(rocket, SDKHook_Touch,  OnRocketTouch);
    
}
    
    
//-----------------------------------------------------------------------------
    // Purpose: Validate target
    //-----------------------------------------------------------------------------
    
public bool ValidTargetPlayerint pPlayer, const float vecStart[3], const float vecEnd[3] )
    {
        
// Ray trace!!!
        
TR_TraceRayFilter(vecStartvecEnd, (MASK_SHOT|CONTENTS_GRATE), RayType_EndPointAimTargetFilterthis.index);
        if(!
TR_DidHit() || TR_GetEntityIndex() == pPlayer)
        {
            return 
true;
        }
        
        return 
false;
    }
    
    public 
void SelectTargetPoint(float vecSrc[3], float vecMidEnemy[3])
    {
        
vecMidEnemy WorldSpaceCenter(EntRefToEntIndex(m_hEnemy));
    
        
// If we cannot see their WorldSpaceCenter ( possible, as we do our target finding based
        // on the eye position of the target ) then fire at the eye position
        
TR_TraceRayFilter(vecSrcvecMidEnemyMASK_SOLIDRayType_EndPointAimTargetFilterthis.index);
        if(
TR_DidHit() && (TR_GetEntityIndex() >= MaxClients || TR_GetEntityIndex() <= 0))
        {
            
// Hack it lower a little bit..
            // The eye position is not always within the hitboxes for a standing CS Player
            
vecMidEnemy EyePosition(EntRefToEntIndex(m_hEnemy));
            
vecMidEnemy[2] -= 5.0;
        }
    }
    
    
//-----------------------------------------------------------------------------
    // Found a Target
    //-----------------------------------------------------------------------------
    
public void FoundTarget(int pTarget, const float vecSoundCenter[3] )
    {    
        
m_hEnemy EntIndexToEntRef(pTarget);
    
        if ((
m_iAmmoShells ) || (m_iAmmoRockets && m_iUpgradeLevel == ))
        {
        
/*    // Play one sound to everyone but the target.
            CPASFilter filter( vecSoundCenter );
    
            if (IsPlayer(pTarget))
            {
                CTFPlayer *pPlayer = ToTFPlayer( pTarget );
    
                // Play a specific sound just to the target and remove it from the genral recipient list.
                CSingleUserRecipientFilter singleFilter( pPlayer );
                EmitSound( singleFilter, entindex(), "Building_Sentrygun.AlertTarget" );
                filter.RemoveRecipient( pPlayer );
            }*/
            
            
EmitAmbientSoundAny("sentrymp3/sentry_spot.mp3"WorldSpaceCenter(this.index));
        }
    
        
// Update timers, we are attacking now!
        
m_iState SENTRY_STATE_ATTACKING;
        
m_flNextAttack GetGameTime() + SENTRY_THINK_DELAY;
        
        if (
m_flNextRocketAttack GetGameTime())
        {
            
m_flNextRocketAttack GetGameTime() + 0.5;
        }
    }
    
    
//-----------------------------------------------------------------------------
    // Look for a target
    //-----------------------------------------------------------------------------
    
public bool FindTarget()
    {
        
// Loop through players within 1100 units (sentry range).
        
float vecSentryOrigin[3]; vecSentryOrigin EyePosition(this.index);
    
        
// Find the opposing team.
        
int pTeam this.GetTeam();
    
        
int iEnemyTeam;
        
        if(
pTeam == CS_TEAM_T)
            
iEnemyTeam CS_TEAM_CT;
        else
            
iEnemyTeam CS_TEAM_T;
            
        
// If we have an enemy get his minimum distance to check against.
        
float vecSegment[3];
        
float vecTargetCenter[3];
        
        
float flMinDist2 1100.0 1100.0;
        
        
int pTargetCurrent INVALID_ENT_REFERENCE;
        
int pTargetOld EntRefToEntIndex(m_hEnemy);
        
        
float flOldTargetDist2 99999999999.0;
    
        
// Sentries will try to target players first, then objects.  However, if the enemy held was an object it will continue
        // to try and attack it first.
        
for (int iPlayer 1iPlayer <= MaxClientsiPlayer++)
        {    
            if(!
IsClientInGame(iPlayer))
                continue;
        
            
// Make sure the player is alive.
            
if (!IsPlayerAlive(iPlayer))
                continue;
        
            if (
GetEntityFlags(iPlayer) & FL_NOTARGET)
                continue;
                
            if(
GetClientTeam(iPlayer) != iEnemyTeam)
                continue;
            
            
vecTargetCenter GetAbsOrigin(iPlayer);
            
vecTargetCenter[2] += GetEntPropFloat(iPlayerProp_Send"m_vecViewOffset[2]");
            
            
SubtractVectors(vecTargetCentervecSentryOriginvecSegment);
            
            
float flDist2 GetVectorLength(vecSegmenttrue);

            
// Store the current target distance if we come across it
            
if (iPlayer == pTargetOld)
            {
                
flOldTargetDist2 flDist2;
            }
            
            
// Check to see if the target is closer than the already validated target.
            
if (flDist2 flMinDist2)
                continue;
            
            
// It is closer, check to see if the target is valid.
            
if (this.ValidTargetPlayer(iPlayervecSentryOriginvecTargetCenter))
            {
                
flMinDist2 flDist2;
                
pTargetCurrent iPlayer;
            }
        }
        
        
// If we already have a target, don't check objects.
        
if (pTargetCurrent == INVALID_ENT_REFERENCE)
        {
            
int iChicken MAXPLAYERS 1;
            while((
iChicken FindEntityByClassname(iChicken"chicken")) != -1)
            {
                
vecTargetCenter EyePosition(iChicken);
                
                
SubtractVectorsvecTargetCentervecSentryOriginvecSegment );
                
                
float flDist2 GetVectorLength(vecSegmenttrue);
    
                
// Store the current target distance if we come across it
                
if ( iChicken == pTargetOld )
                {
                    
flOldTargetDist2 flDist2;
                }
    
                
// Check to see if the target is closer than the already validated target.
                
if ( flDist2 flMinDist2 )
                    continue;
    
                
// It is closer, check to see if the target is valid.
                
if ( this.ValidTargetPlayeriChickenvecSentryOriginvecTargetCenter ) )
                {
                    
flMinDist2 flDist2;
                    
pTargetCurrent iChicken;
                }
            }
        }
    
        
// We have a target.
        
if (pTargetCurrent != INVALID_ENT_REFERENCE)
        {
            if (
pTargetCurrent != pTargetOld)
            {
                
// flMinDist2 is the new target's distance
                // flOldTargetDist2 is the old target's distance
                // Don't switch unless the new target is closer by some percentage
                
if (flMinDist2 < (flOldTargetDist2 0.75))
                {
                    
this.FoundTarget(pTargetCurrentvecSentryOrigin);
                }
            }
            
            return 
true;
        }
    
        return 
false;
    }
    
    public 
bool MoveTurret()
    {
        
bool bMoved false;
        
        
int iBaseTurnRate this.GetBaseTurnRate();
        
        
// any x movement?
        
if (m_vecCurAngles[0] != m_vecGoalAngles[0])
        {
            
float flDir m_vecGoalAngles[0] > m_vecCurAngles[0] ? 1.0 : -1.0 ;
    
            
m_vecCurAngles[0] += SENTRY_THINK_DELAY * (iBaseTurnRate 5) * flDir;
    
            
// if we started below the goal, and now we're past, peg to goal
            
if (flDir == 1)
            {
                if (
m_vecCurAngles[0] > m_vecGoalAngles[0])
                    
m_vecCurAngles[0] = m_vecGoalAngles[0];
            } 
            else
            {
                if (
m_vecCurAngles[0] < m_vecGoalAngles[0])
                    
m_vecCurAngles[0] = m_vecGoalAngles[0];
            }
    
            
this.SetPoseParameter(this.LookupPoseParameter("aim_pitch"), -50.050.0, -m_vecCurAngles[0]);
            
            
bMoved true;
        }
        
        if (
m_vecCurAngles[1] != m_vecGoalAngles[1])
        {
            
float flDir m_vecGoalAngles[1] > m_vecCurAngles[1] ? 1.0 : -1.0 ;
            
float flDist FloatAbs(m_vecGoalAngles[1] - m_vecCurAngles[1]);
            
bool bReversed false;
    
            if (
flDist 180)
            {
                
flDist 360 flDist;
                
flDir = -flDir;
                
bReversed true;
            }
    
            if (
m_hEnemy == INVALID_ENT_REFERENCE)
            {
                if (
flDist 30)
                {
                    if (
m_flTurnRate iBaseTurnRate 10)
                    {
                        
m_flTurnRate += iBaseTurnRate;
                    }
                }
                else
                {
                    
// Slow down
                    
if (m_flTurnRate > (iBaseTurnRate 5))
                        
m_flTurnRate -= iBaseTurnRate;
                }
            }
            else
            {
                
// When tracking enemies, move faster and don't slow
                
if (flDist 30)
                {
                    if (
m_flTurnRate iBaseTurnRate 30)
                    {
                        
m_flTurnRate += iBaseTurnRate 3;
                    }
                }
            }
    
            
m_vecCurAngles[1] += SENTRY_THINK_DELAY m_flTurnRate flDir;
    
            
// if we passed over the goal, peg right to it now
            
if (flDir == -1)
            {
                if ((
bReversed == false && m_vecGoalAngles[1] > m_vecCurAngles[1]) ||
                    (
bReversed == true  && m_vecGoalAngles[1] < m_vecCurAngles[1]))
                {
                    
m_vecCurAngles[1] = m_vecGoalAngles[1];
                }
            } 
            else
            {
                if ((
bReversed == false && m_vecGoalAngles[1] < m_vecCurAngles[1]) ||
                    (
bReversed == true  && m_vecGoalAngles[1] > m_vecCurAngles[1]))
                {
                    
m_vecCurAngles[1] = m_vecGoalAngles[1];
                }
            }
    
            if (
m_vecCurAngles[1] < 0)
            {
                
m_vecCurAngles[1] += 360;
            }
            else if (
m_vecCurAngles[1] >= 360)
            {
                
m_vecCurAngles[1] -= 360;
            }
    
            if (
flDist < (SENTRY_THINK_DELAY 0.5 iBaseTurnRate))
            {
                
m_vecCurAngles[1] = m_vecGoalAngles[1];
            }
    
            
float angles[3]; angles GetAbsAngles(this.index);
            
            
float flYaw AngleNormalize(m_vecCurAngles[1] - angles[1]);
            
            
this.SetPoseParameter(this.LookupPoseParameter("aim_yaw"), -180.0180.0, -flYaw);
    
            
bMoved true;
        }
    
        if (!
bMoved || m_flTurnRate <= 0)
        {
            
m_flTurnRate float(iBaseTurnRate 5);
        }
    
        return 
bMoved;
    }
    
    
//-----------------------------------------------------------------------------
    // Rotate and scan for targets
    //-----------------------------------------------------------------------------
    
public void SentryRotate()
    {
        
// if we're playing a fire gesture, stop it
        
if (this.IsPlayingGesture("ACT_RANGE_ATTACK1"))
        {
            
this.RemoveGesture("ACT_RANGE_ATTACK1");
        }
    
        if (
this.IsPlayingGesture("ACT_RANGE_ATTACK1_LOW"))
        {
            
this.RemoveGesture("ACT_RANGE_ATTACK1_LOW");
        }
    
        
// Look for a target
        
if (this.FindTarget())
        {
            return;
        }
    
        
// Rotate
        
if (!this.MoveTurret())
        {
            
// Change direction
    
            
switch(m_iUpgradeLevel)
            {
                case 
1EmitAmbientSoundAny("sentrymp3/sentry_scan.mp3"WorldSpaceCenter(this.index));
                case 
2EmitAmbientSoundAny("sentrymp3/sentry_scan2.mp3"WorldSpaceCenter(this.index));
                case 
3EmitAmbientSoundAny("sentrymp3/sentry_scan3.mp3"WorldSpaceCenter(this.index));
            }
    
            
// Switch rotation direction
            
if (m_bTurningRight)
            {
                
m_bTurningRight false;
                
m_vecGoalAngles[1] = float(m_iLeftBound);
            }
            else
            {
                
m_bTurningRight true;
                
m_vecGoalAngles[1] = float(m_iRightBound);
            }

            
// Randomly look up and down a bit
            
if (GetRandomFloat(0.01.0) < 0.3)
            {
                
m_vecGoalAngles[0] = float(RoundToNearest(GetRandomFloat(-10.010.0)));
            }
        }
    }
    
    
//-----------------------------------------------------------------------------
    // Fire on our target
    //-----------------------------------------------------------------------------
    
public bool Fire()
    {
        
//NDebugOverlay::Cross3D( m_hEnemy->WorldSpaceCenter(), 10, 255, 0, 0, false, 0.1 );
    
        
float vecAimDir[3];
    
        
// Level 3 Turrets fire rockets every 3 seconds
        
if ( m_iUpgradeLevel == && m_iAmmoRockets && m_flNextRocketAttack GetGameTime())
        {
            
float vecSrc[3];
            
float vecAng[3];
    
            
// alternate between the 2 rocket launcher ports.
            
if ( m_iAmmoRockets ) {
                
this.GetAttachment"rocket_l"vecSrcvecAng );
            } else {
                
this.GetAttachment"rocket_r"vecSrcvecAng );
            }
    
            
SubtractVectors(WorldSpaceCenter(EntRefToEntIndex(m_hEnemy)), vecSrcvecAimDir);
            
NormalizeVector(vecAimDirvecAimDir);
    
            
// NOTE: vecAng is not actually set by GetAttachment!!!
            
float angDir[3];
            
GetVectorAnglesvecAimDirangDir );
    
            
EmitAmbientSoundAny("sentrymp3/sentry_rocket.mp3"WorldSpaceCenter(this.index));
            
            
this.AddGesture("ACT_RANGE_ATTACK2");
        
            
float angAimDir[3];
            
GetVectorAnglesvecAimDirangAimDir );
            
            
this.SentryRocketCreate(vecSrcangAimDir);
    
            
// Setup next rocket shot
            
m_flNextRocketAttack GetGameTime() + 3;
    
            
m_iAmmoRockets--;
        }
    
        
// All turrets fire shells
        
if ( m_iAmmoShells 0)
        {
            if (!
this.IsPlayingGesture("ACT_RANGE_ATTACK1"))
            {
                
this.RemoveGesture("ACT_RANGE_ATTACK1_LOW");
                
this.AddGesture("ACT_RANGE_ATTACK1");
            }
    
            
float vecSrc[3];
            
float vecAng[3];
    
            if ( 
m_iUpgradeLevel )
            {
                
// level 2 and 3 turrets alternate muzzles each time they fizzy fizzy fire.
                
if(m_iAmmoShells 1)
                {
                    
this.GetAttachment"muzzle_l"vecSrcvecAng );
                }
                else
                {
                    switch( 
m_iUpgradeLevel )
                    {
                        case 
1:    EmitAmbientSoundAny("sentrymp3/sentry_shoot.mp3"WorldSpaceCenter(this.index));
                        case 
2EmitAmbientSoundAny("sentrymp3/sentry_shoot2.mp3"WorldSpaceCenter(this.index));
                        case 
3EmitAmbientSoundAny("sentrymp3/sentry_shoot3.mp3"WorldSpaceCenter(this.index));
                    }
    
                    
this.GetAttachment"muzzle_r"vecSrcvecAng );                    
                }
            }
            else
            {
                switch( 
m_iUpgradeLevel )
                {
                    case 
1:    EmitAmbientSoundAny("sentrymp3/sentry_shoot.mp3"WorldSpaceCenter(this.index));
                    case 
2EmitAmbientSoundAny("sentrymp3/sentry_shoot2.mp3"WorldSpaceCenter(this.index));
                    case 
3EmitAmbientSoundAny("sentrymp3/sentry_shoot3.mp3"WorldSpaceCenter(this.index));
                }
            
                
this.GetAttachment"muzzle"vecSrcvecAng );
            }
    
            
float vecMidEnemy[3]; 
            
this.SelectTargetPoint(vecSrcvecMidEnemy); // WorldSpaceCenter(EntRefToEntIndex(m_hEnemy));
    
            
SubtractVectors(vecMidEnemyvecSrcvecAimDir);
            
float flDistToTarget GetVectorLength(vecAimDir);
            
NormalizeVector(vecAimDirvecAimDir);
            
            
//CS:GO Away
            //PrecacheParticleEffect("weapon_tracers_50cal");
            
FireBullet(this.indexthis.GetOwner(), vecSrcvecAimDir16.0flDistToTarget 500DMG_BULLET"weapon_tracers_50cal");
            
            
// Muzzle flash
            
TE_DispatchEffect("weapon_muzzle_flash_awp"vecSrcvecSrcvecAng);
            
TE_SendToAll();
            
            
m_iAmmoShells--;
        }
        else
        {
            if (
m_iUpgradeLevel 1)
            {
                if (!
this.IsPlayingGesture("ACT_RANGE_ATTACK1_LOW"))
                {
                    
this.RemoveGesture("ACT_RANGE_ATTACK1");
                    
this.AddGesture("ACT_RANGE_ATTACK1_LOW");
                }
            }
    
            
// Out of ammo, play a click
            
EmitAmbientSoundAny("sentrymp3/sentry_empty.mp3"WorldSpaceCenter(this.index));
            
m_flNextAttack GetGameTime() + 0.2;
        }
    
        return 
true;
    }

    
//-----------------------------------------------------------------------------
    // Make sure our target is still valid, and if so, fire at it
    //-----------------------------------------------------------------------------
    
public void Attack()
    {
        if (!
this.FindTarget())
        {
            
#if defined DEBUG
            
PrintToServer("Attack() No target");
            
#endif
            
m_iState SENTRY_STATE_SEARCHING;
            
m_hEnemy INVALID_ENT_REFERENCE;
            return;
        }
    
        
// Track enemy
        
float vecMid[3];      vecMid      WorldSpaceCenter(this.index);
        
float vecMidEnemy[3];
        
this.SelectTargetPoint(vecMidvecMidEnemy); //WorldSpaceCenter(EntRefToEntIndex(m_hEnemy));
        
        
float vecDirToEnemy[3];
        
SubtractVectors(vecMidEnemyvecMidvecDirToEnemy);
    
        
float angToTarget[3];
        
GetVectorAngles(vecDirToEnemyangToTarget);
    
        
angToTarget[1] = UTIL_AngleMod(angToTarget[1]);
        if (
angToTarget[0] < -180)
            
angToTarget[0] += 360;
        if (
angToTarget[0] > 180)
            
angToTarget[0] -= 360;
    
        
// now all numbers should be in [1...360]
        // pin to turret limitations to [-50...50]
        
if (angToTarget[0] > 50)
            
angToTarget[0] = 50.0;
        else if (
angToTarget[0] < -50)
            
angToTarget[0] = -50.0;
            
        
m_vecGoalAngles[1] = angToTarget[1];
        
m_vecGoalAngles[0] = angToTarget[0];
    
        
this.MoveTurret();
        
        
float subtracted[3];
        
SubtractVectors(m_vecGoalAnglesm_vecCurAnglessubtracted);
        
        
// Fire on the target if it's within 10 units of being aimed right at it
        
if ( m_flNextAttack <= GetGameTime() && GetVectorLength(subtracted) <= 10 )
        {
            
this.Fire();
        
            if ( 
m_iUpgradeLevel == )
            {
                
// Level 1 sentries fire slower
                
m_flNextAttack GetGameTime() + 0.2;
            }
            else
            {
                
m_flNextAttack GetGameTime() + 0.1;
            }
        }
        
        if(
GetVectorLength(subtracted) > 10)
        {
            
// if we're playing a fire gesture, stop it
            
if (this.IsPlayingGesture("ACT_RANGE_ATTACK1"))
            {
                
this.RemoveGesture("ACT_RANGE_ATTACK1");
            }
        }
    }
}

public 
Action Command_Sentry(int clientint argc)
{
    if(
client <= || client MaxClients && !IsClientInGame(client))
        return 
Plugin_Handled;
        
    
SentryGun(clientGetAbsOrigin(client), GetAbsAngles(client), GetRandomInt(13));
    
    return 
Plugin_Handled;
}

public 
void OnSentryThink(int entityint client)
{
    static 
int iThinkWhenClient 1;
    
    
//This bad code ensures that we don't think any more than we should
    
if(!IsClientInGame(iThinkWhenClient)) {
        
iThinkWhenClient client;
    }
    
    if(
iThinkWhenClient != client) {
        return;
    }
    
    
// animate
    
SDKCall(g_hStudioFrameAdvanceentity);
    
    
SentryGun sentry view_as<SentryGun>(entity);
    
    switch( 
m_iState )
    {
        case 
SENTRY_STATE_SEARCHINGsentry.SentryRotate();
        case 
SENTRY_STATE_ATTACKINGsentry.Attack();
        
//case SENTRY_STATE_UPGRADING: sentry.UpgradeThink();
    
}
}

//TODO
// Trace between position before setting new origin and new origin to not miss anything
public void OnRocketThink(int entityint client)
{
    static 
int iThinkWhenClient 1;
    
    
//This bad code ensures that we don't think any more than we should
    
if(!IsClientInGame(iThinkWhenClient)) {
        
iThinkWhenClient client;
    }
    
    if(
iThinkWhenClient != client) {
        return;
    }

    
float ang[3]; ang GetAbsAngles(entity);
    
float pos[3]; pos GetAbsOrigin(entity);
    
    
float vForward[3];
    
GetAngleVectors(angvForwardNULL_VECTORNULL_VECTOR);
    
    
pos[0] += vForward[0] * 5.0;
    
pos[1] += vForward[1] * 5.0;
    
pos[2] += vForward[2] * 5.0;
    
    
SDKCall(g_hStudioFrameAdvanceentity);
    
    
DispatchKeyValueVector(entity"origin"pos);
}

//Mine now TriHard https://github.com/Rachnus/Small-SourceMod-Plugins/blob/master/explodedroppedgrenades.sp#L63
void CS_CreateExplosion(int clientint damageint radiusfloat pos[3])
{
    
int entity;
    if((
entity CreateEntityByName("env_explosion")) != -1)
    {
        
//DispatchKeyValue(entity, "spawnflags", "552");
        
DispatchKeyValue(entity"rendermode""5");
        
SetEntProp(entityProp_Data"m_iMagnitude"damage);
        
SetEntProp(entityProp_Data"m_iRadiusOverride"radius);
        
SetEntProp(entityProp_Data"m_iTeamNum"GetClientTeam(client));
        
SetEntPropEnt(entityProp_Data"m_hOwnerEntity"client);

        
DispatchSpawn(entity);
        
TeleportEntity(entityposNULL_VECTORNULL_VECTOR);
        
EmitAmbientSound("weapons/hegrenade/explode4.wav"posentity);
        
RequestFrame(TriggerExplosionentity);
    }
}

public 
void TriggerExplosion(int entity)
{
    
AcceptEntityInput(entity"explode");
    
AcceptEntityInput(entity"Kill");
}

public 
void OnRocketTouch(int entityint other)
{    
    
char class[64]; GetEntityClassname(other, class, sizeof(class));
    
    
float flSpawnTime GetGameTime() - GetEntPropFloat(entityProp_Data"m_flNextDodgeTime");
    if( 
flSpawnTime 0.05 && !StrEqual(class, "player"))
        return;
    
    
float pos[3]; pos GetAbsOrigin(entity);
    
CS_CreateExplosion(view_as<SentryGun>(entity).GetOwner(), 100150pos);
    
    
#if defined DEBUG
    
PrintToChatAll("Rocket touch %s %i", class, other);
    
#endif
    
    
AcceptEntityInput(entity"Kill");
}

stock float[] GetAbsOrigin(int client)
{
    
float v[3];
    
GetEntPropVector(clientProp_Data"m_vecAbsOrigin"v);
    return 
v;
}

stock float[] EyePosition(int ent)
{
    
float v[3]; GetAbsOrigin(ent);
    
    if (
HasEntProp(entProp_Send"m_vDefaultEyeOffset"))
    {
        switch(
m_iUpgradeLevel)
        {
            case 
1v[2] += SENTRYGUN_EYE_OFFSET_LEVEL_1;
            case 
2v[2] += SENTRYGUN_EYE_OFFSET_LEVEL_2;
            case 
3v[2] += SENTRYGUN_EYE_OFFSET_LEVEL_3;
        }
    }
    else
    {
        
float max[3];
        
GetEntPropVector(entProp_Data"m_vecMaxs"max);
        
v[2] += max[2];
    }

    return 
v;
}

stock float[] WorldSpaceCenter(int ent)
{
    
float v[3]; GetAbsOrigin(ent);
    
    
float max[3];
    
GetEntPropVector(entProp_Data"m_vecMaxs"max);
    
v[2] += max[2] / 2;
    
    return 
v;
}

stock float[] GetAbsAngles(int client)
{
    
float v[3];
    
GetEntPropVector(clientProp_Data"m_angAbsRotation"v);
    
    return 
v;
}

stock float[] GetEyeAngles(int client)
{
    
float v[3];
    
GetClientEyeAngles(clientv);
    return 
v;
}

public 
float UTIL_AngleMod(float a)
{
    
= (360.0 65536) * (RoundToNearest(* (65536.0 360.0)) & 65535);
    return 
a;
}

stock float AngleNormalize(float angle)
{
    
angle fmodf(angle360.0);
    if (
angle 180
    {
        
angle -= 360;
    }
    if (
angle < -180)
    {
        
angle += 360;
    }
    return 
angle;
}

stock float fmodf(float numfloat denom)
{
    return 
num denom RoundToFloor(num denom);
}

stock float operator%(float oper1float oper2)
{
    return 
fmodf(oper1oper2);
}

public 
bool AimTargetFilter(int entityint contentsMaskany iExclude)
{
    
char class[64];
    
GetEntityClassname(entity, class, sizeof(class));
    
    if(
StrEqual(class, "monster_generic"))
    {
        return 
false;
    }

    return !(
entity == iExclude);
}

stock void FireBullet(int m_pAttackerint m_pDamagerfloat m_vecSrc[3], float m_vecDirShooting[3], float m_flDamagefloat m_flDistanceint nDamageType, const char[] tracerEffect)
{
    
float vecEnd[3];
    
vecEnd[0] = m_vecSrc[0] + m_vecDirShooting[0] * m_flDistance
    
vecEnd[1] = m_vecSrc[1] + m_vecDirShooting[1] * m_flDistance;
    
vecEnd[2] = m_vecSrc[2] + m_vecDirShooting[2] * m_flDistance;
    
    
// Fire a bullet (ignoring the shooter).
    
Handle trace TR_TraceRayFilterEx(m_vecSrcvecEnd, ( MASK_SOLID CONTENTS_HITBOX ), RayType_EndPointAimTargetFilterm_pAttacker);

    if ( 
TR_GetFraction(trace) < 1.0 )
    {
        
// Verify we have an entity at the point of impact.
        
if(TR_GetEntityIndex(trace) == -1)
        {
            
delete trace;
            return;
        }
        
        
float endpos[3]; TR_GetEndPosition(endpostrace);
        
SDKHooks_TakeDamage(TR_GetEntityIndex(trace), m_pAttackerm_pDamagerm_flDamagenDamageTypem_pAttackerCalculateBulletDamageForce(m_vecDirShooting1.0), endpos);
        
        
// Sentryguns are perfectly accurate, but this doesn't look good for tracers.
        // Add a little noise to them, but not enough so that it looks like they're missing.
        
endpos[0] += GetRandomFloat(-10.010.0);
        
endpos[1] += GetRandomFloat(-10.010.0);
        
endpos[2] += GetRandomFloat(-10.010.0);
        
        
// Bullet tracer
        
TE_DispatchEffect(tracerEffectendposm_vecSrcNULL_VECTOR);
        
TE_SendToAll();
        
        
float vecNormal[3];    TR_GetPlaneNormal(tracevecNormal);
        
GetVectorAngles(vecNormalvecNormal);
        
        if(
TR_GetEntityIndex(trace) <= || TR_GetEntityIndex(trace) > MaxClients)
        {
            
//Can't get surface properties from traces unfortunately.
            //Just another shortsighting from the SM devs :///
            
TE_DispatchEffect("impact_dirt"endposendposvecNormal);
            
TE_SendToAll();
            
            
TE_Start("Impact");
            
TE_WriteVector("m_vecOrigin"endpos);
            
TE_WriteVector("m_vecNormal"vecNormal);
            
TE_WriteNum("m_iType"GetRandomInt(110));
            
TE_SendToAll();
        }
        else if(
TR_GetEntityIndex(trace) > && TR_GetEntityIndex(trace) <= MaxClients)
        {
            
TE_DispatchEffect("blood_impact_heavy"endposendposvecNormal);
            
TE_SendToAll();
        }
    }
    
    
delete trace;
}

float[] CalculateBulletDamageForce( const float vecBulletDir[3], float flScale )
{
    
float vecForce[3]; vecForce vecBulletDir;
    
NormalizeVectorvecForcevecForce );
    
ScaleVector(vecForceFindConVar("phys_pushscale").FloatValue);
    
ScaleVector(vecForceflScale);
    return 
vecForce;
}

stock bool IsPlayer(int entity)
{
    return (
entity && entity <= MaxClients);
}

//Thanks Chaosxk
//https://github.com/xcalvinsz/zeustracerbullets/blob/master/addons/sourcemod/scripting/zeustracers.sp
void TE_DispatchEffect(const char[] particle, const float pos[3], const float endpos[3], const float angles[3] = NULL_VECTORint attachment = -1)
{
    
TE_Start("EffectDispatch");
    
TE_WriteFloat("m_vStart.x"pos[0]);
    
TE_WriteFloat("m_vStart.y"pos[1]);
    
TE_WriteFloat("m_vStart.z"pos[2]);
    
TE_WriteFloat("m_vOrigin.x"endpos[0]);
    
TE_WriteFloat("m_vOrigin.y"endpos[1]);
    
TE_WriteFloat("m_vOrigin.z"endpos[2]);
    
TE_WriteVector("m_vAngles"angles);
    
TE_WriteNum("m_nHitBox"GetParticleEffectIndex(particle));
    
TE_WriteNum("m_iEffectName"GetEffectIndex("ParticleEffect"));
    
    if(
attachment != -1)
    {
        
TE_WriteNum("m_nAttachmentIndex"attachment);
    }
}

void PrecacheParticleEffect(const char[] sEffectName)
{
    static 
int table INVALID_STRING_TABLE;
    
    if (
table == INVALID_STRING_TABLE)
        
table FindStringTable("ParticleEffectNames");
        
    
bool save LockStringTables(false);
    
AddToStringTable(tablesEffectName);
    
LockStringTables(save);
}

int GetParticleEffectIndex(const char[] sEffectName)
{
    static 
int table INVALID_STRING_TABLE;

    if (
table == INVALID_STRING_TABLE)
        
table FindStringTable("ParticleEffectNames");

    
int iIndex FindStringIndex(tablesEffectName);

    if (
iIndex != INVALID_STRING_INDEX)
        return 
iIndex;

    return 
0;
}

void PrecacheEffect(const char[] sEffectName)
{
    static 
int table INVALID_STRING_TABLE;
    
    if (
table == INVALID_STRING_TABLE)
        
table FindStringTable("EffectDispatch");
        
    
bool save LockStringTables(false);
    
AddToStringTable(tablesEffectName);
    
LockStringTables(save);
}

int GetEffectIndex(const char[] sEffectName)
{
    static 
int table INVALID_STRING_TABLE;

    if (
table == INVALID_STRING_TABLE)
        
table FindStringTable("EffectDispatch");

    
int iIndex FindStringIndex(tablesEffectName);

    if (
iIndex != INVALID_STRING_INDEX)
        return 
iIndex;

    return 
0;

Sort of a demo video




Windows only
__________________

Last edited by Pelipoika; 03-20-2018 at 10:53.
Pelipoika is offline
Mitchell
~lick~
Join Date: Mar 2010
Old 03-16-2018 , 16:44   Re: [CSGO] Unfinished TF2 sentry
Reply With Quote #2

It looks pretty much done... what exactly needs to be finished?
__________________
Mitchell is offline
Pelipoika
Veteran Member
Join Date: May 2012
Location: Inside
Old 03-16-2018 , 16:49   Re: [CSGO] Unfinished TF2 sentry
Reply With Quote #3

Quote:
Originally Posted by Mitchell View Post
It looks pretty much done... what exactly needs to be finished?
Can't destroy / damage it, can't upgrade it, can't collide with it, rockets are badly and hastly pasted together and rocket launcher thingy on top spazzes out more than im okay with during it's animation.

and sometimes the bullets tracers aren't drawn until you fire your gun as seen in the video
__________________

Last edited by Pelipoika; 03-16-2018 at 16:50.
Pelipoika is offline
8guawong
AlliedModders Donor
Join Date: Dec 2013
Location: BlackMarke7
Old 03-16-2018 , 16:53   Re: [CSGO] Unfinished TF2 sentry
Reply With Quote #4

Neat
__________________
8guawong is offline
senecas
Senior Member
Join Date: Jun 2006
Old 04-10-2018 , 22:17   Re: [CSGO] Unfinished TF2 sentry
Reply With Quote #5

good job & cheer up~~
senecas is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 19:00.


Powered by vBulletin®
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Theme made by Freecode