Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "autowall.h"
- #include "..\..\csgo sdk\IPhysics.h"
- #include "..\..\csgo sdk\ClientClass.h"
- #include "..\..\csgo sdk\ICvar.h"
- #include "..\..\Settings.h"
- typedef CGameTrace trace_t;
- inline bool CGameTrace::DidHitWorld() const
- {
- return hit_entity->EntIndex() == 0;
- }
- inline bool CGameTrace::DidHitNonWorldEntity() const
- {
- return hit_entity != NULL && !DidHitWorld();
- }
- c_autowall* autowall;
- #define DAMAGE_NO 0
- #define DAMAGE_EVENTS_ONLY 1
- #define DAMAGE_YES 2
- #define DAMAGE_AIM 3
- #define CHAR_TEX_ANTLION 'A'
- #define CHAR_TEX_BLOODYFLESH 'B'
- #define CHAR_TEX_CONCRETE 'C'
- #define CHAR_TEX_DIRT 'D'
- #define CHAR_TEX_EGGSHELL 'E' ///< the egg sacs in the tunnels in ep2.
- #define CHAR_TEX_FLESH 'F'
- #define CHAR_TEX_GRATE 'G'
- #define CHAR_TEX_ALIENFLESH 'H'
- #define CHAR_TEX_CLIP 'I'
- #define CHAR_TEX_PLASTIC 'L'
- #define CHAR_TEX_METAL 'M'
- #define CHAR_TEX_SAND 'N'
- #define CHAR_TEX_FOLIAGE 'O'
- #define CHAR_TEX_COMPUTER 'P'
- #define CHAR_TEX_SLOSH 'S'
- #define CHAR_TEX_TILE 'T'
- #define CHAR_TEX_CARDBOARD 'U'
- #define CHAR_TEX_VENT 'V'
- #define CHAR_TEX_WOOD 'W'
- #define CHAR_TEX_GLASS 'Y'
- #define CHAR_TEX_WARPSHIELD 'Z' ///< weird-looking jello effect for advisor shield.
- void ScaleDamage_1(int hitgroup, C_BaseEntity* enemy, float weapon_armor_ratio, float& current_damage)
- {
- int armor = enemy->GetArmor();
- float ratio;
- switch (hitgroup)
- {
- case HITGROUP_HEAD:
- current_damage *= 4.f;
- break;
- case HITGROUP_STOMACH:
- current_damage *= 1.25f;
- break;
- case HITGROUP_LEFTLEG:
- case HITGROUP_RIGHTLEG:
- current_damage *= 0.75f;
- break;
- }
- if (armor > 0)
- {
- switch (hitgroup)
- {
- case HITGROUP_HEAD:
- if (enemy->HasHelmet())
- {
- ratio = (weapon_armor_ratio * 0.5) * current_damage;
- if (((current_damage - ratio) * 0.5) > armor)
- ratio = current_damage - (armor * 2.0);
- current_damage = ratio;
- }
- break;
- case HITGROUP_GENERIC:
- case HITGROUP_CHEST:
- case HITGROUP_STOMACH:
- case HITGROUP_LEFTARM:
- case HITGROUP_RIGHTARM:
- ratio = (weapon_armor_ratio * 0.5) * current_damage;
- if (((current_damage - ratio) * 0.5) > armor)
- ratio = current_damage - (armor * 2.0);
- current_damage = ratio;
- break;
- }
- }
- }
- void c_autowall::TraceLine(Vector& absStart, Vector& absEnd, unsigned int mask, IClientEntity* ignore, CGameTrace* ptr)
- {
- Ray_t ray;
- ray.Init(absStart, absEnd);
- CTraceFilter filter;
- filter.pSkip = ignore;
- g_pEngineTrace->TraceRay(ray, mask, &filter, ptr);
- }
- void c_autowall::ClipTraceToPlayers(const Vector& absStart, const Vector absEnd, unsigned int mask, ITraceFilter* filter, CGameTrace* tr)
- {
- C_BaseEntity *pLocal = g_pEntityList->GetClientEntity(g_pEngine->GetLocalPlayer());
- C_BaseCombatWeapon* weapon = (C_BaseCombatWeapon*)pLocal->GetActiveWeapon();
- static DWORD dwAddress = Utils::FindSignature("client_panorama.dll", "53 8B DC 83 EC 08 83 E4 F0 83 C4 04 55 8B 6B 04 89 6C 24 04 8B EC 81 EC ? ? ? ? 8B 43 10");
- if (!dwAddress)
- return;
- _asm
- {
- MOV EAX, filter
- LEA ECX, tr
- PUSH ECX
- PUSH EAX
- PUSH mask
- LEA EDX, absEnd
- LEA ECX, absStart
- CALL dwAddress
- ADD ESP, 0xC
- }
- }
- ////////////////////////////////////// Legacy Functions //////////////////////////////////////
- void c_autowall::GetBulletTypeParameters(float& maxRange, float& maxDistance, char* bulletType, bool sv_penetration_type)
- {
- if (sv_penetration_type)
- {
- maxRange = 35.0;
- maxDistance = 3000.0;
- }
- else
- {
- //Play tribune to framerate. Thanks, stringcompare
- //Regardless I doubt anyone will use the old penetration system anyway; so it won't matter much.
- if (!strcmp(bulletType, ("BULLET_PLAYER_338MAG")))
- {
- maxRange = 45.0;
- maxDistance = 8000.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_762MM")))
- {
- maxRange = 39.0;
- maxDistance = 5000.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_556MM")) || !strcmp(bulletType, ("BULLET_PLAYER_556MM_SMALL")) || !strcmp(bulletType, ("BULLET_PLAYER_556MM_BOX")))
- {
- maxRange = 35.0;
- maxDistance = 4000.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_57MM")))
- {
- maxRange = 30.0;
- maxDistance = 2000.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_50AE")))
- {
- maxRange = 30.0;
- maxDistance = 1000.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_357SIG")) || !strcmp(bulletType, ("BULLET_PLAYER_357SIG_SMALL")) || !strcmp(bulletType, ("BULLET_PLAYER_357SIG_P250")) || !strcmp(bulletType, ("BULLET_PLAYER_357SIG_MIN")))
- {
- maxRange = 25.0;
- maxDistance = 800.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_9MM")))
- {
- maxRange = 21.0;
- maxDistance = 800.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_45ACP")))
- {
- maxRange = 15.0;
- maxDistance = 500.0;
- }
- if (!strcmp(bulletType, ("BULLET_PLAYER_BUCKSHOT")))
- {
- maxRange = 0.0;
- maxDistance = 0.0;
- }
- }
- }
- ////////////////////////////////////// Misc Functions //////////////////////////////////////
- bool c_autowall::BreakableEntity(IClientEntity* entity)
- {
- ClientClass* pClass = (ClientClass*)entity->GetClientClass();
- if (!pClass)
- return false;
- if (pClass == nullptr)
- return false;
- return pClass->ClassID == EClassIds::CBreakableProp || pClass->ClassID == EClassIds::CBreakableSurface;
- }
- void c_autowall::ScaleDamage(CGameTrace &enterTrace, WeaponInfo_t *weaponData, float& currentDamage)
- {
- C_BaseEntity *pLocal = g_pEntityList->GetClientEntity(g_pEngine->GetLocalPlayer());
- C_BaseCombatWeapon* weapon = (C_BaseCombatWeapon*)pLocal->GetActiveWeapon();
- bool hasHeavyArmor = false;
- int armorValue = ((C_BaseEntity*)enterTrace.hit_entity)->GetArmor();
- int hitGroup = enterTrace.hitgroup;
- if (!pLocal)
- return;
- auto IsArmored = [&enterTrace]()->bool
- {
- C_BaseEntity* targetEntity = (C_BaseEntity*)enterTrace.hit_entity;
- switch (enterTrace.hitgroup)
- {
- case HITGROUP_HEAD:
- return !!(C_BaseEntity*)targetEntity->HasHelmet();
- case HITGROUP_GENERIC:
- case HITGROUP_CHEST:
- case HITGROUP_STOMACH:
- case HITGROUP_LEFTARM:
- case HITGROUP_RIGHTARM:
- return true;
- default:
- return false;
- }
- };
- switch (hitGroup)
- {
- case HITGROUP_HEAD:
- currentDamage *= 2.f;
- break;
- case HITGROUP_STOMACH:
- currentDamage *= 1.25f;
- break;
- case HITGROUP_LEFTLEG:
- case HITGROUP_RIGHTLEG:
- currentDamage *= 0.75f;
- break;
- default:
- break;
- }
- if (armorValue > 0 && IsArmored())
- {
- float bonusValue = 1.f, armorBonusRatio = 0.5f, armorRatio = weaponData->flArmorRatio / 2.f;
- if (hasHeavyArmor)
- {
- armorBonusRatio = 0.33f;
- armorRatio *= 0.5f;
- bonusValue = 0.33f;
- }
- auto NewDamage = currentDamage * armorRatio;
- if (((currentDamage - (currentDamage * armorRatio)) * (bonusValue * armorBonusRatio)) > armorValue)
- NewDamage = currentDamage - (armorValue / armorBonusRatio);
- currentDamage = NewDamage;
- }
- }
- ////////////////////////////////////// Main Autowall Functions //////////////////////////////////////
- bool c_autowall::trace_to_exit(CGameTrace& enterTrace, CGameTrace& exitTrace, Vector startPosition, Vector direction)
- {
- Vector start, end;
- float maxDistance = 90.f, rayExtension = 4.f, currentDistance = 0;
- int firstContents = 0;
- while (currentDistance <= maxDistance)
- {
- currentDistance += rayExtension;
- start = startPosition + direction * currentDistance;
- if (!firstContents)
- firstContents = g_pEngineTrace->GetPointContents(start, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr);
- int pointContents = g_pEngineTrace->GetPointContents(start, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr);
- if (!(pointContents & MASK_SHOT_HULL) || pointContents & CONTENTS_HITBOX && pointContents != firstContents)
- {
- end = start - (direction * rayExtension);
- TraceLine(start, end, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr, &exitTrace);
- if (exitTrace.startsolid && exitTrace.surface.flags & SURF_HITBOX)
- {
- TraceLine(start, startPosition, MASK_SHOT_HULL, (IClientEntity*)exitTrace.hit_entity, &exitTrace);
- if (exitTrace.DidHit() && !exitTrace.startsolid)
- {
- start = exitTrace.endpos;
- return true;
- }
- continue;
- }
- if (exitTrace.DidHit() && !exitTrace.startsolid)
- {
- if (BreakableEntity((IClientEntity*)enterTrace.hit_entity) && BreakableEntity((IClientEntity*)exitTrace.hit_entity))
- return true;
- if (enterTrace.surface.flags & SURF_NODRAW || !(exitTrace.surface.flags & SURF_NODRAW) && (exitTrace.plane.normal.Dot(direction) <= 1.f))
- {
- float multAmount = exitTrace.fraction * 4.f;
- start -= direction * multAmount;
- return true;
- }
- continue;
- }
- if (!exitTrace.DidHit() || exitTrace.startsolid)
- {
- if (enterTrace.DidHitNonWorldEntity() && BreakableEntity((IClientEntity*)enterTrace.hit_entity))
- {
- exitTrace = enterTrace;
- exitTrace.endpos = start + direction;
- return true;
- }
- continue;
- }
- }
- }
- return false;
- }
- bool c_autowall::HandleBulletPenetration(WeaponInfo_t* weaponData, CGameTrace& enterTrace, Vector& eyePosition, Vector direction, int& possibleHitsRemaining, float& currentDamage, float penetrationPower, bool sv_penetration_type, float ff_damage_reduction_bullets, float ff_damage_bullet_penetration)
- {
- //Because there's been issues regarding this- putting this here.
- if (¤tDamage == nullptr)
- {
- return false;
- }
- C_BaseEntity* local = (C_BaseEntity*)g_pEntityList->GetClientEntity(g_pEngine->GetLocalPlayer());
- auto data = FireBulletData(local->GetEyePosition());
- data.filter = CTraceFilter();
- data.filter.pSkip = local;
- CGameTrace exitTrace;
- C_BaseEntity* pEnemy = (C_BaseEntity*)enterTrace.hit_entity;
- surfacedata_t *enterSurfaceData = g_PhysSurface->GetSurfaceData(enterTrace.surface.surfaceProps);
- int enterMaterial = enterSurfaceData->game.material;
- float enterSurfPenetrationModifier = enterSurfaceData->game.flPenetrationModifier;
- float enterDamageModifier = enterSurfaceData->game.flDamageModifier;
- float thickness, modifier, lostDamage, finalDamageModifier, combinedPenetrationModifier;
- bool isSolidSurf = ((enterTrace.contents >> 3) & CONTENTS_SOLID);
- bool isLightSurf = ((enterTrace.surface.flags >> 7) & SURF_LIGHT);
- if (possibleHitsRemaining <= 0
- || (enterTrace.surface.name == (const char*)0x2227c261 && exitTrace.surface.name == (const char*)0x2227c868)
- || (!possibleHitsRemaining && !isLightSurf && !isSolidSurf && enterMaterial != CHAR_TEX_GRATE && enterMaterial != CHAR_TEX_GLASS)
- || weaponData->flPenetration <= 0.f
- || !trace_to_exit(enterTrace, exitTrace, enterTrace.endpos, direction)
- && !(g_pEngineTrace->GetPointContents(enterTrace.endpos, MASK_SHOT_HULL, nullptr) & MASK_SHOT_HULL))
- {
- return false;
- }
- surfacedata_t *exitSurfaceData = g_PhysSurface->GetSurfaceData(exitTrace.surface.surfaceProps);
- int exitMaterial = exitSurfaceData->game.material;
- float exitSurfPenetrationModifier = exitSurfaceData->game.flPenetrationModifier;
- float exitDamageModifier = exitSurfaceData->game.flDamageModifier;
- if (sv_penetration_type)
- {
- if (enterMaterial == CHAR_TEX_GRATE || enterMaterial == CHAR_TEX_GLASS)
- {
- combinedPenetrationModifier = 3.f;
- finalDamageModifier = 0.05f;
- }
- else if (isSolidSurf || isLightSurf)
- {
- combinedPenetrationModifier = 1.f;
- finalDamageModifier = 0.16f;
- }
- else if (enterMaterial == CHAR_TEX_FLESH && (local->GetTeam() == pEnemy->GetTeam() && ff_damage_reduction_bullets == 0.f))
- {
- if (ff_damage_bullet_penetration == 0.f)
- {
- return false;
- }
- combinedPenetrationModifier = ff_damage_bullet_penetration;
- finalDamageModifier = 0.16f;
- }
- else
- {
- combinedPenetrationModifier = (enterSurfPenetrationModifier + exitSurfPenetrationModifier) / 2.f;
- finalDamageModifier = 0.16f;
- }
- if (enterMaterial == exitMaterial)
- {
- if (exitMaterial == CHAR_TEX_CARDBOARD || exitMaterial == CHAR_TEX_WOOD)
- combinedPenetrationModifier = 3.f;
- else if (exitMaterial == CHAR_TEX_PLASTIC)
- combinedPenetrationModifier = 2.f;
- }
- thickness = (exitTrace.endpos - enterTrace.endpos).LengthSqr();
- modifier = fmaxf(1.f / combinedPenetrationModifier, 0.f);
- lostDamage = fmaxf(
- ((modifier * thickness) / 24.f)
- + ((currentDamage * finalDamageModifier)
- + (fmaxf(3.75f / penetrationPower, 0.f) * 3.f * modifier)), 0.f);
- if (lostDamage > currentDamage)
- {
- return false;
- }
- if (lostDamage > 0.f)
- currentDamage -= lostDamage;
- if (currentDamage < 1.f)
- {
- return false;
- }
- eyePosition = exitTrace.endpos;
- --possibleHitsRemaining;
- return true;
- }
- else
- {
- combinedPenetrationModifier = 1.f;
- if (isSolidSurf || isLightSurf)
- finalDamageModifier = 0.99f;
- else
- {
- finalDamageModifier = fminf(enterDamageModifier, exitDamageModifier);
- combinedPenetrationModifier = fminf(enterSurfPenetrationModifier, exitSurfPenetrationModifier);
- }
- if (enterMaterial == exitMaterial && (exitMaterial == CHAR_TEX_METAL || exitMaterial == CHAR_TEX_WOOD))
- combinedPenetrationModifier += combinedPenetrationModifier;
- thickness = (exitTrace.endpos - enterTrace.endpos).LengthSqr();
- if (sqrt(thickness) <= combinedPenetrationModifier * penetrationPower)
- {
- currentDamage *= finalDamageModifier;
- eyePosition = exitTrace.endpos;
- --possibleHitsRemaining;
- return true;
- }
- return false;
- }
- }
- bool c_autowall::FireBullet(C_BaseCombatWeapon* pWeapon, Vector& direction, float& currentDamage)
- {
- if (!pWeapon)
- return false;
- C_BaseEntity* local = (C_BaseEntity*)g_pEntityList->GetClientEntity(g_pEngine->GetLocalPlayer());
- auto data = FireBulletData(local->GetEyePosition());
- data.filter = CTraceFilter();
- data.filter.pSkip = local;
- bool sv_penetration_type;
- float currentDistance = 0.f, penetrationPower, penetrationDistance, maxRange, ff_damage_reduction_bullets, ff_damage_bullet_penetration, rayExtension = 40.f;
- Vector eyePosition = local->GetEyePosition();
- static ConVar* penetrationSystem = g_pCVar->FindVar(("sv_penetration_type"));
- static ConVar* damageReductionBullets = g_pCVar->FindVar(("ff_damage_reduction_bullets"));
- static ConVar* damageBulletPenetration = g_pCVar->FindVar(("ff_damage_bullet_penetration"));
- sv_penetration_type = penetrationSystem->GetBool();
- ff_damage_reduction_bullets = damageReductionBullets->GetFloat();
- ff_damage_bullet_penetration = damageBulletPenetration->GetFloat();
- WeaponInfo_t* weaponData = pWeapon->GetCSWpnData();
- CGameTrace enterTrace;
- CTraceFilter filter;
- filter.pSkip = local;
- if (!weaponData)
- return false;
- maxRange = weaponData->flRange;
- GetBulletTypeParameters(penetrationPower, penetrationDistance, weaponData->szBulletType, sv_penetration_type);
- if (sv_penetration_type)
- penetrationPower = weaponData->flPenetration;
- int possibleHitsRemaining = 4;
- currentDamage = weaponData->iDamage;
- while (possibleHitsRemaining > 0 && currentDamage >= 1.f)
- {
- maxRange -= currentDistance;
- Vector end = eyePosition + direction * maxRange;
- TraceLine(eyePosition, end, MASK_SHOT_HULL | CONTENTS_HITBOX, (IClientEntity*)local, &enterTrace);
- ClipTraceToPlayers(eyePosition, end + direction * rayExtension, MASK_SHOT_HULL | CONTENTS_HITBOX, &filter, &enterTrace); // | CONTENTS_HITBOX
- surfacedata_t *enterSurfaceData = g_PhysSurface->GetSurfaceData(enterTrace.surface.surfaceProps);
- float enterSurfPenetrationModifier = enterSurfaceData->game.flPenetrationModifier;
- int enterMaterial = enterSurfaceData->game.material;
- if (enterTrace.fraction == 1.f)
- break;
- currentDistance += enterTrace.fraction * maxRange;
- currentDamage *= pow(weaponData->flRangeModifier, (currentDistance / 500.f));
- if (currentDistance > penetrationDistance && weaponData->flPenetration > 0.f || enterSurfPenetrationModifier < 0.1f)
- break;
- bool canDoDamage = (enterTrace.hitgroup != HITGROUP_GEAR && enterTrace.hitgroup != HITGROUP_GENERIC);
- bool isEnemy = (((C_BaseEntity*)local)->GetTeam() != ((C_BaseEntity*)enterTrace.hit_entity)->GetTeam());
- if ((canDoDamage && isEnemy))
- {
- ScaleDamage(enterTrace, weaponData, currentDamage);
- return true;
- }
- if (!HandleBulletPenetration(weaponData, enterTrace, eyePosition, direction, possibleHitsRemaining, currentDamage, penetrationPower, sv_penetration_type, ff_damage_reduction_bullets, ff_damage_bullet_penetration))
- break;
- }
- return false;
- }
- ////////////////////////////////////// Usage Calls //////////////////////////////////////
- float c_autowall::CanHit(Vector &point)
- {
- C_BaseEntity* local = (C_BaseEntity*)g_pEntityList->GetClientEntity(g_pEngine->GetLocalPlayer());
- if (!local || !local->IsAlive())
- return -1;
- auto data = FireBulletData(local->GetEyePosition());
- data.filter = CTraceFilter();
- data.filter.pSkip = local;
- Vector angles;
- Vector direction;
- Vector tmp = point - local->GetEyePosition();
- float currentDamage = 0;
- MATH::VectorAngles234(tmp, angles);
- MATH::AngleVectors234(angles, &direction);
- direction.NormalizeInPlace();
- if (FireBullet(local->GetActiveWeapon(), direction, currentDamage))
- return currentDamage;
- return -1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement