гейский анал
-
Автор темы
- #1
Слова автора с uc( перевел близко к тексту, вроде как читабельно)
Поскольку я больше не активен в этом сообществе, я мог бы также опубликовать то, что у меня есть.
Во многих местах все расписано с помощью коментариев и вся необходимая информация присутствует.
Если вы не понимаете что это и видите это первый раз пожалуйста посмотрите и прочитайте комментарии прежде чем вставлять это к себе.
Если у вас есть какие-либо проблемы или предложения для этого кода, которые могут быть сделаны, сообщите мне, так как это поможет всем.
Наслаждайтесь.
//
//
Видос от меня в доказательство того что все работает
Поскольку я больше не активен в этом сообществе, я мог бы также опубликовать то, что у меня есть.
Во многих местах все расписано с помощью коментариев и вся необходимая информация присутствует.
Если вы не понимаете что это и видите это первый раз пожалуйста посмотрите и прочитайте комментарии прежде чем вставлять это к себе.
Если у вас есть какие-либо проблемы или предложения для этого кода, которые могут быть сделаны, сообщите мне, так как это поможет всем.
Наслаждайтесь.
Код:
////////////////////////////////////// Traces //////////////////////////////////////
void 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_EngineTrace->TraceRay(ray, mask, &filter, ptr);
}
void Autowall::ClipTraceToPlayers(Vector& absStart, Vector absEnd, unsigned int mask, ITraceFilter* filter, CGameTrace* tr)
{
//TODO: Un-ASM this
#ifdef _WIN32
_asm
{
mov eax, filter
lea ecx, tr
push ecx
push eax
push mask
lea edx, absEnd
lea ecx, absStart
call UTIL_ClipTraceToPlayers
add esp, 0xC
}
#else
UTIL_ClipTraceToPlayers(absStart, absEnd, mask, filter, tr, 60.f, 0.f);
#endif
}
////////////////////////////////////// Legacy Functions //////////////////////////////////////
void 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, PROTSTR1("BULLET_PLAYER_338MAG")))
{
maxRange = 45.0;
maxDistance = 8000.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_762MM")))
{
maxRange = 39.0;
maxDistance = 5000.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_556MM")) || !strcmp(bulletType, PROTSTR1("BULLET_PLAYER_556MM_SMALL")) || !strcmp(bulletType, PROTSTR1("BULLET_PLAYER_556MM_BOX")))
{
maxRange = 35.0;
maxDistance = 4000.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_57MM")))
{
maxRange = 30.0;
maxDistance = 2000.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_50AE")))
{
maxRange = 30.0;
maxDistance = 1000.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_357SIG")) || !strcmp(bulletType, PROTSTR1("BULLET_PLAYER_357SIG_SMALL")) || !strcmp(bulletType, PROTSTR1("BULLET_PLAYER_357SIG_P250")) || !strcmp(bulletType, PROTSTR1("BULLET_PLAYER_357SIG_MIN")))
{
maxRange = 25.0;
maxDistance = 800.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_9MM")))
{
maxRange = 21.0;
maxDistance = 800.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_45ACP")))
{
maxRange = 15.0;
maxDistance = 500.0;
}
if (!strcmp(bulletType, PROTSTR1("BULLET_PLAYER_BUCKSHOT")))
{
maxRange = 0.0;
maxDistance = 0.0;
}
}
}
////////////////////////////////////// Misc Functions //////////////////////////////////////
bool Autowall::IsBreakableEntity(IClientEntity* entity)
{
if (!entity || entity->EntIndex() == 0)
return false;
//m_takeDamage isn't properly set when using the signature.
//Back it up, set it to true, then restore.
int takeDamageBackup = ((C_BaseEntity*)entity)->m_takeDamage();
ClientClass *pClass = entity->GetClientClass();
// ' '' ' ' '
// 01234567890123456 012345678
//Check against CBreakableSurface and CBaseDoor
//Windows etc. are CBrekableSurface
//Large garage door in Office is CBaseDoor and it get's reported as a breakable when it is not one
//This is seperate from "CPropDoorRotating", which is a normal door.
//Normally you would also check for "CFuncBrush" but it was acting oddly so I removed it. It's below if interested.
//((clientClass->m_pNetworkName[1]) != 'F' || (clientClass->m_pNetworkName[4]) != 'c' || (clientClass->m_pNetworkName[5]) != 'B' || (clientClass->m_pNetworkName[9]) != 'h')
if ((pClass->m_pNetworkName[1] == 'B' && pClass->m_pNetworkName[9] == 'e' && pClass->m_pNetworkName[10] == 'S' && pClass->m_pNetworkName[16] == 'e')
|| (pClass->m_pNetworkName[1] != 'B' || pClass->m_pNetworkName[5] != 'D'))
((C_BaseEntity*)entity)->m_takeDamage() = DAMAGE_YES;
bool breakable = ::IsBreakableEntity(entity);
((C_BaseEntity*)entity)->m_takeDamage() = takeDamageBackup;
return breakable;
}
void Autowall::ScaleDamage(CGameTrace &enterTrace, CCSWeaponInfo *weaponData, float& currentDamage)
{
//Cred. to N0xius for reversing this.
//TODO: _xAE^; look into reversing this yourself sometime
bool hasHeavyArmor = ((C_BasePlayer*)enterTrace.m_pEnt)->m_bHasHeavyArmor();
int armorValue = ((C_BasePlayer*)enterTrace.m_pEnt)->m_ArmorValue();
HitGroups hitGroup = enterTrace.hitgroup;
//Fuck making a new function, lambda beste. ~ Does the person have armor on for the hitbox checked?
auto IsArmored = [&enterTrace]()->bool
{
C_BasePlayer* targetEntity = (C_BasePlayer*)enterTrace.m_pEnt;
switch (enterTrace.hitgroup)
{
case HitGroups::HITGROUP_HEAD:
return !!(C_BasePlayer*)targetEntity->m_bHasHelmet(); //Fuck compiler errors - force-convert it to a bool via (!!)
case HitGroups::HITGROUP_GENERIC:
case HitGroups::HITGROUP_CHEST:
case HitGroups::HITGROUP_STOMACH:
case HitGroups::HITGROUP_LEFTARM:
case HitGroups::HITGROUP_RIGHTARM:
return true;
default:
return false;
}
};
switch (hitGroup)
{
case HitGroups::HITGROUP_HEAD:
currentDamage *= hasHeavyArmor ? 2.f : 4.f; //Heavy Armor does 1/2 damage
break;
case HitGroups::HITGROUP_STOMACH:
currentDamage *= 1.25f;
break;
case HitGroups::HITGROUP_LEFTLEG:
case HitGroups::HITGROUP_RIGHTLEG:
currentDamage *= 0.75f;
break;
default:
break;
}
if (armorValue > 0 && IsArmored())
{
float bonusValue = 1.f, armorBonusRatio = 0.5f, armorRatio = weaponData->flArmorRatio() / 2.f;
//Damage gets modified for heavy armor users
if (hasHeavyArmor)
{
armorBonusRatio = 0.33f;
armorRatio *= 0.5f;
bonusValue = 0.33f;
}
auto NewDamage = currentDamage * armorRatio;
if (hasHeavyArmor)
NewDamage *= 0.85f;
if (((currentDamage - (currentDamage * armorRatio)) * (bonusValue * armorBonusRatio)) > armorValue)
NewDamage = currentDamage - (armorValue / armorBonusRatio);
currentDamage = NewDamage;
}
}
////////////////////////////////////// Main Autowall Functions //////////////////////////////////////
bool Autowall::TraceToExit(CGameTrace& enterTrace, CGameTrace& exitTrace, Vector startPosition, Vector direction)
{
/*
Masks used:
MASK_SHOT_HULL = 0x600400B
CONTENTS_HITBOX = 0x40000000
MASK_SHOT_HULL | CONTENTS_HITBOX = 0x4600400B
*/
Vector start, end;
float maxDistance = 90.f, rayExtension = 4.f, currentDistance = 0;
int firstContents = 0;
while (currentDistance <= maxDistance)
{
//Add extra distance to our ray
currentDistance += rayExtension;
//Multiply the direction vector to the distance so we go outwards, add our position to it.
start = startPosition + direction * currentDistance;
if (!firstContents)
firstContents = g_EngineTrace->GetPointContents(start, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr); /*0x4600400B*/
int pointContents = g_EngineTrace->GetPointContents(start, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr);
if (!(pointContents & MASK_SHOT_HULL) || pointContents & CONTENTS_HITBOX && pointContents != firstContents) /*0x600400B, *0x40000000*/
{
//Let's setup our end position by deducting the direction by the extra added distance
end = start - (direction * rayExtension);
//Let's cast a ray from our start pos to the end pos
TraceLine(start, end, MASK_SHOT_HULL | CONTENTS_HITBOX, nullptr, &exitTrace);
//Let's check if a hitbox is in-front of our enemy and if they are behind of a solid wall
if (exitTrace.startsolid && exitTrace.surface.flags & SURF_HITBOX)
{
TraceLine(start, startPosition, MASK_SHOT_HULL, exitTrace.m_pEnt, &exitTrace);
if (exitTrace.DidHit() && !exitTrace.startsolid)
{
start = exitTrace.endpos;
return true;
}
continue;
}
//Can we hit? Is the wall solid?
if (exitTrace.DidHit() && !exitTrace.startsolid)
{
//Is the wall a breakable? If so, let's shoot through it.
if (Autowall::IsBreakableEntity(enterTrace.m_pEnt) && Autowall::IsBreakableEntity(exitTrace.m_pEnt))
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() && Autowall::IsBreakableEntity(enterTrace.m_pEnt))
{
exitTrace = enterTrace;
exitTrace.endpos = start + direction;
return true;
}
continue;
}
}
}
return false;
}
bool Autowall::HandleBulletPenetration(CCSWeaponInfo* 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)
throw std::invalid_argument("currentDamage is null!");
SafeLocalPlayer() false;
CGameTrace exitTrace;
C_BaseEntity* pEnemy = (C_BasePlayer*)enterTrace.m_pEnt;
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
//Test for "DE_CACHE/DE_CACHE_TELA_03" as the entering surface and "CS_ITALY/CR_MISCWOOD2B" as the exiting surface.
//Fixes a wall in de_cache which seems to be broken in some way. Although bullet penetration is not recorded to go through this wall
//Decals can be seen of bullets within the glass behind of the enemy. Hacky method, but works.
//You might want to have a check for this to only be activated on de_cache.
|| (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
|| !TraceToExit(enterTrace, exitTrace, enterTrace.endpos, direction)
&& !(g_EngineTrace->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;
//Are we using the newer penetration system?
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 && (localPlayer->m_iTeamNum() == pEnemy->m_iTeamNum() && ff_damage_reduction_bullets == 0.f)) //TODO: Team check config
{
//Look's like you aren't shooting through your teammate today
if (ff_damage_bullet_penetration == 0.f)
return false;
//Let's shoot through teammates and get kicked for teamdmg! Whatever, atleast we did damage to the enemy. I call that a win.
combinedPenetrationModifier = ff_damage_bullet_penetration;
finalDamageModifier = 0.16f;
}
else
{
combinedPenetrationModifier = (enterSurfPenetrationModifier + exitSurfPenetrationModifier) / 2.f;
finalDamageModifier = 0.16f;
}
//Do our materials line up?
if (enterMaterial == exitMaterial)
{
if (exitMaterial == CHAR_TEX_CARDBOARD || exitMaterial == CHAR_TEX_WOOD)
combinedPenetrationModifier = 3.f;
else if (exitMaterial == CHAR_TEX_PLASTIC)
combinedPenetrationModifier = 2.f;
}
//Calculate thickness of the wall by getting the length of the range of the trace and squaring
thickness = (exitTrace.endpos - enterTrace.endpos).LengthSqr();
modifier = fmaxf(1.f / combinedPenetrationModifier, 0.f);
//This calculates how much damage we've lost depending on thickness of the wall, our penetration, damage, and the modifiers set earlier
lostDamage = fmaxf(
((modifier * thickness) / 24.f)
+ ((currentDamage * finalDamageModifier)
+ (fmaxf(3.75f / penetrationPower, 0.f) * 3.f * modifier)), 0.f);
//Did we loose too much damage?
if (lostDamage > currentDamage)
return false;
//We can't use any of the damage that we've lost
if (lostDamage > 0.f)
currentDamage -= lostDamage;
//Do we still have enough damage to deal?
if (currentDamage < 1.f)
return false;
eyePosition = exitTrace.endpos;
--possibleHitsRemaining;
return true;
}
else //Legacy penetration system
{
combinedPenetrationModifier = 1.f;
if (isSolidSurf || isLightSurf)
finalDamageModifier = 0.99f; //Good meme :^)
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 Autowall::FireBullet(C_BaseCombatWeapon* pWeapon, Vector& direction, float& currentDamage)
{
if (!pWeapon)
return false;
SafeLocalPlayer() false;
bool sv_penetration_type;
// Current bullet travel Power to penetrate Distance to penetrate Range Player bullet reduction convars Amount to extend ray by
float currentDistance = 0.f, penetrationPower, penetrationDistance, maxRange, ff_damage_reduction_bullets, ff_damage_bullet_penetration, rayExtension = 40.f;
Vector eyePosition = localPlayer->GetEyePos();
//For being superiour when the server owners think your autowall isn't well reversed. Imagine a meme HvH server with the old penetration system- pff
static ConVar* penetrationSystem = g_CVar->FindVar(PROTSTR1("sv_penetration_type"));
static ConVar* damageReductionBullets = g_CVar->FindVar(PROTSTR1("ff_damage_reduction_bullets"));
static ConVar* damageBulletPenetration = g_CVar->FindVar(PROTSTR1("ff_damage_bullet_penetration"));
sv_penetration_type = penetrationSystem->GetBool();
ff_damage_reduction_bullets = damageReductionBullets->GetFloat();
ff_damage_bullet_penetration = damageBulletPenetration->GetFloat();
CCSWeaponInfo* weaponData = pWeapon->GetCSWeaponData();
CGameTrace enterTrace;
//We should be skipping localplayer when casting a ray to players.
CTraceFilter filter;
filter.pSkip = localPlayer;
if (!weaponData)
return false;
maxRange = weaponData->flRange();
GetBulletTypeParameters(penetrationPower, penetrationDistance, weaponData->bulletType(), sv_penetration_type);
if (sv_penetration_type)
penetrationPower = weaponData->flPenetration();
//This gets set in FX_Firebullets to 4 as a pass-through value.
//CS:GO has a maximum of 4 surfaces a bullet can pass-through before it 100% stops.
//Excerpt from Valve: https://steamcommunity.com/sharedfiles/filedetails/?id=275573090
//"The total number of surfaces any bullet can penetrate in a single flight is capped at 4." -CS:GO Official
int possibleHitsRemaining = 4;
//Set our current damage to what our gun's initial damage reports it will do
currentDamage = weaponData->iDamage();
//If our damage is greater than (or equal to) 1, and we can shoot, let's shoot.
while (possibleHitsRemaining > 0 && currentDamage >= 1.f)
{
//Calculate max bullet range
maxRange -= currentDistance;
//Create endpoint of bullet
Vector end = eyePosition + direction * maxRange;
TraceLine(eyePosition, end, MASK_SHOT_HULL | CONTENTS_HITBOX, localPlayer, &enterTrace);
Autowall::ClipTraceToPlayers(eyePosition, end + direction * rayExtension, MASK_SHOT_HULL | CONTENTS_HITBOX, &filter, &enterTrace);
//We have to do this *after* tracing to the player.
surfacedata_t *enterSurfaceData = g_PhysSurface->GetSurfaceData(enterTrace.surface.surfaceProps);
float enterSurfPenetrationModifier = enterSurfaceData->game.flPenetrationModifier;
int enterMaterial = enterSurfaceData->game.material;
//"Fraction == 1" means that we didn't hit anything. We don't want that- so let's break on it.
if (enterTrace.fraction == 1.f)
break;
//calculate the damage based on the distance the bullet traveled.
currentDistance += enterTrace.fraction * maxRange;
//Let's make our damage drops off the further away the bullet is.
currentDamage *= pow(weaponData->flRangeModifier(), (currentDistance / 500.f));
//Sanity checking / Can we actually shoot through?
if (currentDistance > penetrationDistance && weaponData->flPenetration() > 0.f || enterSurfPenetrationModifier < 0.1f)
break;
//This looks gay as fuck if we put it into 1 long line of code.
bool canDoDamage = (enterTrace.hitgroup != HitGroups::HITGROUP_GEAR && enterTrace.hitgroup != HitGroups::HITGROUP_GENERIC);
bool isPlayer = ((enterTrace.m_pEnt)->GetClientClass()->m_ClassID == ClassId_CCSPlayer);
bool isEnemy = (((C_BasePlayer*)localPlayer)->m_iTeamNum() != ((C_BasePlayer*)enterTrace.m_pEnt)->m_iTeamNum());
bool onTeam = (((C_BasePlayer*)enterTrace.m_pEnt)->m_iTeamNum() == (int32_t)TeamNumbers::TEAM_CT || ((C_BasePlayer*)enterTrace.m_pEnt)->m_iTeamNum() == (int32_t)TeamNumbers::TEAM_T);
//TODO: Team check config
if ((canDoDamage && isPlayer && isEnemy) && onTeam)
{
ScaleDamage(enterTrace, weaponData, currentDamage);
return true;
}
//Calling HandleBulletPenetration here reduces our penetrationCounter, and if it returns true, we can't shoot through it.
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 Autowall::CanHit(Vector &vecEyePos, Vector &point)
{
SafeLocalPlayer() -1.f; //If localplayer isn't avaliable, just return as "too thick"
Vector angles, direction;
Vector tmp = point - localPlayer->GetEyePos();
float currentDamage = 0;
Math::VectorAngles(tmp, angles);
Math::AngleVectors(angles, &direction);
direction.NormalizeInPlace();
if (FireBullet(localPlayer->m_hActiveWeapon(), direction, currentDamage))
return currentDamage;
return -1; //That wall is just a bit too thick buddy
}
//////////////////////////////////////////////////////////////////////////////////////////////
// Wow I took way too long on autowall.
// Special Thanks to the following (No order intended)
// Killerra
// Flaw
// Zbe
// Heep
// Polak (indirectly; IsBreakable Fix)
// Esoterik (Autowall UC Post)
// N0xius (ScaleDamage)
// Requiii
// drew1ind#8957 (Scaling for ConVar)
// The non-autistic slice of CS:GO-UC
//
Видос от меня в доказательство того что все работает