Fix truce and enable aimbot to aim at npcs (#1137)

* Fix truce and enable aimbot to aim at npcs

This simply makes aimbot able to aim at npcs and the cheat will ignore players in truce.

* Added Horseless Headless Horsemann as aimbot target

* Move truce check

* Improve NPC/Item esp

Co-authored-by: NotAnUser1 <NotAnUser1@github.com>

Co-authored-by: d3fc0n6 <7269950-d3fc0n6@users.noreply.gitlab.com>
Co-authored-by: NotAnUser1 <NotAnUser1@github.com>
This commit is contained in:
LightCat 2020-10-25 22:35:34 +01:00 committed by GitHub
parent 6559321a4c
commit 46e139a44e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 286 additions and 101 deletions

View File

@ -17,14 +17,17 @@
<AutoVariable width="fill" target="esp.item.enable" label="Enable item ESP"/>
<AutoVariable width="fill" target="esp.projectile.enable" label="Enable projectile ESP"/>
<AutoVariable width="fill" target="esp.projectile.enemy-only" label="Only enemy projectiles"/>
<AutoVariable width="fill" target="esp.show.tank" label="Tank ESP"/>
<AutoVariable width="fill" target="esp.show.npc" label="NPC ESP"/>
<AutoVariable width="fill" target="esp.item.money" label="MvM money"/>
<AutoVariable width="fill" target="esp.item.money-red" label="MvM red money" tooltip="Red money is automatically collected."/>
<AutoVariable width="fill" target="esp.item.powerup" label="Mannpower powerups"/>
<AutoVariable width="fill" target="esp.item.spellbook" label="Spellbooks"/>
<AutoVariable width="fill" target="esp.item.weapons" label="HL2:DM weapons"/>
<AutoVariable width="fill" target="esp.item.explosive" label="Explosives" tooltip="Environmental hazards like bombs"/>
<AutoVariable width="fill" target="esp.item.crumpkin" label="Crumpkin" tooltip="Ammo box that also gives crits"/>
<AutoVariable width="fill" target="esp.item.gargoyle" label="Gargoyle" tooltip="Soul gargoyle pickup on halloween maps"/>
<!-- <AutoVariable width="fill" target="esp.item.weapons" label="HL2:DM weapons"/>
<AutoVariable width="fill" target="esp.item.adrenaline" label="TF2C adrenaline"/>
<AutoVariable width="fill" target="esp.item.weapon-spawner" label="TC2C weapon spawner"/>
<AutoVariable width="fill" target="esp.item.weapon-spawner" label="TC2C weapon spawner"/> -->
</List>
</Box>
<Box padding="12 6 6 6" width="content" height="content" name="Projectiles" x="170">

View File

@ -202,6 +202,7 @@ public:
offset_t m_iPlayerLevel_Resource;
offset_t m_iPlayerIndex;
offset_t m_hTargetPlayer;
};
extern NetVars netvar;

View File

@ -157,6 +157,8 @@ public:
ret = ENTITY_PROJECTILE;
else if (classid == CL_CLASS(CObjectTeleporter) || classid == CL_CLASS(CObjectSentrygun) || classid == CL_CLASS(CObjectDispenser))
ret = ENTITY_BUILDING;
else if (classid == CL_CLASS(CZombie) || classid == CL_CLASS(CTFTankBoss) || classid == CL_CLASS(CMerasmus) || classid == CL_CLASS(CMerasmusDancer) || classid == CL_CLASS(CEyeballBoss) || classid == CL_CLASS(CHeadlessHatman))
ret = ENTITY_NPC;
else
ret = ENTITY_GENERIC;
return ret;

View File

@ -12,7 +12,8 @@ enum EntityType
ENTITY_GENERIC,
ENTITY_PLAYER,
ENTITY_BUILDING,
ENTITY_PROJECTILE
ENTITY_PROJECTILE,
ENTITY_NPC
};
enum powerup_type
@ -102,4 +103,4 @@ enum hitbox_t
hip_R = 15,
knee_R = 16,
foot_R = 17
};
};

