diff --git a/data/menu/nullifiedcat/visuals/esp.xml b/data/menu/nullifiedcat/visuals/esp.xml
index 2fbf941c..d95795ec 100755
--- a/data/menu/nullifiedcat/visuals/esp.xml
+++ b/data/menu/nullifiedcat/visuals/esp.xml
@@ -17,14 +17,17 @@
-
+
-
+
+
+
+
diff --git a/include/core/netvars.hpp b/include/core/netvars.hpp
index be4fb062..47b531be 100644
--- a/include/core/netvars.hpp
+++ b/include/core/netvars.hpp
@@ -202,6 +202,7 @@ public:
offset_t m_iPlayerLevel_Resource;
offset_t m_iPlayerIndex;
+ offset_t m_hTargetPlayer;
};
extern NetVars netvar;
diff --git a/include/entitycache.hpp b/include/entitycache.hpp
index a4dcd27e..7785111d 100644
--- a/include/entitycache.hpp
+++ b/include/entitycache.hpp
@@ -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;
diff --git a/include/enums.hpp b/include/enums.hpp
index d9bb8c1b..7a0e9894 100755
--- a/include/enums.hpp
+++ b/include/enums.hpp
@@ -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
-};
\ No newline at end of file
+};
diff --git a/include/helpers.hpp b/include/helpers.hpp
index 129bb0cd..5a6638d6 100644
--- a/include/helpers.hpp
+++ b/include/helpers.hpp
@@ -227,3 +227,5 @@ template std::string format(const Args &... args)
extern const std::string classes[10];
extern const char *powerups[POWERUP_COUNT];
+bool isTruce();
+void setTruce(bool status);
diff --git a/include/itemtypes.hpp b/include/itemtypes.hpp
index 306abd5f..7c657bfb 100644
--- a/include/itemtypes.hpp
+++ b/include/itemtypes.hpp
@@ -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,
diff --git a/include/sdk/CGameRules.h b/include/sdk/CGameRules.h
index 770781ff..1ffa240a 100755
--- a/include/sdk/CGameRules.h
+++ b/include/sdk/CGameRules.h
@@ -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
};
diff --git a/src/PlayerTools.cpp b/src/PlayerTools.cpp
index a8f15b70..64ecc308 100644
--- a/src/PlayerTools.cpp
+++ b/src/PlayerTools.cpp
@@ -49,8 +49,15 @@ bool shouldTarget(CachedEntity *entity)
return false;
if (HasCondition(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;
}
diff --git a/src/core/netvars.cpp b/src/core/netvars.cpp
index 84e54551..7bee11ed 100644
--- a/src/core/netvars.cpp
+++ b/src/core/netvars.cpp
@@ -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())
{
diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp
index b0ceeb5f..ccc81799 100644
--- a/src/hacks/Aimbot.cpp
+++ b/src/hacks/Aimbot.cpp
@@ -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();
diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp
index 60d69c2b..ddc27d38 100644
--- a/src/hacks/ESP.cpp
+++ b/src/hacks/ESP.cpp
@@ -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)
{
diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp
index 4a259e07..9c65662e 100644
--- a/src/hacks/Misc.cpp
+++ b/src/hacks/Misc.cpp
@@ -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
diff --git a/src/helpers.cpp b/src/helpers.cpp
index 3c908572..730ef5b7 100644
--- a/src/helpers.cpp
+++ b/src/helpers.cpp
@@ -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 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;
+}
diff --git a/src/hooks/DispatchUserMessage.cpp b/src/hooks/DispatchUserMessage.cpp
index 3d4fedc2..5b75cf53 100644
--- a/src/hooks/DispatchUserMessage.cpp
+++ b/src/hooks/DispatchUserMessage.cpp
@@ -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)
{
diff --git a/src/itemtypes.cpp b/src/itemtypes.cpp
index 2880918b..d29b5653 100644
--- a/src/itemtypes.cpp
+++ b/src/itemtypes.cpp
@@ -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