View File

@ -227,3 +227,5 @@ template <typename... Args> std::string format(const Args &... args)
extern const std::string classes[10];
extern const char *powerups[POWERUP_COUNT];
bool isTruce();
void setTruce(bool status);

View File

@ -24,6 +24,7 @@ enum k_EItemType
ITEM_AMMO_SMALL,
ITEM_AMMO_MEDIUM,
ITEM_AMMO_LARGE,
ITEM_CRUMPKIN,
ITEM_POWERUP_STRENGTH,
ITEM_POWERUP_RESISTANCE,
@ -42,6 +43,14 @@ enum k_EItemType
ITEM_POWERUP_FIRST = ITEM_POWERUP_STRENGTH,
ITEM_POWERUP_LAST = ITEM_POWERUP_CRITS,
HALLOWEEN_GHOST,
HALLOWEEN_GHOST_NOHAT_RED,
HALLOWEEN_GHOST_NOHAT,
BOMB_BALLOONBOMB,
BOMB_WOODENBARREL,
BOMB_WALKEREXPLODE,
ITEM_TF2C_PILL,
ITEM_TF2C_CRITS,

View File

@ -6,12 +6,11 @@
*/
#pragma once
class CGameRules
{
public:
int unknown_pad_0[12];
int roundmode;
int unknown_pad_1[1];
int winning_team;
int pad0[12]; // 0 | 48 bytes | 48
int roundmode; // 48 | 4 bytes | 52
int pad1[1]; // 52 | 4 bytes | 56
int winning_team; // 56 | 4 bytes | 60
};

View File

@ -49,8 +49,15 @@ bool shouldTarget(CachedEntity *entity)
return false;
if (HasCondition<TFCond_HalloweenGhostMode>(entity))
return false;
// Don't shoot players in truce
if (isTruce())
return false;
return shouldTargetSteamId(entity->player_info.friendsID);
}
else if (entity->m_Type() == ENTITY_BUILDING)
// Don't shoot buildings in truce
if (isTruce())
return false;
return true;
}

View File

@ -149,6 +149,9 @@ void NetVars::Init()
this->m_iHealingAssist_Resource = gNetvars.get_offset("DT_TFPlayerResource", "m_iHealingAssist");
this->m_iPlayerLevel_Resource = gNetvars.get_offset("DT_TFPlayerResource", "m_iPlayerLevel");
this->m_iPlayerIndex = gNetvars.get_offset("DT_TFRagdoll", "m_iPlayerIndex");
// Gargoyle
this->m_hTargetPlayer = gNetvars.get_offset("DT_CHalloweenGiftPickup", "m_hTargetPlayer");
}
IF_GAME(IsTF2C())
{

View File

@ -77,6 +77,7 @@ static settings::Boolean ignore_vaccinator{ "aimbot.target.ignore-vaccinator", "
static settings::Boolean ignore_deadringer{ "aimbot.target.ignore-deadringer", "1" };
static settings::Boolean buildings_sentry{ "aimbot.target.sentry", "1" };
static settings::Boolean buildings_other{ "aimbot.target.other-buildings", "1" };
static settings::Boolean npcs{ "aimbot.target.npcs", "1" };
static settings::Boolean stickybot{ "aimbot.target.stickybomb", "0" };
static settings::Boolean rageonly{ "aimbot.target.ignore-non-rage", "0" };
static settings::Int teammates{ "aimbot.target.teammates", "0" };
@ -141,7 +142,7 @@ int GetSentry()
CachedEntity *ent = ENTITY(i);
if (CE_BAD(ent))
continue;
if ((ent->m_Type() != ENTITY_BUILDING && ent->m_iClassID() != CL_CLASS(CTFTankBoss)) || ent->m_iClassID() != CL_CLASS(CObjectSentrygun))
if (ent->m_Type() != ENTITY_BUILDING || ent->m_iClassID() != CL_CLASS(CObjectSentrygun))
continue;
if ((CE_INT(ent, netvar.m_hBuilder) & 0xFFF) != g_pLocalPlayer->entity_idx)
continue;
@ -745,10 +746,9 @@ bool IsTargetStateGood(CachedEntity *entity)
return false;
return true;
// Check for buildings
}
else if (entity->m_Type() == ENTITY_BUILDING || entity->m_iClassID() == CL_CLASS(CTFTankBoss))
// Check for buildings
else if (entity->m_Type() == ENTITY_BUILDING)
{
// Don't aim if holding sapper
if (g_pLocalPlayer->holding_sapper)
@ -803,9 +803,39 @@ bool IsTargetStateGood(CachedEntity *entity)
return false;
return true;
// Check for stickybombs
}
// NPCs (Skeletons, Merasmus, etc)
else if (entity->m_Type() == ENTITY_NPC)
{
// Sapper aimbot? no.
if (g_pLocalPlayer->holding_sapper)
return false;
// NPC targeting is disabled
if (!npcs)
return false;
// Cannot shoot this
if (entity->m_iTeam() == LOCAL_E->m_iTeam())
return false;
// Distance
if (EffectiveTargetingRange())
{
if (entity->m_flDistance() > (int) EffectiveTargetingRange())
return false;
}
// Grab the prediction var
AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX];
if (!VischeckPredictedEntity(entity))
return false;
if (fov > 0.0f && cd.fov > fov)
return false;
return true;
}
// Check for stickybombs
else if (entity->m_iClassID() == CL_CLASS(CTFGrenadePipebombProjectile))
{
// Enabled
@ -885,7 +915,7 @@ void Aim(CachedEntity *entity)
Vector angles = GetAimAtAngles(g_pLocalPlayer->v_Eye, PredictEntity(entity));
// Multipoint
if (multipoint && !projectile_mode)
if (multipoint && !projectile_mode && entity->m_Type() == ENTITY_PLAYER)
{
// Get hitbox num
AimbotCalculatedData_s &cd = calculated_data_array[entity->m_IDX];
@ -894,7 +924,7 @@ void Aim(CachedEntity *entity)
auto hitboxmin = hb->min;
auto hitboxmax = hb->max;
auto hitboxcenter = hb->center;
if (shouldBacktrack() && entity->m_Type() == ENTITY_PLAYER)
if (shouldBacktrack())
{
// This does vischecks and everything
auto data = hacks::tf2::backtrack::getClosestEntTick(entity, LOCAL_E->m_vecOrigin(), aimbotTickFilter);
@ -1100,16 +1130,23 @@ const Vector &PredictEntity(CachedEntity *entity)
else
GetHitbox(entity, cd.hitbox, result);
}
// Buildings
}
else if (entity->m_Type() == ENTITY_BUILDING || entity->m_iClassID() != CL_CLASS(CTFTankBoss))
// Buildings
else if (entity->m_Type() == ENTITY_BUILDING)
{
if (cur_proj_grav || cur_proj_grav)
result = BuildingPrediction(entity, GetBuildingPosition(entity), cur_proj_speed, cur_proj_grav, cur_proj_start_vel);
else
result = GetBuildingPosition(entity);
// Other
}
// NPCs (Skeletons, merasmus, etc)
else if (entity->m_Type() == ENTITY_NPC)
{
auto mins = RAW_ENT(entity)->GetCollideable()->OBBMins();
auto maxs = RAW_ENT(entity)->GetCollideable()->OBBMaxs();
result = RAW_ENT(entity)->GetCollideable()->GetCollisionOrigin() + (mins + maxs) / 2.0f;
}
// Other
else
{
result = entity->m_vecOrigin();

View File

@ -1,4 +1,4 @@
/*
/*
* HEsp.cpp
*
* Created on: Oct 6, 2016
@ -40,7 +40,7 @@ static settings::Boolean legit{ "esp.legit", "false" };
static settings::Boolean local_esp{ "esp.show.local", "true" };
static settings::Boolean buildings{ "esp.show.buildings", "true" };
static settings::Boolean teammates{ "esp.show.teammates", "true" };
static settings::Boolean tank{ "esp.show.tank", "true" };
static settings::Boolean npc{ "esp.show.npc", "true" };
static settings::Boolean show_weapon{ "esp.info.weapon", "false" };
static settings::Boolean show_distance{ "esp.info.distance", "true" };
@ -60,6 +60,9 @@ static settings::Boolean item_powerups{ "esp.item.powerup", "true" };
static settings::Boolean item_money{ "esp.item.money", "true" };
static settings::Boolean item_money_red{ "esp.item.money-red", "false" };
static settings::Boolean item_spellbooks{ "esp.item.spellbook", "true" };
static settings::Boolean item_explosive{ "esp.item.explosive", "true" };
static settings::Boolean item_crumpkin{ "esp.item.crumpkin", "true" };
static settings::Boolean item_gargoyle{ "esp.item.gargoyle", "true" };
// TF2C
static settings::Boolean item_weapon_spawners{ "esp.item.weapon-spawner", "true" };
static settings::Boolean item_adrenaline{ "esp.item.adrenaline", "true" };
@ -248,6 +251,17 @@ const std::string health_small_str = "Small Medkit";
const std::string mvm_money_str = "Money";
const std::string mvm_red_money_str = "~Money~";
const std::string tank_str = "Tank";
const std::string merasmus_str = "Merasmus";
const std::string monoculus_str = "Monoculus";
const std::string horsemann_str = "Horsemann";
const std::string skeleton_str = "Skeleton";
const std::string ghost_str = "Ghost";
const std::string pumpkinbomb_str = "Pumpkin Bomb";
const std::string crumpkin_str = "Crumpkin";
const std::string gargoyle_str = "Gargoyle";
const std::string balloonbomb_str = "Dynamite Balloon";
const std::string woodenbarrel_str = "Explosive Barrel";
const std::string walkerexplode_str = "Alien Walker";
const std::string rpg_str = "RPG";
const std::string smg_str = "SMG";
const std::string shotgun_str = "Shotgun";
@ -1022,7 +1036,6 @@ void _FASTCALL ProcessEntity(CachedEntity *ent)
// Projectile esp
if (ent->m_Type() == ENTITY_PROJECTILE && proj_esp && (ent->m_bEnemy() || (teammates && !proj_enemy)))
{
// Rockets
if (classid == CL_CLASS(CTFProjectile_Rocket) || classid == CL_CLASS(CTFProjectile_SentryRocket))
{
@ -1104,22 +1117,147 @@ void _FASTCALL ProcessEntity(CachedEntity *ent)
}
}
}
int itemtype = ent->m_ItemType();
// Tank esp
if (classid == CL_CLASS(CTFTankBoss) && tank)
// NPC esp
if (npc)
{
// We can mark everything except the ghost like this
if (ent->m_Type() == ENTITY_NPC)
{
switch (classid)
{
case CL_CLASS(CTFTankBoss):
AddEntityString(ent, tank_str, colors::FromRGBA8(0, 128, 0, 255));
break;
case CL_CLASS(CMerasmus):
case CL_CLASS(CMerasmusDancer):
AddEntityString(ent, merasmus_str, colors::FromRGBA8(0, 128, 0, 255));
break;
case CL_CLASS(CZombie):
AddEntityString(ent, skeleton_str, colors::FromRGBA8(0, 128, 0, 255));
break;
case CL_CLASS(CEyeballBoss):
AddEntityString(ent, monoculus_str, colors::FromRGBA8(0, 128, 0, 255));
break;
case CL_CLASS(CHeadlessHatman):
AddEntityString(ent, horsemann_str, colors::FromRGBA8(0, 128, 0, 255));
break;
}
}
else
{
switch (itemtype)
{
case HALLOWEEN_GHOST:
case HALLOWEEN_GHOST_NOHAT_RED:
case HALLOWEEN_GHOST_NOHAT:
AddEntityString(ent, ghost_str, colors::FromRGBA8(0, 128, 0, 255));
}
}
}
if (item_esp)
{
AddEntityString(ent, tank_str);
// Dropped weapon esp
}
else if (classid == CL_CLASS(CTFDroppedWeapon) && item_esp && item_dropped_weapons)
{
AddEntityString(ent, std::string("Dropped Weapon")); //I've never seen this not being "WEAPON CTFDroppedWeapon" so why not make it prettier?
if (item_dropped_weapons && classid == CL_CLASS(CTFDroppedWeapon))
{
AddEntityString(ent, std::string("Dropped Weapon"));
}
// Gargoyle esp
else if (item_gargoyle && classid == CL_CLASS(CHalloweenGiftPickup))
{
if (HandleToIDX(CE_INT(ent, netvar.m_hTargetPlayer)) == g_pLocalPlayer->entity_idx)
{
AddEntityString(ent, gargoyle_str, colors::FromRGBA8(98, 163, 213, 255));
}
}
// Explosive/Environmental hazard esp
else if (item_explosive && (classid == CL_CLASS(CTFPumpkinBomb) || itemtype == BOMB_BALLOONBOMB || itemtype == BOMB_WOODENBARREL || itemtype == BOMB_WALKEREXPLODE))
{
if (classid == CL_CLASS(CTFPumpkinBomb))
AddEntityString(ent, pumpkinbomb_str, colors::FromRGBA8(255, 162, 0, 255));
else
{
switch (itemtype)
{
case BOMB_BALLOONBOMB:
AddEntityString(ent, balloonbomb_str, colors::FromRGBA8(255, 162, 0, 255));
break;
case BOMB_WOODENBARREL:
AddEntityString(ent, woodenbarrel_str, colors::FromRGBA8(255, 162, 0, 255));
break;
case BOMB_WALKEREXPLODE:
AddEntityString(ent, walkerexplode_str, colors::FromRGBA8(255, 162, 0, 255));
break;
}
}
}
// Other item esp
else if (itemtype != ITEM_NONE)
{
// Health pack esp
if (item_health_packs && (itemtype >= ITEM_HEALTH_SMALL && itemtype <= ITEM_HEALTH_LARGE || itemtype == ITEM_HL_BATTERY))
{
if (itemtype == ITEM_HEALTH_SMALL)
AddEntityString(ent, health_small_str);
if (itemtype == ITEM_HEALTH_MEDIUM)
AddEntityString(ent, health_medium_str);
if (itemtype == ITEM_HEALTH_LARGE)
AddEntityString(ent, health_big_str);
if (itemtype == ITEM_HL_BATTERY)
AddEntityString(ent, hl_battery_str);
// MVM Money esp
// TF2C Adrenaline esp
}
else if (item_adrenaline && itemtype == ITEM_TF2C_PILL)
{
AddEntityString(ent, pill_str);
// Ammo pack esp
}
else if (item_ammo_packs && itemtype >= ITEM_AMMO_SMALL && itemtype <= ITEM_AMMO_LARGE)
{
if (itemtype == ITEM_AMMO_SMALL)
AddEntityString(ent, ammo_small_str);
if (itemtype == ITEM_AMMO_MEDIUM)
AddEntityString(ent, ammo_medium_str);
if (itemtype == ITEM_AMMO_LARGE)
AddEntityString(ent, ammo_big_str);
// Powerup esp
}
else if (item_powerups && itemtype >= ITEM_POWERUP_FIRST && itemtype <= ITEM_POWERUP_LAST)
{
AddEntityString(ent, std::string(powerups[itemtype - ITEM_POWERUP_FIRST]));
// TF2C weapon spawner esp
}
else if (item_weapon_spawners && itemtype >= ITEM_TF2C_W_FIRST && itemtype <= ITEM_TF2C_W_LAST)
{
AddEntityString(ent, std::string(tf2c_weapon_names[itemtype - ITEM_TF2C_W_FIRST]) + " Spawner");
if (CE_BYTE(ent, netvar.bRespawning))
AddEntityString(ent, tf2c_spawner_respawn_str);
}
// Halloween spell esp
else if (item_spellbooks && (itemtype == ITEM_SPELL || itemtype == ITEM_SPELL_RARE))
{
if (itemtype == ITEM_SPELL)
{
AddEntityString(ent, spell_str, colors::green);
}
else
{
AddEntityString(ent, rare_spell_str, colors::FromRGBA8(139, 31, 221, 255));
}
}
// Crumpkin esp https://wiki.teamfortress.com/wiki/Halloween_pumpkin
else if (item_crumpkin && itemtype == ITEM_CRUMPKIN)
{
AddEntityString(ent, crumpkin_str, colors::FromRGBA8(253, 203, 88, 255));
}
}
}
else if (classid == CL_CLASS(CCurrencyPack) && item_money)
// MVM Money esp
if (classid == CL_CLASS(CCurrencyPack) && item_money)
{
if (CE_BYTE(ent, netvar.bDistributed))
{
@ -1132,71 +1270,8 @@ void _FASTCALL ProcessEntity(CachedEntity *ent)
{
AddEntityString(ent, mvm_money_str);
}
// Other item esp
}
else if (itemtype != ITEM_NONE && item_esp)
{
// Health pack esp
if (item_health_packs && (itemtype >= ITEM_HEALTH_SMALL && itemtype <= ITEM_HEALTH_LARGE || itemtype == ITEM_HL_BATTERY))
{
if (itemtype == ITEM_HEALTH_SMALL)
AddEntityString(ent, health_small_str);
if (itemtype == ITEM_HEALTH_MEDIUM)
AddEntityString(ent, health_medium_str);
if (itemtype == ITEM_HEALTH_LARGE)
AddEntityString(ent, health_big_str);
if (itemtype == ITEM_HL_BATTERY)
AddEntityString(ent, hl_battery_str);
// TF2C Adrenaline esp
}
else if (item_adrenaline && itemtype == ITEM_TF2C_PILL)
{
AddEntityString(ent, pill_str);
// Ammo pack esp
}
else if (item_ammo_packs && itemtype >= ITEM_AMMO_SMALL && itemtype <= ITEM_AMMO_LARGE)
{
if (itemtype == ITEM_AMMO_SMALL)
AddEntityString(ent, ammo_small_str);
if (itemtype == ITEM_AMMO_MEDIUM)
AddEntityString(ent, ammo_medium_str);
if (itemtype == ITEM_AMMO_LARGE)
AddEntityString(ent, ammo_big_str);
// Powerup esp
}
else if (item_powerups && itemtype >= ITEM_POWERUP_FIRST && itemtype <= ITEM_POWERUP_LAST)
{
AddEntityString(ent, std::string(powerups[itemtype - ITEM_POWERUP_FIRST])); //User should already know it's a pickup
// TF2C weapon spawner esp
}
else if (item_weapon_spawners && itemtype >= ITEM_TF2C_W_FIRST && itemtype <= ITEM_TF2C_W_LAST)
{
AddEntityString(ent, std::string(tf2c_weapon_names[itemtype - ITEM_TF2C_W_FIRST]) + " SPAWNER");
if (CE_BYTE(ent, netvar.bRespawning))
AddEntityString(ent, tf2c_spawner_respawn_str);
// Halloween spell esp
}
else if (item_spellbooks && (itemtype == ITEM_SPELL || itemtype == ITEM_SPELL_RARE))
{
if (itemtype == ITEM_SPELL)
{
AddEntityString(ent, spell_str, colors::green);
}
else
{
AddEntityString(ent, rare_spell_str, colors::FromRGBA8(139, 31, 221, 255));
}
}
// Building esp
}
// Building esp
else if (ent->m_Type() == ENTITY_BUILDING && buildings)
{

View File

@ -776,6 +776,14 @@ static InitRoutine init([]() {
// Patch!
patch_scoreboardcolor1->Patch();
patch_scoreboardcolor2->Patch();
EC::Register(
EC::LevelInit,
[]() {
// Remove truce status
setTruce(false);
},
"truce_reset");
});
} // namespace ScoreboardColoring

View File

@ -963,7 +963,7 @@ bool AmbassadorCanHeadshot()
}
static std::random_device random_device;
static std::mt19937 engine{random_device()};
static std::mt19937 engine{ random_device() };
float RandFloatRange(float min, float max)
{
@ -1930,3 +1930,13 @@ bool HookNetvar(std::vector<std::string> path, ProxyFnHook &hook, RecvVarProxyFn
}
return false;
}
static bool is_truce_active = false;
bool isTruce()
{
return is_truce_active;
}
void setTruce(bool status)
{
is_truce_active = status;
}

View File

@ -120,6 +120,22 @@ DEFINE_HOOKED_METHOD(DispatchUserMessage, bool, void *this_, int type, bf_read &
buf.Seek(0);
break;
}
// Hud message
case 26:
{
// Hud message type
auto message_type = buf.ReadByte();
// Truce activated
if (message_type == 26)
setTruce(true);
// Truce deactivated
else if (message_type == 27)
setTruce(false);
buf.Seek(0);
break;
}
case 12:
if (hacks::shared::catbot::anti_motd && hacks::shared::catbot::catbotmode)
{

View File

@ -34,6 +34,8 @@ ItemManager::ItemManager() : mapper()
RegisterModelMapping("models/items/ammopack_small_bday.mdl", ITEM_AMMO_SMALL);
RegisterModelMapping("models/items/ammopack_medium_bday.mdl", ITEM_AMMO_MEDIUM);
RegisterModelMapping("models/items/ammopack_large_bday.mdl", ITEM_AMMO_LARGE);
// Crumpkin
RegisterModelMapping("models/props_halloween/pumpkin_loot.mdl", ITEM_CRUMPKIN);
// == POWERUPS
RegisterModelMapping("models/pickups/pickup_powerup_haste.mdl", ITEM_POWERUP_HASTE);
@ -71,7 +73,17 @@ ItemManager::ItemManager() : mapper()
RegisterModelMapping("models/props_halloween/hwn_spellbook_upright_major.mdl", ITEM_SPELL_RARE);
RegisterModelMapping("models/items/crystal_ball_pickup_major.mdl", ITEM_SPELL_RARE);
RegisterSpecialMapping([](CachedEntity *ent) -> bool { return ent->m_iClassID() == CL_CLASS(CTFAmmoPack); }, ITEM_AMMO_MEDIUM);
// == GHOSTS
RegisterModelMapping("models/props_halloween/ghost.mdl", HALLOWEEN_GHOST);
RegisterModelMapping("models/props_halloween/ghost_no_hat_red.mdl", HALLOWEEN_GHOST_NOHAT_RED);
RegisterModelMapping("models/props_halloween/ghost_no_hat.mdl", HALLOWEEN_GHOST_NOHAT);
// == BOMBS
RegisterModelMapping("models/props_laughter/balloonbomb.mdl", BOMB_BALLOONBOMB);
RegisterModelMapping("models/props_coast/wooden_barrel.mdl", BOMB_WOODENBARREL);
RegisterModelMapping("models/props_invasion/props_alien/walker_explode.mdl", BOMB_WALKEREXPLODE);
RegisterSpecialMapping([](CachedEntity *ent) -> bool { return ent->m_iClassID() == CL_CLASS(CTFAmmoPack) && g_ItemManager.mapper.GetItemType(ent) != ITEM_CRUMPKIN; }, ITEM_AMMO_MEDIUM);
RegisterModelMapping("models/items/medkit_overheal.mdl", ITEM_TF2C_PILL);
// TF2C spawners