diff --git a/src/Effects/effect.cpp b/src/Effects/effect.cpp index e707195..802f751 100644 --- a/src/Effects/effect.cpp +++ b/src/Effects/effect.cpp @@ -2,14 +2,14 @@ #include "../script.h" std::vector Effect::WeaponNames = std::vector(); -std::vector Effect::WeaponHashes = std::vector(); +std::vector Effect::WeaponHashes = std::vector(); std::vector Effect::weatherNames = std::vector(); -std::vector Effect::weatherHashes = std::vector(); +std::vector Effect::weatherHashes = std::vector(); Effect::Effect() { - internalTimer = 0; + internalTimer = {}; } Effect::~Effect() @@ -18,12 +18,12 @@ Effect::~Effect() void Effect::OnActivate() { - internalTimer = 0; + internalTimer = {}; } void Effect::OnDeactivate() { - internalTimer = 0; + internalTimer = {}; } void Effect::OnTick() @@ -32,14 +32,19 @@ void Effect::OnTick() bool Effect::TimerTick(uint32_t maxMs) { - internalTimer += ChaosMod::GetDeltaTime(); + return TimerTick(maxMs, 0); +} - if (internalTimer >= maxMs) +bool Effect::TimerTick(uint32_t maxMs, uint32_t timerIndex) +{ + internalTimer[timerIndex] += ChaosMod::GetDeltaTime(); + + if (internalTimer[timerIndex] >= maxMs) { - internalTimer = internalTimer % maxMs; + internalTimer[timerIndex] = internalTimer[timerIndex] % maxMs; return true; } - + return false; } @@ -49,9 +54,9 @@ void LoadModel(Hash model) //{ // return; //} - + STREAMING::REQUEST_MODEL(model, true); - + while (!STREAMING::HAS_MODEL_LOADED(model)) { WAIT(0); @@ -60,112 +65,51 @@ void LoadModel(Hash model) void InitWeaponHashes() { - Effect::WeaponNames = { - "WEAPON_REPEATER_CARBINE", - "WEAPON_REVOLVER_CATTLEMAN", - "WEAPON_REVOLVER_CATTLEMAN_JOHN", - "WEAPON_REVOLVER_CATTLEMAN_MEXICAN", - "WEAPON_REVOLVER_CATTLEMAN_PIG", - "WEAPON_REVOLVER_DOUBLEACTION_MICAH", - "WEAPON_REVOLVER_DOUBLEACTION_GAMBLER", - "WEAPON_REVOLVER_DOUBLEACTION_EXOTIC", - "WEAPON_REVOLVER_SCHOFIELD_CALLOWAY", - "WEAPON_REVOLVER_SCHOFIELD_GOLDEN", - "WEAPON_REVOLVER_DOUBLEACTION", - "WEAPON_REVOLVER_SCHOFIELD", - "WEAPON_REVOLVER_LEMAT", - "WEAPON_PISTOL_VOLCANIC", - "WEAPON_PISTOL_M1899", - "WEAPON_PISTOL_MAUSER", - "WEAPON_PISTOL_MAUSER_DRUNK", - "WEAPON_PISTOL_SEMIAUTO", - "WEAPON_REPEATER_WINCHESTER", - "WEAPON_REPEATER_HENRY", - "WEAPON_RIFLE_VARMINT", - "WEAPON_RIFLE_SPRINGFIELD", - "WEAPON_RIFLE_BOLTACTION", - "WEAPON_SHOTGUN_DOUBLEBARREL", - "WEAPON_SHOTGUN_DOUBLEBARREL_EXOTIC", - "WEAPON_SHOTGUN_SAWEDOFF", - "WEAPON_SHOTGUN_REPEATING", - "WEAPON_SHOTGUN_PUMP", - "WEAPON_SHOTGUN_SEMIAUTO", - "WEAPON_SNIPERRIFLE_ROLLINGBLOCK", - "WEAPON_SNIPERRIFLE_ROLLINGBLOCK_EXOTIC", - "WEAPON_SNIPERRIFLE_CARCANO", - "WEAPON_MELEE_KNIFE", - "WEAPON_MELEE_KNIFE_JAWBONE", - "WEAPON_MELEE_KNIFE_JOHN", - "WEAPON_MELEE_KNIFE_MICAH", - "WEAPON_MELEE_KNIFE_MINER", - "WEAPON_MELEE_KNIFE_VAMPIRE", - "WEAPON_MELEE_KNIFE_CIVIL_WAR", - "WEAPON_MELEE_KNIFE_BEAR", - "WEAPON_MELEE_BROKEN_SWORD", - "WEAPON_MELEE_CLEAVER", - "WEAPON_MELEE_HATCHET", - "WEAPON_MELEE_MACHETE", - "WEAPON_MELEE_ANCIENT_HATCHET", - "WEAPON_MELEE_HATCHET_VIKING", - "WEAPON_MELEE_HATCHET_HEWING", - "WEAPON_MELEE_HATCHET_HUNTER", - "WEAPON_MELEE_HATCHET_HUNTER_RUSTED", - "WEAPON_MELEE_HATCHET_DOUBLE_BIT", - "WEAPON_MELEE_HATCHET_DOUBLE_BIT_RUSTED", - "WEAPON_THROWN_DYNAMITE", - "WEAPON_THROWN_MOLOTOV", - "WEAPON_THROWN_THROWING_KNIVES", - "WEAPON_THROWN_TOMAHAWK", - "WEAPON_THROWN_TOMAHAWK_ANCIENT", - "WEAPON_REPEATER_EVANS", - - /** Should not be removed */ - "WEAPON_BOW", - "WEAPON_KIT_CAMERA", - "WEAPON_LASSO", - "WEAPON_FISHINGROD", - "WEAPON_MELEE_LANTERN_ELECTRIC" - }; - + Effect::WeaponNames = {"WEAPON_REPEATER_CARBINE", "WEAPON_REVOLVER_CATTLEMAN", "WEAPON_REVOLVER_CATTLEMAN_JOHN", + "WEAPON_REVOLVER_CATTLEMAN_MEXICAN", "WEAPON_REVOLVER_CATTLEMAN_PIG", + "WEAPON_REVOLVER_DOUBLEACTION_MICAH", "WEAPON_REVOLVER_DOUBLEACTION_GAMBLER", + "WEAPON_REVOLVER_DOUBLEACTION_EXOTIC", "WEAPON_REVOLVER_SCHOFIELD_CALLOWAY", + "WEAPON_REVOLVER_SCHOFIELD_GOLDEN", "WEAPON_REVOLVER_DOUBLEACTION", + "WEAPON_REVOLVER_SCHOFIELD", "WEAPON_REVOLVER_LEMAT", "WEAPON_PISTOL_VOLCANIC", + "WEAPON_PISTOL_M1899", "WEAPON_PISTOL_MAUSER", "WEAPON_PISTOL_MAUSER_DRUNK", + "WEAPON_PISTOL_SEMIAUTO", "WEAPON_REPEATER_WINCHESTER", "WEAPON_REPEATER_HENRY", + "WEAPON_RIFLE_VARMINT", "WEAPON_RIFLE_SPRINGFIELD", "WEAPON_RIFLE_BOLTACTION", + "WEAPON_SHOTGUN_DOUBLEBARREL", "WEAPON_SHOTGUN_DOUBLEBARREL_EXOTIC", + "WEAPON_SHOTGUN_SAWEDOFF", "WEAPON_SHOTGUN_REPEATING", "WEAPON_SHOTGUN_PUMP", + "WEAPON_SHOTGUN_SEMIAUTO", "WEAPON_SNIPERRIFLE_ROLLINGBLOCK", + "WEAPON_SNIPERRIFLE_ROLLINGBLOCK_EXOTIC", "WEAPON_SNIPERRIFLE_CARCANO", "WEAPON_MELEE_KNIFE", + "WEAPON_MELEE_KNIFE_JAWBONE", "WEAPON_MELEE_KNIFE_JOHN", "WEAPON_MELEE_KNIFE_MICAH", + "WEAPON_MELEE_KNIFE_MINER", "WEAPON_MELEE_KNIFE_VAMPIRE", "WEAPON_MELEE_KNIFE_CIVIL_WAR", + "WEAPON_MELEE_KNIFE_BEAR", "WEAPON_MELEE_BROKEN_SWORD", "WEAPON_MELEE_CLEAVER", + "WEAPON_MELEE_HATCHET", "WEAPON_MELEE_MACHETE", "WEAPON_MELEE_ANCIENT_HATCHET", + "WEAPON_MELEE_HATCHET_VIKING", "WEAPON_MELEE_HATCHET_HEWING", "WEAPON_MELEE_HATCHET_HUNTER", + "WEAPON_MELEE_HATCHET_HUNTER_RUSTED", "WEAPON_MELEE_HATCHET_DOUBLE_BIT", + "WEAPON_MELEE_HATCHET_DOUBLE_BIT_RUSTED", "WEAPON_THROWN_DYNAMITE", "WEAPON_THROWN_MOLOTOV", + "WEAPON_THROWN_THROWING_KNIVES", "WEAPON_THROWN_TOMAHAWK", "WEAPON_THROWN_TOMAHAWK_ANCIENT", + "WEAPON_REPEATER_EVANS", + + /** Should not be removed */ + "WEAPON_BOW", "WEAPON_KIT_CAMERA", "WEAPON_LASSO", "WEAPON_FISHINGROD", + "WEAPON_MELEE_LANTERN_ELECTRIC"}; + Effect::WeaponHashes.clear(); - + for (auto name : Effect::WeaponNames) { - Effect::WeaponHashes.push_back(GAMEPLAY::GET_HASH_KEY((char*)name)); + Effect::WeaponHashes.push_back(GAMEPLAY::GET_HASH_KEY((char*) name)); } } void InitWeatherHashes() { - Effect::weatherNames = { - "SUNNY", - "MISTY", - "FOG", - "CLOUDS", - "OVERCAST", - "OVERCASTDARK", - "DRIZZLE", - "RAIN", - "THUNDER", - "THUNDERSTORM", - "HURRICANE", - "HIGHPRESSURE", - "SHOWER", - "HAIL", - "SLEET", - "SNOWCLEARING", - "SNOWLIGHT", - "SNOW", - "BLIZZARD", - "GROUNDBLIZZARD", - "WHITEOUT", - "SANDSTORM" - }; - + Effect::weatherNames = {"SUNNY", "MISTY", "FOG", "CLOUDS", "OVERCAST", "OVERCASTDARK", "DRIZZLE", "RAIN", "THUNDER", + "THUNDERSTORM", "HURRICANE", "HIGHPRESSURE", "SHOWER", "HAIL", "SLEET", "SNOWCLEARING", + "SNOWLIGHT", "SNOW", "BLIZZARD", "GROUNDBLIZZARD", "WHITEOUT", "SANDSTORM"}; + Effect::weatherHashes.clear(); - + for (auto name : Effect::weatherNames) { - Effect::weatherHashes.push_back(GAMEPLAY::GET_HASH_KEY((char*)name)); + Effect::weatherHashes.push_back(GAMEPLAY::GET_HASH_KEY((char*) name)); } } diff --git a/src/Effects/effect.h b/src/Effects/effect.h index 3cb6d11..fde1b09 100644 --- a/src/Effects/effect.h +++ b/src/Effects/effect.h @@ -1,4 +1,5 @@ #pragma once + #include #include #include @@ -6,15 +7,19 @@ #include #include #include +#include #include #define GET_HASH(str) GAMEPLAY::GET_HASH_KEY((char*)str) -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 struct LinearColor { - LinearColor() {}; + LinearColor() + { + }; + LinearColor(uint8_t _R, uint8_t _G, uint8_t _B, uint8_t _A) { R = _R; @@ -22,7 +27,7 @@ struct LinearColor B = _B; A = _A; }; - + uint8_t R = 0; uint8_t G = 0; uint8_t B = 0; @@ -30,10 +35,10 @@ struct LinearColor }; -template +template inline T Lerp(T min, T max, double alpha) { - return min + (T)(double(max - min) * alpha); + return min + (T) (double(max - min) * alpha); } struct NearbyEntities @@ -52,47 +57,52 @@ class Effect { public: Effect(); + ~Effect(); - + virtual void OnActivate(); + virtual void OnDeactivate(); - + virtual void OnTick(); - + std::string ID = ""; std::string name = ""; - + bool bTimed = false; - + /** In seconds */ uint32_t EffectDuration = 0; - + uint32_t DeactivationTime = 0; uint32_t ActivationTime = 0; - + uint32_t DisplayTime = 0; + static std::vector WeaponNames; - static std::vector WeaponHashes; - + static std::vector WeaponHashes; + static std::vector weatherNames; - static std::vector weatherHashes; - + static std::vector weatherHashes; + /** * Adds delta time to the current internal timer. * Returns whether time (maxMs) has expired or not */ bool TimerTick(uint32_t maxMs); - + + bool TimerTick(uint32_t maxMs, uint32_t timerIndex); + bool bIsMeta = false; - + bool bIsFake = false; private: - uint32_t internalTimer = 0; + std::map internalTimer = {}; }; class MetaEffect : public Effect { public: - MetaEffect() + MetaEffect() : Effect() { bIsMeta = true; bTimed = true; diff --git a/src/Effects/misc.cpp b/src/Effects/misc.cpp index 4d36cef..2e21d2c 100644 --- a/src/Effects/misc.cpp +++ b/src/Effects/misc.cpp @@ -7,27 +7,27 @@ Entity SpawnObject(Hash model) { LoadModel(model); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + Entity object = OBJECT::CREATE_OBJECT(model, vec.x, vec.y, vec.z, 1, 1, 0, 0, 1); - + ENTITY::SET_ENTITY_VISIBLE(object, true); ENTITY::SET_ENTITY_ALPHA(object, 255, true); - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(object, false, false); Entity objCopy = object; ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&objCopy); - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); - + if (ENTITY::DOES_ENTITY_EXIST(object)) { ChaosMod::propsSet.insert(object); } - + return object; } @@ -41,17 +41,17 @@ Vector3 GetRandomCoordInRange(Vector3 vec, float distance) { /** In radians */ float angle = float(rand() % 360) * (M_PI / 180.0f); - + vec.x += distance * sin(angle); vec.y += distance * cos(angle); - + return vec; } Vector3 GetRandomCoordAroundPlayer(float distance, bool bUseVelocity) { Entity entity = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(entity, false)) { entity = PED::GET_VEHICLE_PED_IS_IN(entity, false); @@ -60,46 +60,47 @@ Vector3 GetRandomCoordAroundPlayer(float distance, bool bUseVelocity) { entity = PED::GET_MOUNT(entity); } - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(entity, true, 0); - + if (bUseVelocity) { Vector3 velocity = ENTITY::GET_ENTITY_VELOCITY(entity, 0); - + vec.x += velocity.x * 2.0f; vec.y += velocity.y * 2.0f; vec.z += velocity.z * 2.0f; } - + return GetRandomCoordInRange(vec, distance); } void EffectSpawnHotchkissCannon::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerLocation = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - - static Hash model = GAMEPLAY::GET_HASH_KEY((char*)"hotchkiss_cannon"); - + + static Hash model = GAMEPLAY::GET_HASH_KEY((char*) "hotchkiss_cannon"); + LoadModel(model); - + float playerHeading = ENTITY::GET_ENTITY_HEADING(playerPed); - - Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, playerHeading, false, false, false, false); - + + Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, playerHeading, + false, false, false, false); + Vehicle vehCopy = veh; ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&vehCopy); - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); - + if (ENTITY::DOES_ENTITY_EXIST(veh)) { ChaosMod::vehsSet.insert(veh); } - + if (!PED::IS_PED_IN_ANY_VEHICLE(playerPed, true) && !PED::IS_PED_ON_MOUNT(playerPed)) { PED::SET_PED_INTO_VEHICLE(playerPed, veh, -1); @@ -109,10 +110,10 @@ void EffectSpawnHotchkissCannon::OnActivate() void EffectTeleportEverything::OnActivate() { - std::vector entities; + std::vector entities; auto nearbyPeds = GetNearbyPeds(45); auto nearbyVehs = GetNearbyVehs(10); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -120,7 +121,7 @@ void EffectTeleportEverything::OnActivate() entities.push_back(ped); } } - + for (auto veh : nearbyVehs) { if (ENTITY::DOES_ENTITY_EXIST(veh)) @@ -128,28 +129,28 @@ void EffectTeleportEverything::OnActivate() entities.push_back(veh); } } - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerCoord = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + for (auto entity : entities) { //ENTITY::SET_ENTITY_AS_MISSION_ENTITY(entity, true, true); ENTITY::SET_ENTITY_COORDS(entity, playerCoord.x, playerCoord.y, playerCoord.z, 0, 0, 0, 0); - + if (ENTITY::IS_ENTITY_A_PED(entity)) { PED::SET_PED_TO_RAGDOLL(entity, 3000, 3000, 0, true, true, false); } } - + props.clear(); oldPropsCoords.clear(); - + int* objects = new int[10]; - + int32_t foundObjects = worldGetAllObjects(objects, 10); - + for (int32_t i = 0; i < foundObjects; i++) { Entity entity = objects[i]; @@ -163,7 +164,7 @@ void EffectTeleportEverything::OnActivate() ENTITY::SET_ENTITY_COORDS(entity, playerCoord.x, playerCoord.y, playerCoord.z, 0, 0, 0, 0); } } - + delete[] objects; } @@ -172,7 +173,7 @@ void EffectTeleportEverything::OnDeactivate() for (int32_t i = 0; i < props.size(); i++) { Entity entity = props[i]; - + if (ENTITY::DOES_ENTITY_EXIST(entity)) { Vector3 oldCoord = oldPropsCoords[i]; @@ -181,7 +182,7 @@ void EffectTeleportEverything::OnDeactivate() ENTITY::SET_ENTITY_COORDS(entity, oldCoord.x, oldCoord.y, oldCoord.z, 0, 0, 0, 0); } } - + props.clear(); oldPropsCoords.clear(); } @@ -189,17 +190,17 @@ void EffectTeleportEverything::OnDeactivate() void EffectSnowstorm::OnActivate() { Effect::OnActivate(); - + GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); - static Hash weather = GAMEPLAY::GET_HASH_KEY((char*)"WHITEOUT"); + static Hash weather = GAMEPLAY::GET_HASH_KEY((char*) "WHITEOUT"); GAMEPLAY::SET_WEATHER_TYPE(weather, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - + GAMEPLAY::SET_WIND_SPEED(50.0f); - + /** Set SNOW_LEVEL to -1 (enabled) */ invoke(0xF6BEE7E80EC5CA40, -1); - + /** Set SNOW_COVERAGE_TYPE */ invoke(0xF02A9C330BBFC5C7, 2); } @@ -207,17 +208,17 @@ void EffectSnowstorm::OnActivate() void EffectSnowstorm::OnDeactivate() { Effect::OnDeactivate(); - + GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); - static Hash weather = GAMEPLAY::GET_HASH_KEY((char*)"SUNNY"); + static Hash weather = GAMEPLAY::GET_HASH_KEY((char*) "SUNNY"); GAMEPLAY::SET_WEATHER_TYPE(weather, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - + GAMEPLAY::SET_WIND_SPEED(0.0f); - + /** Set SNOW_LEVEL to 1 (disabled) */ invoke(0xF6BEE7E80EC5CA40, 1); - + /** Set SNOW_COVERAGE_TYPE */ invoke(0xF02A9C330BBFC5C7, 0); } @@ -225,22 +226,22 @@ void EffectSnowstorm::OnDeactivate() void EffectThunderstorm::OnActivate() { GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); - static Hash weather = GAMEPLAY::GET_HASH_KEY((char*)"THUNDERSTORM"); + static Hash weather = GAMEPLAY::GET_HASH_KEY((char*) "THUNDERSTORM"); GAMEPLAY::SET_WEATHER_TYPE(weather, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - + GAMEPLAY::SET_WIND_SPEED(50.0f); } void EffectThunderstorm::OnDeactivate() { Effect::OnDeactivate(); - + GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); - static Hash weather = GAMEPLAY::GET_HASH_KEY((char*)"SUNNY"); + static Hash weather = GAMEPLAY::GET_HASH_KEY((char*) "SUNNY"); GAMEPLAY::SET_WEATHER_TYPE(weather, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - + GAMEPLAY::SET_WIND_SPEED(0.0f); } @@ -260,7 +261,7 @@ void EffectGiantPeds::OnDeactivate() invoke(0x25ACFC650B65C538, ped, 1.0f); } } - + giantPeds.clear(); } @@ -275,14 +276,14 @@ void EffectGiantPeds::OnTick() void EffectGiantPeds::SetScale(float scale) { auto nearbyPeds = GetNearbyPeds(45); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) { /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, ped, scale); - + if (scale != 1.0f) { giantPeds.insert(ped); @@ -294,34 +295,34 @@ void EffectGiantPeds::SetScale(float scale) void EffectAllPedsWannaKillPlayer::OnActivate() { Hash enemyGroup; - PED::ADD_RELATIONSHIP_GROUP((char*)"_CHAOS_ENEMY_PEDS", &enemyGroup); - static Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*)"PLAYER"); - + PED::ADD_RELATIONSHIP_GROUP((char*) "_CHAOS_ENEMY_PEDS", &enemyGroup); + static Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*) "PLAYER"); + PED::SET_RELATIONSHIP_BETWEEN_GROUPS(5, enemyGroup, playerGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(5, playerGroup, enemyGroup); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + auto nearbyPeds = GetNearbyPeds(45); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) { - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_REVOLVER_SCHOFIELD"); + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_REVOLVER_SCHOFIELD"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(ped, weaponHash, 100); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); - + PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, enemyGroup); - + /** BF_CanFightArmedPedsWhenNotArmed */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 5, true); /** BF_AlwaysFight */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 46, true); - + PED::SET_PED_FLEE_ATTRIBUTES(ped, 2, true); - + AI::TASK_COMBAT_PED(ped, playerPed, 0, 16); } } @@ -329,9 +330,9 @@ void EffectAllPedsWannaKillPlayer::OnActivate() void EffectAllPedsWannaKillPlayer::OnDeactivate() { - static Hash enemyGroup = GAMEPLAY::GET_HASH_KEY((char*)"_CHAOS_ENEMY_PEDS"); - static Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*)"PLAYER"); - + static Hash enemyGroup = GAMEPLAY::GET_HASH_KEY((char*) "_CHAOS_ENEMY_PEDS"); + static Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*) "PLAYER"); + PED::SET_RELATIONSHIP_BETWEEN_GROUPS(3, enemyGroup, playerGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(3, playerGroup, enemyGroup); } @@ -342,12 +343,12 @@ void EffectAllPedsWannaKillPlayer::OnTick() { return; } - static Hash enemyGroup = GAMEPLAY::GET_HASH_KEY((char*)"_CHAOS_ENEMY_PEDS"); - + static Hash enemyGroup = GAMEPLAY::GET_HASH_KEY((char*) "_CHAOS_ENEMY_PEDS"); + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + auto nearbyPeds = GetNearbyPeds(45); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -356,16 +357,16 @@ void EffectAllPedsWannaKillPlayer::OnTick() //WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 100, 1, 0x2cd419dc); //WEAPON::SET_PED_AMMO(ped, weaponHash, 100); //WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); - + /** BF_CanFightArmedPedsWhenNotArmed */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 5, true); /** BF_AlwaysFight */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 46, true); - + PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, enemyGroup); - + PED::SET_PED_FLEE_ATTRIBUTES(ped, 2, true); - + AI::TASK_COMBAT_PED(ped, playerPed, 0, 16); } } @@ -375,9 +376,9 @@ void EffectRagdollEveryone::OnActivate() { auto nearbyPeds = GetNearbyPeds(100); Ped playerPed = PLAYER::PLAYER_PED_ID(); - + nearbyPeds.push_back(playerPed); - + for (Ped ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -385,9 +386,9 @@ void EffectRagdollEveryone::OnActivate() FixEntityInCutscene(ped); } } - + WAIT(75); - + for (Ped ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -401,15 +402,15 @@ void EffectLaunchPedsUp::OnActivate() { auto nearbyPeds = GetNearbyPeds(100); Ped playerPed = PLAYER::PLAYER_PED_ID(); - + bool bPlayerOnMount = PED::IS_PED_ON_MOUNT(playerPed); Ped playerMount; - + if (bPlayerOnMount) { playerMount = PED::GET_MOUNT(playerPed); } - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped) && (!bPlayerOnMount || playerMount != ped)) @@ -417,29 +418,29 @@ void EffectLaunchPedsUp::OnActivate() FixEntityInCutscene(ped); } } - + WAIT(75); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped) && (!bPlayerOnMount || playerMount != ped)) { PED::SET_PED_TO_RAGDOLL(ped, 5000, 5000, 0, true, true, false); Vector3 entityVelocity = ENTITY::GET_ENTITY_VELOCITY(ped, 0); - + ENTITY::SET_ENTITY_VELOCITY(ped, entityVelocity.x, entityVelocity.y, 35.0f); } } - + } void EffectInvertedGravity::OnActivate() { auto nearbyPeds = GetNearbyPeds(100); entities.clear(); - + nearbyPeds.push_back(PLAYER::PLAYER_PED_ID()); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -453,35 +454,35 @@ void EffectInvertedGravity::OnActivate() void EffectInvertedGravity::OnTick() { Effect::OnTick(); - + if (TimerTick(1000)) { entities.clear(); auto nearbyPeds = GetNearbyPeds(45); auto nearbyVehs = GetNearbyVehs(45); auto nearbyProps = GetNearbyProps(45); - + for (auto ped : nearbyPeds) { entities.insert(ped); } - + for (auto veh : nearbyVehs) { entities.insert(veh); } - + for (auto prop : nearbyProps) { ENTITY::SET_ENTITY_DYNAMIC(prop, true); ENTITY::SET_ENTITY_HAS_GRAVITY(prop, true); entities.insert(prop); } - - + + entities.insert(PLAYER::PLAYER_PED_ID()); } - + for (auto entity : entities) { if (ENTITY::DOES_ENTITY_EXIST(entity)) @@ -499,24 +500,24 @@ void EffectInvertedGravity::OnTick() void EffectDoomsday::OnActivate() { GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); - static Hash weather = GAMEPLAY::GET_HASH_KEY((char*)"THUNDERSTORM"); + static Hash weather = GAMEPLAY::GET_HASH_KEY((char*) "THUNDERSTORM"); GAMEPLAY::SET_WEATHER_TYPE(weather, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - + GAMEPLAY::SET_WIND_SPEED(350.0f); - GRAPHICS::SET_TIMECYCLE_MODIFIER((char*)"EagleEyeTest"); + GRAPHICS::SET_TIMECYCLE_MODIFIER((char*) "EagleEyeTest"); GRAPHICS::SET_TIMECYCLE_MODIFIER_STRENGTH(1.0f); } void EffectDoomsday::OnDeactivate() { GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); - static Hash weather = GAMEPLAY::GET_HASH_KEY((char*)"SUNNY"); + static Hash weather = GAMEPLAY::GET_HASH_KEY((char*) "SUNNY"); GAMEPLAY::SET_WEATHER_TYPE(weather, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - + GAMEPLAY::SET_WIND_SPEED(0.0f); - + GRAPHICS::CLEAR_TIMECYCLE_MODIFIER(); GRAPHICS::SET_TIMECYCLE_MODIFIER_STRENGTH(1.0f); } @@ -529,11 +530,11 @@ void EffectDoomsday::OnTick() auto nearbyPeds = GetNearbyPeds(45); auto nearbyVehs = GetNearbyVehs(45); auto nearbyProps = GetNearbyProps(20); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + nearbyPeds.push_back(playerPed); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -542,49 +543,49 @@ void EffectDoomsday::OnTick() { FixEntityInCutscene(ped); } - + PED::SET_PED_TO_RAGDOLL(ped, 1000, 1000, 0, true, true, false); entities.insert(ped); } } - + for (auto veh : nearbyVehs) { entities.insert(veh); } - + for (auto prop : nearbyProps) { ENTITY::SET_ENTITY_DYNAMIC(prop, true); ENTITY::SET_ENTITY_HAS_GRAVITY(prop, true); entities.insert(prop); } - - + + Vector3 vec = GetRandomCoordAroundPlayer(rand() % 100); - + /** _FORCE_LIGHTNING_FLASH_AT_COORDS */ invoke(0x67943537D179597C, vec.x, vec.y, vec.z); - + randomDirection.x = float((rand() % 5) + 1) * (rand() % 2 ? -1.0f : 1.0f); randomDirection.y = float((rand() % 5) + 1) * (rand() % 2 ? -1.0f : 1.0f); randomDirection.z = float((rand() % 5) + 1) * (rand() % 2 ? -1.0f : 1.0f); } - - + + for (auto entity : entities) { if (ENTITY::DOES_ENTITY_EXIST(entity)) { Vector3 direction; - + direction.x = float((rand() % 70) + 5); direction.y = float((rand() % 70) + 5); direction.z = float((rand() % 10) + 0); - + direction.x *= rand() % 2 ? -1.0f : 1.0f; direction.y *= rand() % 2 ? -1.0f : 1.0f; - + ENTITY::SET_ENTITY_VELOCITY(entity, direction.x, direction.y, direction.z); } } @@ -592,12 +593,12 @@ void EffectDoomsday::OnTick() void EffectPlayIntro::OnActivate() { - GRAPHICS::ANIMPOSTFX_PLAY((char*)"Title_GameIntro"); + GRAPHICS::ANIMPOSTFX_PLAY((char*) "Title_GameIntro"); } void EffectPlayIntro::OnDeactivate() { - GRAPHICS::ANIMPOSTFX_STOP((char*)"Title_GameIntro"); + GRAPHICS::ANIMPOSTFX_STOP((char*) "Title_GameIntro"); WAIT(500); PLAYER::SET_PLAYER_CONTROL(PLAYER::PLAYER_ID(), true, 0, false); UI::DISPLAY_HUD(true); @@ -614,7 +615,7 @@ void SetWeather(Hash hash) void EffectSetRandomWeather::OnActivate() { Hash weatherHash = Effect::weatherHashes[rand() % Effect::weatherHashes.size()]; - + SetWeather(weatherHash); } @@ -635,17 +636,17 @@ void EffectSetRandomTime::OnActivate() void EffectSetSunnyWeather::OnActivate() { - SetWeather(GAMEPLAY::GET_HASH_KEY((char*)"SUNNY")); + SetWeather(GAMEPLAY::GET_HASH_KEY((char*) "SUNNY")); } void EffectSetRainyWeather::OnActivate() { - SetWeather(GAMEPLAY::GET_HASH_KEY((char*)"RAIN")); + SetWeather(GAMEPLAY::GET_HASH_KEY((char*) "RAIN")); } void EffectSetRapidWeather::OnDeactivate() { - SetWeather(GAMEPLAY::GET_HASH_KEY((char*)"SUNNY")); + SetWeather(GAMEPLAY::GET_HASH_KEY((char*) "SUNNY")); } void EffectSetRapidWeather::OnTick() @@ -653,7 +654,7 @@ void EffectSetRapidWeather::OnTick() if (TimerTick(500)) { Hash weatherHash = Effect::weatherHashes[rand() % Effect::weatherHashes.size()]; - + SetWeather(weatherHash); } } @@ -666,11 +667,11 @@ void EffectEarthquake::OnTick() auto nearbyPeds = GetNearbyPeds(45); auto nearbyVehs = GetNearbyVehs(45); auto nearbyProps = GetNearbyProps(20); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + nearbyPeds.push_back(playerPed); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -683,12 +684,12 @@ void EffectEarthquake::OnTick() entities.insert(ped); } } - + for (auto veh : nearbyVehs) { entities.insert(veh); } - + for (auto prop : nearbyProps) { ENTITY::SET_ENTITY_DYNAMIC(prop, true); @@ -696,7 +697,7 @@ void EffectEarthquake::OnTick() entities.insert(prop); } } - + for (auto entity : entities) { if (ENTITY::DOES_ENTITY_EXIST(entity)) @@ -705,11 +706,11 @@ void EffectEarthquake::OnTick() randomDirection.x = float((rand() % 5) + 1); randomDirection.y = float((rand() % 5) + 1); randomDirection.z = float((rand() % 7) + 7); - + randomDirection.x *= rand() % 2 ? -1.0f : 1.0f; randomDirection.y *= rand() % 2 ? -1.0f : 1.0f; randomDirection.z *= rand() % 2 ? -1.0f : 0.5f; - + ENTITY::SET_ENTITY_VELOCITY(entity, randomDirection.x, randomDirection.y, randomDirection.z); } } @@ -724,7 +725,7 @@ void EffectEveryoneIsInvincible::OnDeactivate() ENTITY::SET_ENTITY_INVINCIBLE(ped, false); } } - + entities.clear(); } @@ -734,22 +735,22 @@ void EffectEveryoneIsInvincible::OnTick() { return; } - + auto peds = GetNearbyPeds(45); - + peds.push_back(PLAYER::PLAYER_PED_ID()); - + for (auto ped : peds) { ENTITY::SET_ENTITY_INVINCIBLE(ped, true); - + entities.insert(ped); } } void Effect120FOV::OnActivate() { - this->cam = CAM::CREATE_CAM((char*)"DEFAULT_SCRIPTED_CAMERA", 1); + this->cam = CAM::CREATE_CAM((char*) "DEFAULT_SCRIPTED_CAMERA", 1); CAM::RENDER_SCRIPT_CAMS(true, true, 500, 1, 1, 1); } @@ -764,23 +765,24 @@ void Effect120FOV::OnDeactivate() void Effect120FOV::OnTick() { CAM::SET_CAM_ACTIVE(this->cam, true); - + Vector3 camCoord = CAM::GET_GAMEPLAY_CAM_COORD(); Vector3 camRotation = CAM::GET_GAMEPLAY_CAM_ROT(2); - CAM::SET_CAM_PARAMS(this->cam, camCoord.x, camCoord.y, camCoord.z, camRotation.x, camRotation.y, camRotation.z, 120, 0, 0, 2, 0, 0, 0); + CAM::SET_CAM_PARAMS(this->cam, camCoord.x, camCoord.y, camCoord.z, camRotation.x, camRotation.y, camRotation.z, 120, + 0, 0, 2, 0, 0, 0); } void EffectIgniteNearbyPeds::OnActivate() { auto peds = GetNearbyPeds(45); - + for (auto ped : peds) { Hash pedModel = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, pedModel); - + /** Don't ignite horses */ if (!bModelIsHorse) { @@ -792,29 +794,29 @@ void EffectIgniteNearbyPeds::OnActivate() void EffectLightningOnce::OnActivate() { Vector3 vec = GetRandomCoordAroundPlayer(float((rand() % 5) + 2), false); - + /** _FORCE_LIGHTNING_FLASH_AT_COORDS */ invoke(0x67943537D179597C, vec.x, vec.y, vec.z); } -std::vector GetNearbyProps(int32_t Max) +std::vector GetNearbyProps(int32_t Max) { - std::vector propsOut; - + std::vector propsOut; + if (Max > 255) { Max = 255; } - + int* worldProps = new int[255]; - + int found = worldGetAllObjects(worldProps, 255); - + if (found < Max) { Max = found; } - + for (int32_t i = 0; i < Max; i++) { Entity prop = worldProps[i]; @@ -823,9 +825,9 @@ std::vector GetNearbyProps(int32_t Max) propsOut.push_back(prop); } } - + delete[] worldProps; - + return propsOut; } @@ -836,48 +838,48 @@ void PlayAmbientSpeech(const char* voiceDict, const char* voiceSpeech, Ped ped, const char* speechName = ""; const char* voiceName = ""; alignas(8) int v3 = 0; - alignas(8) Hash speechParamHash = GAMEPLAY::GET_HASH_KEY((char*)"speech_params_force"); + alignas(8) Hash speechParamHash = GAMEPLAY::GET_HASH_KEY((char*) "speech_params_force"); alignas(8) Entity entity; alignas(8) BOOL v6 = true; alignas(8) int v7 = 1; alignas(8) int v8 = 1; } speechData; - + speechData.v3 = speechID; - + speechData.speechName = voiceSpeech; speechData.voiceName = voiceDict; - + if (bSetEntity) { speechData.entity = ped; } - - AUDIO::_PLAY_AMBIENT_SPEECH1(ped, (char*)&speechData); + + AUDIO::_PLAY_AMBIENT_SPEECH1(ped, (char*) &speechData); } void EffectLightningEnemy::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + auto nearbyPeds = GetNearbyPeds(45); - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) { int rel = PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped, playerPed); - + /** If ped is an enemy */ if (rel == 5 || rel == 4) { Vector3 vec = ENTITY::GET_ENTITY_COORDS(ped, true, 0); - + ENTITY::SET_ENTITY_HEALTH(ped, 1, 0); - + /** _FORCE_LIGHTNING_FLASH_AT_COORDS */ invoke(0x67943537D179597C, vec.x, vec.y, vec.z); - + return; } } @@ -888,41 +890,41 @@ void EffectAltTab::OnActivate() { INPUT inputs[4] = {}; ZeroMemory(inputs, sizeof(inputs)); - + inputs[0].type = INPUT_KEYBOARD; inputs[0].ki.wVk = VK_MENU; - + inputs[1].type = INPUT_KEYBOARD; inputs[1].ki.wVk = VK_TAB; - + inputs[2].type = INPUT_KEYBOARD; inputs[2].ki.wVk = VK_TAB; inputs[2].ki.dwFlags = KEYEVENTF_KEYUP; - + inputs[3].type = INPUT_KEYBOARD; inputs[3].ki.wVk = VK_MENU; inputs[3].ki.dwFlags = KEYEVENTF_KEYUP; - + SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT)); } void EffectRemoveWeaponFromEveryone::OnActivate() { Effect::OnActivate(); - + auto peds = GetNearbyPeds(45); - + peds.push_back(PLAYER::PLAYER_PED_ID()); - + for (auto ped : peds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) { Hash pedModel = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, pedModel); - + if (!bModelIsHorse) { RemoveAllPedWeapons(ped); @@ -933,24 +935,23 @@ void EffectRemoveWeaponFromEveryone::OnActivate() void EffectSetFoggyWeather::OnActivate() { - SetWeather(GAMEPLAY::GET_HASH_KEY((char*)"FOG")); + SetWeather(GAMEPLAY::GET_HASH_KEY((char*) "FOG")); } - void EffectGhostTown::OnActivate() { Effect::OnActivate(); - + entities.clear(); } void EffectGhostTown::OnDeactivate() { Effect::OnDeactivate(); - + entities.insert(PLAYER::PLAYER_PED_ID()); - + for (auto entity : entities) { if (ENTITY::DOES_ENTITY_EXIST(entity)) @@ -958,29 +959,29 @@ void EffectGhostTown::OnDeactivate() ENTITY::SET_ENTITY_VISIBLE(entity, true); } } - + entities.clear(); } void EffectGhostTown::OnTick() { Effect::OnTick(); - + if (!TimerTick(1000)) { return; } - + auto nearbyPeds = GetNearbyPeds(40); auto nearbyVehs = GetNearbyVehs(40); - + auto nearbyEntites = nearbyVehs; - + for (auto ped : nearbyPeds) { nearbyEntites.push_back(ped); } - + for (auto entity : nearbyEntites) { if (ENTITY::DOES_ENTITY_EXIST(entity)) @@ -994,35 +995,35 @@ void EffectGhostTown::OnTick() void EffectSpawnUFO::OnActivate() { TIME::SET_CLOCK_TIME(2, 0, 0); - - static Hash weatherHash = GAMEPLAY::GET_HASH_KEY((char*)"FOG"); - + + static Hash weatherHash = GAMEPLAY::GET_HASH_KEY((char*) "FOG"); + GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); GAMEPLAY::SET_WEATHER_TYPE(weatherHash, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - + movesCount = 0; this->ufo = SpawnObject(0xC92962E3); ENTITY::SET_ENTITY_DYNAMIC(ufo, true); ENTITY::SET_ENTITY_HAS_GRAVITY(ufo, true); heading = 0.0f; - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(ufo, true, 1); - + vec.z += 2.0f; - + ENTITY::SET_ENTITY_COORDS(ufo, vec.x, vec.y, vec.z, false, false, false, false); - + static Hash blipHash = GET_HASH("BLIP_STYLE_FRIENDLY"); - + /** BLIP_ADD_FOR_ENTITY */ Blip blip = RADAR::_0x23F74C2FDA6E7C61(blipHash, ufo); - - - GRAPHICS::SET_TIMECYCLE_MODIFIER((char*)"PLayerSpottedDark"); + + + GRAPHICS::SET_TIMECYCLE_MODIFIER((char*) "PLayerSpottedDark"); GRAPHICS::SET_TIMECYCLE_MODIFIER_STRENGTH(1.0f); - - AUDIO::_0x6FB1DA3CA9DA7D90((Any*)"Loop_A", ufo, (Any*)"Ufos_Sounds", 0, 0, 0); + + AUDIO::_0x6FB1DA3CA9DA7D90((Any*) "Loop_A", ufo, (Any*) "Ufos_Sounds", 0, 0, 0); } void EffectSpawnUFO::OnTick() @@ -1031,30 +1032,30 @@ void EffectSpawnUFO::OnTick() { return; } - + ENTITY::SET_ENTITY_ROTATION(ufo, 0.0f, 0.0f, 0.0f, 2, 0); - + heading += ChaosMod::GetDeltaTimeSeconds() * 2000.0f; - + ENTITY::SET_ENTITY_HEADING(ufo, heading); - + if (TimerTick(500) && ENTITY::DOES_ENTITY_EXIST(ufo)) { Vector3 vel; vel.x = 175.0f; vel.y = 175.0f; vel.z = 5.0f; - + vel.x *= rand() % 2 ? 1.0f : -1.0f; vel.y *= rand() % 2 ? 1.0f : -1.0f; vel.z *= rand() % 2 ? 1.0f : -1.0f; - + if (movesCount % 2) { auto nearbyPeds = GetNearbyPeds(50); nearbyPeds.push_back(PLAYER::PLAYER_PED_ID()); - std::vector validPeds; - + std::vector validPeds; + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped) && PED::IS_PED_HUMAN(ped)) @@ -1062,55 +1063,55 @@ void EffectSpawnUFO::OnTick() validPeds.push_back(ped); } } - + if (validPeds.size()) { Ped ped = validPeds[rand() % validPeds.size()]; - + Vector3 pedCoord = ENTITY::GET_ENTITY_COORDS(ped, true, 1); Vector3 ufoCoord = ENTITY::GET_ENTITY_COORDS(ufo, true, 1); - + Vector3 diff = pedCoord; diff.x -= ufoCoord.x; diff.y -= ufoCoord.y; diff.z -= ufoCoord.z; - + const float squareSum = (diff.x * diff.x) + (diff.y * diff.y) + (diff.z * diff.z); const float length = sqrt(squareSum); diff.x /= length; diff.y /= length; diff.z /= length; - + const float speed = 100.0f; - + diff.x *= speed; diff.y *= speed; diff.z *= speed; - + vel = diff; } } - + movesCount++; ENTITY::SET_ENTITY_VELOCITY(ufo, vel.x, vel.y, vel.z); - + } } void EffectSpawnUFO::OnDeactivate() { Vector3 vec = ENTITY::GET_ENTITY_COORDS(ufo, true, 1); - + FIRE::ADD_EXPLOSION(vec.x, vec.y, vec.z, 27, 1.0f, true, false, 1.0f); - + ChaosMod::propsSet.erase(ufo); - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(ufo, false, false); - + OBJECT::DELETE_OBJECT(&ufo); - + ufo = 0; - + GRAPHICS::CLEAR_TIMECYCLE_MODIFIER(); GRAPHICS::SET_TIMECYCLE_MODIFIER_STRENGTH(1.0f); } @@ -1118,23 +1119,23 @@ void EffectSpawnUFO::OnDeactivate() void EffectGravityField::OnActivate() { Effect::OnActivate(); - + entities.clear(); } void EffectGravityField::OnTick() { Effect::OnTick(); - + if (TimerTick(1000)) { entities.clear(); - + auto peds = GetNearbyPeds(30); auto vehs = GetNearbyVehs(30); auto props = GetNearbyProps(20); - - + + for (auto ped : peds) { if (!PED::IS_PED_RAGDOLL(ped)) @@ -1144,12 +1145,12 @@ void EffectGravityField::OnTick() PED::SET_PED_TO_RAGDOLL(ped, 2000, 2000, 0, true, true, false); entities.insert(ped); } - + for (auto veh : vehs) { entities.insert(veh); } - + for (auto prop : props) { ENTITY::SET_ENTITY_DYNAMIC(prop, true); @@ -1157,38 +1158,38 @@ void EffectGravityField::OnTick() entities.insert(prop); } } - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Vector3 vec1 = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); vec1.z += 1.0f; - + for (auto entity : entities) { if (!ENTITY::DOES_ENTITY_EXIST(entity)) { continue; } - + Vector3 vec2 = ENTITY::GET_ENTITY_COORDS(entity, true, 0); - + Vector3 diff = vec1; diff.x -= vec2.x; diff.y -= vec2.y; diff.z -= vec2.z; - + const float squareSum = (diff.x * diff.x) + (diff.y * diff.y) + (diff.z * diff.z); const float length = sqrt(squareSum); diff.x /= length; diff.y /= length; diff.z /= length; - + const float gravityForce = 70.0f; - + diff.x *= gravityForce; diff.y *= gravityForce; diff.z *= gravityForce; - + ENTITY::APPLY_FORCE_TO_ENTITY_CENTER_OF_MASS(entity, 0, diff.x, diff.y, diff.z, false, false, true, false); } } @@ -1196,7 +1197,7 @@ void EffectGravityField::OnTick() void EffectPigWeapons::OnActivate() { Effect::OnActivate(); - + peds.clear(); pigs.clear(); pigsVelocity.clear(); @@ -1205,7 +1206,7 @@ void EffectPigWeapons::OnActivate() void EffectPigWeapons::OnDeactivate() { Effect::OnDeactivate(); - + for (auto ped : pigs) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -1214,7 +1215,7 @@ void EffectPigWeapons::OnDeactivate() PED::DELETE_PED(&ped); } } - + pigs.clear(); peds.clear(); } @@ -1222,36 +1223,36 @@ void EffectPigWeapons::OnDeactivate() void EffectPigWeapons::OnTick() { Effect::OnTick(); - + if (TimerTick(2000)) { peds.clear(); auto nearbyPeds = GetNearbyPeds(20); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + nearbyPeds.push_back(playerPed); - + for (auto ped : nearbyPeds) { peds.insert(ped); } } - - - static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_UNARMED"); - static Hash pigSkin = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Pig_01"); - + + + static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_UNARMED"); + static Hash pigSkin = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Pig_01"); + bool bModelLoaded = false; - + uint32_t timeNow = GetTickCount(); - + for (uint32_t i = 0; i < pigsVelocity.size(); i++) { auto pig = pigsVelocity[i]; if (timeNow > pig.maxTick) { - + pigsVelocity.erase(pigsVelocity.begin() + i); i--; continue; @@ -1259,66 +1260,67 @@ void EffectPigWeapons::OnTick() PED::SET_PED_TO_RAGDOLL(pig.entity, 1000, 1000, 0, true, true, false); ENTITY::SET_ENTITY_VELOCITY(pig.entity, pig.velocity.x, pig.velocity.y, pig.velocity.z); } - + for (auto ped : peds) { Hash weaponHash = 0; - + if (WEAPON::GET_CURRENT_PED_WEAPON(ped, &weaponHash, 0, 0, 0) && weaponHash == unarmed) { continue; } - + Vector3 newVec; - + bool bFoundVec = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(ped, &newVec); - + if (!PED::IS_PED_SHOOTING(ped) || !bFoundVec) { continue; } - + Vector3 pedCoord = ENTITY::GET_ENTITY_COORDS(ped, true, 0); pedCoord.z += 0.25f; - + Vector3 forwardVec = ENTITY::GET_ENTITY_FORWARD_VECTOR(ped); - + pedCoord.x += (forwardVec.x * 0.5f); pedCoord.y += (forwardVec.y * 0.5f); - + Vector3 diff = newVec; - + diff.x -= pedCoord.x; diff.y -= pedCoord.y; diff.z -= pedCoord.z; - + const float squareSum = (diff.x * diff.x) + (diff.y * diff.y) + (diff.z * diff.z); const float length = sqrt(squareSum); diff.x /= length; diff.y /= length; diff.z /= length; - + const float velocity = 50.0f; - + diff.x *= velocity; diff.y *= velocity; diff.z *= velocity; - + if (!bModelLoaded) { LoadModel(pigSkin); bModelLoaded = true; } - - Ped pig = PED::CREATE_PED(pigSkin, pedCoord.x, pedCoord.y, pedCoord.z, ENTITY::GET_ENTITY_HEADING(ped), true, 0, 0, 0); + + Ped pig = PED::CREATE_PED(pigSkin, pedCoord.x, pedCoord.y, pedCoord.z, ENTITY::GET_ENTITY_HEADING(ped), true, 0, + 0, 0); PED::SET_PED_VISIBLE(pig, true); ENTITY::SET_ENTITY_INVINCIBLE(pig, true); PED::SET_PED_CAN_RAGDOLL(pig, true); invoke(0x77FF8D35EEC6BBC4, pig, rand() % 4, false); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, pig, 0.4f); - + if (ENTITY::DOES_ENTITY_EXIST(pig)) { pigs.insert(pig); @@ -1329,9 +1331,9 @@ void EffectPigWeapons::OnTick() pedStruct.maxTick = timeNow + 500; pigsVelocity.push_back(pedStruct); } - + } - + if (bModelLoaded) { STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(pigSkin); @@ -1359,32 +1361,32 @@ void EffectRainingPigs::OnTick() { return; } - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Vector3 vec = GetRandomCoordAroundPlayer(float(rand() % 20)); - + static Hash model = GET_HASH("A_C_Pig_01"); Ped pig = SpawnPedAroundPlayer(model, false, false); - + ENTITY::SET_ENTITY_COORDS(pig, vec.x, vec.y, vec.z + 35.0f, false, false, false, false); - + ENTITY::SET_ENTITY_INVINCIBLE(pig, true); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, pig, float((rand() % 5) + 1)); - + /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, pig, rand() % 4, false); - + PED::SET_PED_TO_RAGDOLL(pig, 10000, 10000, 0, true, true, false); - + PED::_SET_PED_RAGDOLL_BLOCKING_FLAGS(pig, 512); - + ENTITY::SET_ENTITY_VELOCITY(pig, 0.0f, 0.0f, -50.0f); - + pigs.push_back(pig); - + invoke(0x22B0D0E37CCB840D, pig, playerPed, 5000.0f, -1.0f, 0, 3.0f, 0); } @@ -1398,17 +1400,17 @@ void EffectRainingPigs::OnDeactivate() PED::DELETE_PED(&pig); } } - + this->pigs.clear(); } void EffectRainbow::OnActivate() { SetWeather(GET_HASH("FOG")); - + TIME::SET_CLOCK_TIME(8, 0, 0); - - GRAPHICS::SET_TIMECYCLE_MODIFIER((char*)"rainBowMod"); + + GRAPHICS::SET_TIMECYCLE_MODIFIER((char*) "rainBowMod"); GRAPHICS::SET_TIMECYCLE_MODIFIER_STRENGTH(1.0f); } @@ -1421,9 +1423,9 @@ void EffectRainbow::OnDeactivate() void EffectGiveEveryoneRifle::OnActivate() { auto nearbyPeds = GetNearbyPeds(50); - + nearbyPeds.push_back(PLAYER::PLAYER_PED_ID()); - + for (auto ped : nearbyPeds) { if (PED::IS_PED_HUMAN(ped)) @@ -1439,34 +1441,34 @@ void EffectGiveEveryoneRifle::OnActivate() void EffectTimelapse::OnActivate() { SetWeather(GET_HASH("SUNNY")); - + int hours = TIME::GET_CLOCK_HOURS(); int minutes = TIME::GET_CLOCK_MINUTES(); int seconds = TIME::GET_CLOCK_SECONDS(); - + totalSeconds = (hours * 3600) + (minutes * 60) + seconds; } void EffectTimelapse::OnTick() { totalSeconds += ChaosMod::GetDeltaTimeSeconds() * 10000.0f; - + static float maxSeconds = float(24 * 60 * 60); - + totalSeconds = fmod(totalSeconds, maxSeconds); - + int totalSecondsInt = int(totalSeconds); - + static int secondsInMinute = 60; static int secondsInHour = 60 * 60; - + int hours = totalSecondsInt / secondsInHour; int minutes = (totalSecondsInt % secondsInHour) / secondsInMinute; int seconds = (totalSecondsInt % secondsInHour) % secondsInMinute; - + TIME::SET_CLOCK_TIME(hours, minutes, seconds); - - GRAPHICS::SET_TIMECYCLE_MODIFIER((char*)"SkyTimelapses01"); + + GRAPHICS::SET_TIMECYCLE_MODIFIER((char*) "SkyTimelapses01"); GRAPHICS::SET_TIMECYCLE_MODIFIER_STRENGTH(1.0f); } @@ -1491,18 +1493,18 @@ void EffectInsaneGravity::OnTick() if (TimerTick(1000)) { entities.clear(); - + auto peds = GetNearbyPeds(50); Ped playerPed = PLAYER::PLAYER_PED_ID(); peds.push_back(playerPed); auto vehs = GetNearbyVehs(20); auto props = GetNearbyProps(20); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, false)) { vehs.push_back(PED::GET_VEHICLE_PED_IS_IN(playerPed, false)); } - + for (auto ped : peds) { if (!PED::IS_PED_RAGDOLL(ped)) @@ -1513,18 +1515,18 @@ void EffectInsaneGravity::OnTick() PED::SET_PED_TO_RAGDOLL(ped, 5000, 5000, 0, true, true, false); entities.insert(ped); } - + for (auto veh : vehs) { entities.insert(veh); } - + for (auto prop : props) { entities.insert(prop); } } - + for (auto entity : entities) { if (ENTITY::DOES_ENTITY_EXIST(entity)) @@ -1538,7 +1540,7 @@ void EffectInsaneGravity::OnTick() void EffectUpsideDownCamera::OnActivate() { - this->cam = CAM::CREATE_CAM((char*)"DEFAULT_SCRIPTED_CAMERA", 1); + this->cam = CAM::CREATE_CAM((char*) "DEFAULT_SCRIPTED_CAMERA", 1); CAM::RENDER_SCRIPT_CAMS(true, true, 500, 1, 1, 1); } @@ -1553,13 +1555,14 @@ void EffectUpsideDownCamera::OnDeactivate() void EffectUpsideDownCamera::OnTick() { CAM::SET_CAM_ACTIVE(this->cam, true); - + Vector3 camCoord = CAM::GET_GAMEPLAY_CAM_COORD(); Vector3 camRotation = CAM::GET_GAMEPLAY_CAM_ROT(2); camRotation.y = 180.0f; camRotation.x = 0.0f; float fov = CAM::GET_GAMEPLAY_CAM_FOV(); - CAM::SET_CAM_PARAMS(this->cam, camCoord.x, camCoord.y, camCoord.z, camRotation.x, camRotation.y, camRotation.z, fov, 0, 0, 2, 0, 0, 0); + CAM::SET_CAM_PARAMS(this->cam, camCoord.x, camCoord.y, camCoord.z, camRotation.x, camRotation.y, camRotation.z, fov, + 0, 0, 2, 0, 0, 0); } void EffectOneHitKO::OnActivate() @@ -1573,14 +1576,14 @@ void EffectOneHitKO::OnTick() { auto nearbyPeds = GetNearbyPeds(50); nearbyPeds.push_back(PLAYER::PLAYER_PED_ID()); - + for (auto ped : nearbyPeds) { if (!peds.contains(ped)) { peds.insert(ped); } - + if (!PED::IS_PED_DEAD_OR_DYING(ped, 1)) { ENTITY::SET_ENTITY_HEALTH(ped, 1, 0); @@ -1596,20 +1599,20 @@ void EffectOneHitKO::OnDeactivate() if (ENTITY::DOES_ENTITY_EXIST(ped) && !ENTITY::IS_ENTITY_DEAD(ped)) { int maxHP = ENTITY::GET_ENTITY_MAX_HEALTH(ped, 1); - + ENTITY::SET_ENTITY_HEALTH(ped, maxHP, 0); } } - + /** Remove hunger */ ATTRIBUTE::_0xC6258F41D86676E0(PLAYER::PLAYER_PED_ID(), 0, 100); - + peds.clear(); } void EffectShadesOfGray::OnTick() { - GRAPHICS::SET_TIMECYCLE_MODIFIER((char*)"PauseMenuDark"); + GRAPHICS::SET_TIMECYCLE_MODIFIER((char*) "PauseMenuDark"); GRAPHICS::SET_TIMECYCLE_MODIFIER_STRENGTH(1.0f); } @@ -1629,17 +1632,17 @@ void EffectPotatoMode::OnTick() if (TimerTick(500)) { auto nearbyPeds = GetNearbyPeds(75); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + PED::SET_PED_LOD_MULTIPLIER(playerPed, 0.06f); - + for (auto ped : nearbyPeds) { peds.insert(ped); } } - + for (auto ped : peds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -1656,6 +1659,6 @@ void EffectPotatoMode::OnDeactivate() PED::SET_PED_LOD_MULTIPLIER(ped, 1.0f); } PED::SET_PED_LOD_MULTIPLIER(PLAYER::PLAYER_PED_ID(), 1.0f); - + peds.clear(); } diff --git a/src/Effects/misc.h b/src/Effects/misc.h index 1f3a845..2d97bce 100644 --- a/src/Effects/misc.h +++ b/src/Effects/misc.h @@ -17,7 +17,7 @@ class EffectSpawnHotchkissCannon : public Effect name = "Spawn Hotchkiss cannon"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -31,12 +31,14 @@ class EffectTeleportEverything : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + private: - std::vector props; - std::vector oldPropsCoords; + std::vector props; + std::vector oldPropsCoords; }; @@ -50,13 +52,13 @@ class EffectSnowstorm : public Effect bTimed = true; EffectDuration = 45; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; - class EffectThunderstorm : public Effect { public: @@ -67,8 +69,9 @@ class EffectThunderstorm : public Effect bTimed = true; EffectDuration = 45; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; @@ -82,16 +85,17 @@ class EffectGiantPeds : public Effect bTimed = true; EffectDuration = 45; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; - + void SetScale(float scale); private: - std::set giantPeds; + std::set giantPeds; }; class EffectAllPedsWannaKillPlayer : public Effect @@ -104,10 +108,11 @@ class EffectAllPedsWannaKillPlayer : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; }; @@ -121,7 +126,7 @@ class EffectRagdollEveryone : public Effect name = "Ragdoll Everyone"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -134,7 +139,7 @@ class EffectLaunchPedsUp : public Effect name = "Launch Nearby Peds Up"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -148,12 +153,14 @@ class EffectInvertedGravity : public Effect bTimed = true; EffectDuration = 10; } - + virtual void OnActivate() override; + virtual void OnTick() override; -private: - std::set entities; +private: + + std::set entities; }; class EffectDoomsday : public Effect @@ -166,15 +173,17 @@ class EffectDoomsday : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; + private: Vector3 randomDirection; - - std::set entities; + + std::set entities; }; class EffectPlayIntro : public Effect @@ -187,8 +196,9 @@ class EffectPlayIntro : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; @@ -201,7 +211,7 @@ class EffectSetTimeMorning : public Effect name = "Set Time to Morning"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -214,7 +224,7 @@ class EffectSetTimeNight : public Effect name = "Set Time to Night"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -227,7 +237,7 @@ class EffectSetRandomTime : public Effect name = "Set Random Time of Day"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -240,7 +250,7 @@ class EffectSetRandomWeather : public Effect name = "Set Random Weather"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -253,7 +263,7 @@ class EffectSetSunnyWeather : public Effect name = "Set Sunny Weather"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -266,7 +276,7 @@ class EffectSetRainyWeather : public Effect name = "Set Rainy Weather"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -280,9 +290,9 @@ class EffectSetRapidWeather : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnDeactivate() override; - + virtual void OnTick() override; }; @@ -296,11 +306,12 @@ class EffectEarthquake : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnTick() override; -private: - std::set entities; +private: + + std::set entities; }; class EffectEveryoneIsInvincible : public Effect @@ -313,12 +324,14 @@ class EffectEveryoneIsInvincible : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnDeactivate() override; + virtual void OnTick() override; -private: - std::set entities; +private: + + std::set entities; }; /** Original code by ChaosModV contributors */ @@ -332,10 +345,13 @@ class Effect120FOV : public Effect bTimed = true; EffectDuration = 15; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + virtual void OnTick() override; + private: Camera cam; }; @@ -349,7 +365,7 @@ class EffectIgniteNearbyPeds : public Effect name = "Ignite Nearby Peds"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -362,7 +378,7 @@ class EffectLightningOnce : public Effect name = "Lightning In a Few Meters"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -375,7 +391,7 @@ class EffectLightningEnemy : public Effect name = "Kill Enemy with Lightning"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -388,7 +404,7 @@ class EffectAltTab : public Effect name = "Alt + Tab"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -401,7 +417,7 @@ class EffectRemoveWeaponFromEveryone : public Effect name = "Remove Weapons From Everyone"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -414,7 +430,7 @@ class EffectSetFoggyWeather : public Effect name = "Set Foggy Weather"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -429,12 +445,15 @@ class EffectGhostTown : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + virtual void OnTick() override; + private: - std::set entities; + std::set entities; }; @@ -448,10 +467,13 @@ class EffectSpawnUFO : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: Object ufo; float heading = 0.0f; @@ -468,13 +490,13 @@ class EffectGravityField : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; - + virtual void OnTick() override; private: - std::set entities; + std::set entities; }; @@ -495,33 +517,35 @@ class EffectPigWeapons : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; private: - std::set peds; - - std::set pigs; - - std::vector pigsVelocity; + std::set peds; + + std::set pigs; + + std::vector pigsVelocity; }; class IEffectGamespeed : public Effect { public: - + IEffectGamespeed() { bTimed = true; EffectDuration = 25; } - + float timeToSet = 1.0f; - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; @@ -529,33 +553,33 @@ class IEffectGamespeed : public Effect class EffectGamespeedx02 : public IEffectGamespeed { public: - + EffectGamespeedx02() { ID = "gamespeed_02"; name = "x0.2 Gamespeed"; timeToSet = 0.2f; - + } }; class EffectGamespeedx05 : public IEffectGamespeed { public: - + EffectGamespeedx05() { ID = "gamespeed_05"; name = "x0.5 Gamespeed"; timeToSet = 0.5f; - + } }; class EffectRainingPigs : public Effect { public: - + EffectRainingPigs() { ID = "raining_pigs"; @@ -563,13 +587,15 @@ class EffectRainingPigs : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; private: - std::vector pigs; + std::vector pigs; }; class EffectRainbow : public Effect @@ -582,8 +608,9 @@ class EffectRainbow : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; @@ -596,7 +623,7 @@ class EffectGiveEveryoneRifle : public Effect name = "Give Everyone A Rifle"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -610,10 +637,13 @@ class EffectTimelapse : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: float totalSeconds = 0; }; @@ -628,7 +658,7 @@ class EffectNoHUD : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnTick() override; }; @@ -642,12 +672,14 @@ class EffectInsaneGravity : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnTick() override; -private: - std::set entities; +private: + + std::set entities; }; class EffectUpsideDownCamera : public Effect @@ -660,10 +692,13 @@ class EffectUpsideDownCamera : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + virtual void OnTick() override; + private: Camera cam; }; @@ -679,12 +714,15 @@ class EffectOneHitKO : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: - std::set peds; + std::set peds; }; class EffectShadesOfGray : public Effect @@ -697,8 +735,9 @@ class EffectShadesOfGray : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnTick() override; + virtual void OnDeactivate() override; }; @@ -712,16 +751,18 @@ class EffectPotatoMode : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: - std::set peds; + std::set peds; }; - /** Meta */ class MetaEffectTotalChaos : public MetaEffect @@ -747,9 +788,23 @@ class MetaEffectComboTime : public MetaEffect } }; +class MetaEffectDoubleSubs : public MetaEffect +{ +public: + MetaEffectDoubleSubs() + { + ID = "double_subs"; + name = "Double Subs"; + EffectDuration = 180; + } +}; + -std::vector GetNearbyProps(int32_t Max); +std::vector GetNearbyProps(int32_t Max); + +void PlayAmbientSpeech(const char* voiceDict, const char* voiceSpeech, Ped ped, uint32_t speechID = 0, + bool bSetEntity = false); -void PlayAmbientSpeech(const char* voiceDict, const char* voiceSpeech, Ped ped, uint32_t speechID = 0, bool bSetEntity = false); Vector3 GetRandomCoordInRange(Vector3 vec, float distance); + Vector3 GetRandomCoordAroundPlayer(float distance, bool bUseVelocity = true); \ No newline at end of file diff --git a/src/Effects/peds.cpp b/src/Effects/peds.cpp index cc8753b..96f6110 100644 --- a/src/Effects/peds.cpp +++ b/src/Effects/peds.cpp @@ -12,22 +12,22 @@ void SetPedOnMount(Ped ped, Ped mount, int seat) Ped SpawnPedAroundPlayer(Hash skinModel, bool bSetInVehicle, bool bSpawnHorseForPed) { LoadModel(skinModel); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, skinModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerLocation = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + bool bPlayerInVehicle = PED::IS_PED_IN_ANY_VEHICLE(playerPed, true); if (bPlayerInVehicle) { playerLocation.z += 2.0f; } - + Ped ped = PED::CREATE_PED(skinModel, playerLocation.x, playerLocation.y, playerLocation.z, 0.0f, 1, 0, 0, 0); - DECORATOR::DECOR_SET_INT(ped, (char*)"honor_override", 0); + DECORATOR::DECOR_SET_INT(ped, (char*) "honor_override", 0); PED::SET_PED_VISIBLE(ped, true); PED::SET_PED_HEARING_RANGE(ped, 10000.0f); STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(skinModel); @@ -36,102 +36,94 @@ Ped SpawnPedAroundPlayer(Hash skinModel, bool bSetInVehicle, bool bSpawnHorseFor { ChaosMod::pedsSet.insert(ped); } - + if (bSetInVehicle && !bModelIsHorse) { if (bPlayerInVehicle) { Vehicle playerVehicle = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + PED::SET_PED_INTO_VEHICLE(ped, playerVehicle, -2); } else if (PED::IS_PED_ON_MOUNT(playerPed)) { Ped mount = PED::GET_MOUNT(playerPed); bool bIsMountSeatFree = invoke(0xAAB0FE202E9FC9F0, mount, 0); - + if (bIsMountSeatFree) { SetPedOnMount(ped, mount, 0); } } } - + if (bSpawnHorseForPed && !bModelIsHorse) { if (PED::IS_PED_ON_MOUNT(playerPed) || bPlayerInVehicle) { - static Hash mountModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Horse_Morgan_Bay"); - + static Hash mountModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Horse_Morgan_Bay"); + Ped mount = SpawnPedAroundPlayer(mountModel, false, false); - + SetPedOnMount(ped, mount, -1); } } - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(ped, false, false); - + return ped; } void MarkPedAsCompanion(Ped ped) { - Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*)"PLAYER"); + Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*) "PLAYER"); Hash companionGroup; - - PED::ADD_RELATIONSHIP_GROUP((char*)"_CHAOS_COMPANION", &companionGroup); + + PED::ADD_RELATIONSHIP_GROUP((char*) "_CHAOS_COMPANION", &companionGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(0, companionGroup, playerGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(0, playerGroup, companionGroup); - + PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, companionGroup); - + PED::SET_PED_AS_GROUP_MEMBER(ped, PLAYER::GET_PLAYER_GROUP(PLAYER::PLAYER_ID())); - + /** BF_CanFightArmedPedsWhenNotArmed */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 5, true); /** BF_AlwaysFight */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 46, true); - + static Hash blipHash = GET_HASH("BLIP_STYLE_FRIENDLY"); - + /** BLIP_ADD_FOR_ENTITY */ Blip blip = RADAR::_0x23F74C2FDA6E7C61(blipHash, ped); - + static Hash blipModifier = GET_HASH("BLIP_MODIFIER_MP_COLOR_1"); - + /** BLIP_ADD_MODIFIER */ RADAR::_0x662D364ABF16DE2F(blip, blipModifier); - + /** Allow talk */ PED::SET_PED_CONFIG_FLAG(ped, 130, 0); } void MarkPedAsEnemy(Ped ped) { - static std::vector groups = { - GET_HASH("PLAYER"), - 0x8A33CDCF, // Civ Male - 0x3220F762, // Civ Female - 0x3D714F12, - 0x915095B1, - 0x2A318608, - 0x9BA3F8C6, - 0xD23F79CC, - 0xF287AFC3, - 0x403647E5 - }; - + static std::vector groups = {GET_HASH("PLAYER"), 0x8A33CDCF, // Civ Male + 0x3220F762, // Civ Female + 0x3D714F12, 0x915095B1, 0x2A318608, 0x9BA3F8C6, 0xD23F79CC, 0xF287AFC3, + 0x403647E5}; + Hash enemyGroup; - PED::ADD_RELATIONSHIP_GROUP((char*)"_CHAOS_ENEMY", &enemyGroup); - + PED::ADD_RELATIONSHIP_GROUP((char*) "_CHAOS_ENEMY", &enemyGroup); + for (uint32_t i = 0; i < groups.size(); i++) { PED::SET_RELATIONSHIP_BETWEEN_GROUPS(5, enemyGroup, groups[i]); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(5, groups[i], enemyGroup); } - + PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, enemyGroup); - + /** BF_CanFightArmedPedsWhenNotArmed */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 5, true); /** BF_AlwaysFight */ @@ -140,7 +132,7 @@ void MarkPedAsEnemy(Ped ped) PED::SET_PED_COMBAT_ATTRIBUTES(ped, 1, true); /** BF_CanLeaveVehicle */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 3, true); - + AI::TASK_COMBAT_PED(ped, PLAYER::PLAYER_PED_ID(), 0, 16); } @@ -150,19 +142,19 @@ void FixEntityInCutscene(Entity entity) ENTITY::SET_ENTITY_COORDS(entity, vec.x, vec.y, vec.z, 0, 0, 0, 0); } -void EffectSpawnSoldier::OnActivate() +void EffectSpawnSoldier::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"s_m_m_army_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "s_m_m_army_01"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + MarkPedAsCompanion(ped); - + RemoveAllPedWeapons(ped); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_SNIPERRIFLE_ROLLINGBLOCK"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_SNIPERRIFLE_ROLLINGBLOCK"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 9999, true, 0x2cd419dc); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); } @@ -170,19 +162,19 @@ void EffectSpawnSoldier::OnActivate() void EffectSpawnDrunkardJon::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_GrizzledJon"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_GrizzledJon"); + Ped ped = SpawnPedAroundPlayer(skinModel, false, true); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 1000); ENTITY::SET_ENTITY_HEALTH(ped, 1000, 0); - + MarkPedAsEnemy(ped); - + /** Set drunk */ invoke(0x406CCF555B04FAD3, ped, true, 0.75f); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -190,119 +182,128 @@ void EffectSpawnDrunkardJon::OnActivate() void EffectSpawnLenny::OnActivate() { Effect::OnActivate(); - - static std::vector skins = { - GAMEPLAY::GET_HASH_KEY((char*)"CS_lenny"), - GAMEPLAY::GET_HASH_KEY((char*)"MSP_SALOON1_MALES_01"), - GAMEPLAY::GET_HASH_KEY((char*)"MSP_SALOON1_FEMALES_01") - }; - + + static std::vector skins = {GAMEPLAY::GET_HASH_KEY((char*) "CS_lenny"), + GAMEPLAY::GET_HASH_KEY((char*) "MSP_SALOON1_MALES_01"), + GAMEPLAY::GET_HASH_KEY((char*) "MSP_SALOON1_FEMALES_01")}; + int32_t skinID = rand() % skins.size(); - + Ped ped = SpawnPedAroundPlayer(skins[skinID]); - + MarkPedAsCompanion(ped); - + RemoveAllPedWeapons(ped); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_RIFLE_SPRINGFIELD"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_RIFLE_SPRINGFIELD"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 9999, true, 0x2cd419dc); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); - + int32_t outfitID = 0; - + switch (skinID) { - case 0: - outfitID = rand() % 13; - invoke(0x77FF8D35EEC6BBC4, ped, rand() % 13, false); - break; - case 1: + case 0: + outfitID = rand() % 13; + invoke(0x77FF8D35EEC6BBC4, ped, rand() % 13, false); + break; + case 1: { - static std::vector outfits = { - 0, 2, 5, 7, 9, 11, 13, 15, 17, 21, 23, - 25, 27, 29, 31, 33, 35, 37, 39, 41, 43 - }; - + static std::vector outfits = {0, 2, 5, 7, 9, 11, 13, 15, 17, 21, 23, 25, 27, 29, 31, 33, 35, 37, + 39, 41, 43}; + outfitID = outfits[rand() % outfits.size()]; - + break; } - case 2: + case 2: { - static std::vector outfits = { - 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 - }; - - outfitID = outfits[rand() % outfits.size()]; + static std::vector outfits = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; + + outfitID = outfits[rand() % outfits.size()]; break; } } - + invoke(0x77FF8D35EEC6BBC4, ped, outfitID, false); - + } void EffectSpawnChicken::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Chicken_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Chicken_01"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + MarkPedAsCompanion(ped); } -void EffectKidnapping::OnActivate() +void EffectSpawnWolfPack::OnActivate() { Effect::OnActivate(); + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Wolf"); + + for (int i = 0; i < 8; i++) + { + Ped ped = SpawnPedAroundPlayer(skinModel); + + MarkPedAsCompanion(ped); + } +} - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_AberdeenPigFarmer"); - static Hash skinModel2 = GAMEPLAY::GET_HASH_KEY((char*)"CS_AberdeenSister"); - +void EffectKidnapping::OnActivate() +{ + Effect::OnActivate(); + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_AberdeenPigFarmer"); + static Hash skinModel2 = GAMEPLAY::GET_HASH_KEY((char*) "CS_AberdeenSister"); + Ped ped = SpawnPedAroundPlayer(skinModel); Ped sister = SpawnPedAroundPlayer(skinModel2); - - Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*)"PLAYER"); + + Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*) "PLAYER"); Hash relationshipGroup; - - PED::ADD_RELATIONSHIP_GROUP((char*)"_CHAOS_KIDNAPPERS", &relationshipGroup); + + PED::ADD_RELATIONSHIP_GROUP((char*) "_CHAOS_KIDNAPPERS", &relationshipGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(3, relationshipGroup, playerGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(3, playerGroup, relationshipGroup); - + auto playerGroupID = PLAYER::GET_PLAYER_GROUP(PLAYER::PLAYER_ID()); - + PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, relationshipGroup); PED::SET_PED_RELATIONSHIP_GROUP_HASH(sister, relationshipGroup); - + /** BF_CanLeaveVehicle */ PED::SET_PED_COMBAT_ATTRIBUTES(ped, 3, false); /** BF_CanLeaveVehicle */ PED::SET_PED_COMBAT_ATTRIBUTES(sister, 3, false); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerCoord = ENTITY::GET_ENTITY_COORDS(playerPed, true, false); - + Entity vehicle = 0; - - static Hash wagonModel = GAMEPLAY::GET_HASH_KEY((char*)"WAGONPRISON01X"); + + static Hash wagonModel = GAMEPLAY::GET_HASH_KEY((char*) "WAGONPRISON01X"); LoadModel(wagonModel); - + float playerHeading = ENTITY::GET_ENTITY_HEADING(playerPed); - vehicle = VEHICLE::CREATE_VEHICLE(wagonModel, playerCoord.x, playerCoord.y, playerCoord.z, playerHeading, 0, 0, 0, 0); - DECORATOR::DECOR_SET_BOOL(vehicle, (char*)"wagon_block_honor", true); + vehicle = VEHICLE::CREATE_VEHICLE(wagonModel, playerCoord.x, playerCoord.y, playerCoord.z, playerHeading, 0, 0, 0, + 0); + DECORATOR::DECOR_SET_BOOL(vehicle, (char*) "wagon_block_honor", true); Vehicle vehCopy = vehicle; ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&vehCopy); PED::SET_PED_INTO_VEHICLE(ped, vehicle, -1); PED::SET_PED_INTO_VEHICLE(sister, vehicle, 0); PED::SET_PED_INTO_VEHICLE(playerPed, vehicle, 1); - + if (ENTITY::DOES_ENTITY_EXIST(vehicle)) { ChaosMod::vehsSet.insert(vehicle); } - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(wagonModel); if (vehicle) @@ -320,37 +321,37 @@ void EffectKidnapping::OnTick() void EffectSpawnHorse::OnActivate() { Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Horse_Arabian_White"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Horse_Arabian_White"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + SetPedOnMount(playerPed, horse, -1); } -std::vector GetNearbyPeds(int32_t Max) +std::vector GetNearbyPeds(int32_t Max) { - std::vector pedsOut; + std::vector pedsOut; Ped playerPed = PLAYER::PLAYER_PED_ID(); - + NearbyEntities peds; peds.size = 100; - + if (Max > 100) { Max = 100; } - - int pedsFound = PED::GET_PED_NEARBY_PEDS(playerPed, (int*)&peds, -1, 0); - + + int pedsFound = PED::GET_PED_NEARBY_PEDS(playerPed, (int*) &peds, -1, 0); + if (Max > pedsFound) { Max = pedsFound; } - + for (int32_t i = 0; i < Max; i++) { Entity ped = peds.entities[i]; @@ -359,7 +360,7 @@ std::vector GetNearbyPeds(int32_t Max) pedsOut.push_back(ped); } } - + return pedsOut; } @@ -369,7 +370,7 @@ void RemovePedFromVeh(Ped ped) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(ped, false); Vector3 vec = ENTITY::GET_ENTITY_COORDS(veh, true, 0); - + ENTITY::SET_ENTITY_COORDS(ped, vec.x, vec.y, vec.z + 2.0f, 0, 0, 0, 0); } else if (PED::IS_PED_ON_MOUNT(ped)) @@ -383,25 +384,20 @@ void RemoveAllPedWeapons(Ped ped) { static Hash unarmed = GET_HASH("WEAPON_UNARMED"); WEAPON::SET_CURRENT_PED_WEAPON(ped, unarmed, 1, 0, 0, 0); - + /** This weapons can't be received without mods, so don't remove it */ - static std::set importantWeapons = - { - GET_HASH("WEAPON_BOW"), - GET_HASH("WEAPON_KIT_CAMERA"), - GET_HASH("WEAPON_LASSO"), - GET_HASH("WEAPON_FISHINGROD"), - GET_HASH("WEAPON_MELEE_LANTERN_ELECTRIC"), - GET_HASH("WEAPON_MELEE_KNIFE") - }; - + static std::set importantWeapons = {GET_HASH("WEAPON_BOW"), GET_HASH("WEAPON_KIT_CAMERA"), + GET_HASH("WEAPON_LASSO"), GET_HASH("WEAPON_FISHINGROD"), + GET_HASH("WEAPON_MELEE_LANTERN_ELECTRIC"), + GET_HASH("WEAPON_MELEE_KNIFE")}; + for (Hash weaponHash : Effect::WeaponHashes) { if (importantWeapons.contains(weaponHash)) { continue; } - + WEAPON::REMOVE_WEAPON_FROM_PED(ped, weaponHash, 0, 0); } } @@ -409,50 +405,50 @@ void RemoveAllPedWeapons(Ped ped) void EffectSpawnMule::OnActivate() { Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_HorseMule_01"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_HorseMule_01"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + SetPedOnMount(playerPed, horse, -1); } void EffectSpawnDonkey::OnActivate() { Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Donkey_01"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Donkey_01"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + SetPedOnMount(playerPed, horse, -1); } void EffectSpawnSerialKiller::OnActivate() { /** Spawn donkey */ - + Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Donkey_01"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Donkey_01"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** Spawn killer */ - static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*)"G_M_M_UniDuster_03"); - + static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*) "G_M_M_UniDuster_03"); + Ped ped = SpawnPedAroundPlayer(pedModel); - + SetPedOnMount(ped, horse, -1); - + MarkPedAsEnemy(ped); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -460,16 +456,16 @@ void EffectSpawnSerialKiller::OnActivate() void EffectSpawnVampire::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_Vampire"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_Vampire"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 1000); ENTITY::SET_ENTITY_HEALTH(ped, 1000, 0); - + MarkPedAsEnemy(ped); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -477,49 +473,49 @@ void EffectSpawnVampire::OnActivate() void EffectSpawnGiantDonkey::OnActivate() { Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Donkey_01"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Donkey_01"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, horse, 1.5f); - + SetPedOnMount(playerPed, horse, -1); } void EffectSpawnMiniDonkey::OnActivate() { Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Donkey_01"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Donkey_01"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, horse, 0.42f); - + SetPedOnMount(playerPed, horse, -1); } void EffectSpawnGiantCop::OnActivate() { Effect::OnActivate(); - - static Hash copGroup = GAMEPLAY::GET_HASH_KEY((char*)"COP"); - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"S_M_M_DispatchLeaderPolice_01"); - + + static Hash copGroup = GAMEPLAY::GET_HASH_KEY((char*) "COP"); + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "S_M_M_DispatchLeaderPolice_01"); + Ped ped = SpawnPedAroundPlayer(skinModel, false, false); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, ped, 10.0f); - + PED::SET_PED_RELATIONSHIP_GROUP_HASH(ped, copGroup); - + AI::TASK_LOOK_AT_ENTITY(ped, PLAYER::PLAYER_PED_ID(), -1, 2048, 3, 1); AI::TASK_WANDER_STANDARD(ped, 10.0f, 10); } @@ -527,49 +523,42 @@ void EffectSpawnGiantCop::OnActivate() void EffectSpawnAngrySkeleton::OnActivate() { Effect::OnActivate(); - - static std::vector skins = { - "U_M_M_CircusWagon_01", - //"CS_ODPROSTITUTE", - "A_M_M_UniCorpse_01", - "A_F_M_UniCorpse_01" - }; - + + static std::vector skins = {"U_M_M_CircusWagon_01", + //"CS_ODPROSTITUTE", + "A_M_M_UniCorpse_01", "A_F_M_UniCorpse_01"}; + uint32_t skinID = rand() % skins.size(); - - Ped ped = SpawnPedAroundPlayer(GAMEPLAY::GET_HASH_KEY((char*)skins[skinID])); - + + Ped ped = SpawnPedAroundPlayer(GAMEPLAY::GET_HASH_KEY((char*) skins[skinID])); + if (skinID == 1) { - static std::vector skeletonOutfitsIDs = { - 31, 36, 46, 56, 68, 143, 144, 147, - }; - + static std::vector skeletonOutfitsIDs = {31, 36, 46, 56, 68, 143, 144, 147,}; + /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, ped, skeletonOutfitsIDs[rand() % skeletonOutfitsIDs.size()], false); } else if (skinID == 2) { - static std::vector skeletonOutfitsIDs = { - 11, 12, 27, 28, - }; - + static std::vector skeletonOutfitsIDs = {11, 12, 27, 28,}; + /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, ped, skeletonOutfitsIDs[rand() % skeletonOutfitsIDs.size()], false); } - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 500); ENTITY::SET_ENTITY_HEALTH(ped, 500, 0); - + if (rand() % 2 == 0) { - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_MELEE_BROKEN_SWORD"); + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_MELEE_BROKEN_SWORD"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 1, true, 0x2cd419dc); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); } - + MarkPedAsEnemy(ped); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -577,34 +566,34 @@ void EffectSpawnAngrySkeleton::OnActivate() void EffectSpawnAngryDwarf::OnActivate() { Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Donkey_01"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Donkey_01"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, horse, 0.5f); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** Spawn dwarf */ - static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_Magnifico"); - + static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_Magnifico"); + Ped ped = SpawnPedAroundPlayer(pedModel, false); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_MELEE_KNIFE"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_MELEE_KNIFE"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 9999, true, 0x2cd419dc); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); - + SetPedOnMount(ped, horse, -1); - + MarkPedAsEnemy(ped); - + if (!PED::IS_PED_IN_ANY_VEHICLE(playerPed, true) && !PED::IS_PED_ON_MOUNT(playerPed)) { - + } - + /** _REMOVE_PED_FROM_MOUNT */ invoke(0x5337B721C51883A9, ped, 0, 0); } @@ -612,35 +601,35 @@ void EffectSpawnAngryDwarf::OnActivate() void EffectSpawnCompanionBertram::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_ODDFELLOWSPINHEAD"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_ODDFELLOWSPINHEAD"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, ped, 1.25f); - + MarkPedAsCompanion(ped); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 1000); ENTITY::SET_ENTITY_HEALTH(ped, 1000, 0); - + WEAPON::REMOVE_ALL_PED_WEAPONS(ped, true, 0); } void EffectSpawnFrozenCouple::OnActivate() { Effect::OnActivate(); - - static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*)"RE_FROZENTODEATH_FEMALES_01"); - static Hash pedModel2 = GAMEPLAY::GET_HASH_KEY((char*)"RE_FROZENTODEATH_MALES_01"); - + + static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*) "RE_FROZENTODEATH_FEMALES_01"); + static Hash pedModel2 = GAMEPLAY::GET_HASH_KEY((char*) "RE_FROZENTODEATH_MALES_01"); + Ped ped = SpawnPedAroundPlayer(pedModel); Ped ped2 = SpawnPedAroundPlayer(pedModel2); - + MarkPedAsEnemy(ped); MarkPedAsEnemy(ped2); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); /** PCF_NoCriticalHits */ @@ -650,11 +639,11 @@ void EffectSpawnFrozenCouple::OnActivate() void EffectSpawnRobot::OnActivate() { Effect::OnActivate(); - - static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_crackpotRobot"); - + + static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_crackpotRobot"); + Ped ped = SpawnPedAroundPlayer(pedModel); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 10000); ENTITY::SET_ENTITY_HEALTH(ped, 10000, 0); @@ -664,22 +653,22 @@ void EffectSpawnRobot::OnActivate() void EffectSpawnLassoGuy::OnActivate() { Effect::OnActivate(); - - static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_EXOTICCOLLECTOR"); - + + static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_EXOTICCOLLECTOR"); + Ped ped = SpawnPedAroundPlayer(pedModel, false, true); - + MarkPedAsEnemy(ped); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_LASSO"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_LASSO"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** TASK_LASSO_PED */ invoke(0xC716EB2BD16370A3, ped, PLAYER::PLAYER_PED_ID()); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -687,68 +676,69 @@ void EffectSpawnLassoGuy::OnActivate() void EffectSkyrimIntro::OnActivate() { Effect::OnActivate(); - - GRAPHICS::ANIMPOSTFX_PLAY((char*)"PlayerWakeUpInterrogation"); - + + GRAPHICS::ANIMPOSTFX_PLAY((char*) "PlayerWakeUpInterrogation"); + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerCoord = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - - static Hash copModel = GAMEPLAY::GET_HASH_KEY((char*)"U_M_O_BlWPoliceChief_01"); - static Hash wagonModel = GAMEPLAY::GET_HASH_KEY((char*)"wagon03x"); - static Hash prisonerModel1 = GAMEPLAY::GET_HASH_KEY((char*)"RE_PRISONWAGON_MALES_01"); - static Hash prisonerModel2 = GAMEPLAY::GET_HASH_KEY((char*)"RE_LONEPRISONER_MALES_01"); - static Hash prisonerModel3 = GAMEPLAY::GET_HASH_KEY((char*)"CS_chainprisoner_01"); - + + static Hash copModel = GAMEPLAY::GET_HASH_KEY((char*) "U_M_O_BlWPoliceChief_01"); + static Hash wagonModel = GAMEPLAY::GET_HASH_KEY((char*) "wagon03x"); + static Hash prisonerModel1 = GAMEPLAY::GET_HASH_KEY((char*) "RE_PRISONWAGON_MALES_01"); + static Hash prisonerModel2 = GAMEPLAY::GET_HASH_KEY((char*) "RE_LONEPRISONER_MALES_01"); + static Hash prisonerModel3 = GAMEPLAY::GET_HASH_KEY((char*) "CS_chainprisoner_01"); + Ped cop = SpawnPedAroundPlayer(copModel, false); Ped prisoner1 = SpawnPedAroundPlayer(prisonerModel1, false); Ped prisoner2 = SpawnPedAroundPlayer(prisonerModel2, false); Ped prisoner3 = SpawnPedAroundPlayer(prisonerModel3, false); - - Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*)"PLAYER"); + + Hash playerGroup = GAMEPLAY::GET_HASH_KEY((char*) "PLAYER"); Hash relationshipGroup; - - PED::ADD_RELATIONSHIP_GROUP((char*)"_CHAOS_WAGON", &relationshipGroup); + + PED::ADD_RELATIONSHIP_GROUP((char*) "_CHAOS_WAGON", &relationshipGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(3, relationshipGroup, playerGroup); PED::SET_RELATIONSHIP_BETWEEN_GROUPS(3, playerGroup, relationshipGroup); - + PED::SET_PED_RELATIONSHIP_GROUP_HASH(cop, relationshipGroup); PED::SET_PED_RELATIONSHIP_GROUP_HASH(prisoner1, relationshipGroup); PED::SET_PED_RELATIONSHIP_GROUP_HASH(prisoner2, relationshipGroup); PED::SET_PED_RELATIONSHIP_GROUP_HASH(prisoner3, relationshipGroup); - + /** BF_CanLeaveVehicle */ PED::SET_PED_COMBAT_ATTRIBUTES(cop, 3, false); PED::SET_PED_COMBAT_ATTRIBUTES(prisoner1, 3, false); PED::SET_PED_COMBAT_ATTRIBUTES(prisoner2, 3, false); PED::SET_PED_COMBAT_ATTRIBUTES(prisoner3, 3, false); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_REPEATER_WINCHESTER"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_REPEATER_WINCHESTER"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(cop, weaponHash, 100, true, 0x2cd419dc); WEAPON::SET_PED_AMMO(cop, weaponHash, 100); - + LoadModel(wagonModel); - + float playerHeading = ENTITY::GET_ENTITY_HEADING(playerPed); - Vehicle vehicle = VEHICLE::CREATE_VEHICLE(wagonModel, playerCoord.x, playerCoord.y, playerCoord.z, playerHeading, 0, 0, 0, 0); - + Vehicle vehicle = VEHICLE::CREATE_VEHICLE(wagonModel, playerCoord.x, playerCoord.y, playerCoord.z, playerHeading, 0, + 0, 0, 0); + Vehicle vehCopy = vehicle; ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&vehCopy); - + PED::SET_PED_INTO_VEHICLE(cop, vehicle, -1); PED::SET_PED_INTO_VEHICLE(playerPed, vehicle, 1); PED::SET_PED_INTO_VEHICLE(prisoner1, vehicle, 2); PED::SET_PED_INTO_VEHICLE(prisoner2, vehicle, 3); PED::SET_PED_INTO_VEHICLE(prisoner3, vehicle, 4); - + if (ENTITY::DOES_ENTITY_EXIST(vehicle)) { ChaosMod::vehsSet.insert(vehicle); } - + VEHICLE::SET_VEHICLE_ON_GROUND_PROPERLY(vehicle, 0); - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(wagonModel); - + AI::TASK_VEHICLE_DRIVE_WANDER(cop, vehicle, 10000.0f, 0x400c0025); PED::SET_PED_KEEP_TASK(cop, true); } @@ -762,24 +752,24 @@ void EffectSkyrimIntro::OnTick() void EffectSpawnParrotCompanion::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Parrot_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Parrot_01"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + MarkPedAsCompanion(ped); ENTITY::SET_ENTITY_MAX_HEALTH(ped, 1000); ENTITY::SET_ENTITY_HEALTH(ped, 1000, 0); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (!PED::IS_PED_IN_ANY_VEHICLE(playerPed, true) && !PED::IS_PED_ON_MOUNT(playerPed)) { Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + vec.z += 2.0f; - + ENTITY::SET_ENTITY_COORDS(ped, vec.x, vec.y, vec.z, false, false, false, false); } } @@ -787,67 +777,67 @@ void EffectSpawnParrotCompanion::OnActivate() void EffectSpawnShireHorse::OnActivate() { Effect::OnActivate(); - - static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Horse_Shire_DarkBay"); - + + static Hash horseModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Horse_Shire_DarkBay"); + Ped horse = SpawnPedAroundPlayer(horseModel); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + SetPedOnMount(playerPed, horse, -1); } void EffectUndeadNightmare::OnActivate() { Effect::OnActivate(); - + TIME::SET_CLOCK_TIME(22, 0, 0); - - static Hash weatherHash = GAMEPLAY::GET_HASH_KEY((char*)"FOG"); - + + static Hash weatherHash = GAMEPLAY::GET_HASH_KEY((char*) "FOG"); + GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); GAMEPLAY::SET_WEATHER_TYPE(weatherHash, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - - static Hash skin = GAMEPLAY::GET_HASH_KEY((char*)"A_M_M_ARMCHOLERACORPSE_01"); - static Hash skin2 = GAMEPLAY::GET_HASH_KEY((char*)"A_M_M_UniCorpse_01"); - + + static Hash skin = GAMEPLAY::GET_HASH_KEY((char*) "A_M_M_ARMCHOLERACORPSE_01"); + static Hash skin2 = GAMEPLAY::GET_HASH_KEY((char*) "A_M_M_UniCorpse_01"); + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Vector3 playerVec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + for (int32_t i = 0; i < 5; i++) { Ped zombie = SpawnPedAroundPlayer(i == 0 ? skin : skin2, false); - + if (i != 0) { /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, zombie, rand() % 187, false); } - + float radius = 10.0f; - + Vector3 coord = playerVec; - + /** In radians */ float angle = i * (360.0f / 5) * (M_PI / 180.0f); - + coord.x += radius * sin(angle); coord.y += radius * cos(angle); - + ENTITY::SET_ENTITY_COORDS(zombie, coord.x, coord.y, coord.z, false, false, false, false); - + /** Set walking style */ invoke(0x89F5E7ADECCCB49C, zombie, "very_drunk"); - + MarkPedAsEnemy(zombie); - + /** BF_CanUseVehicles */ PED::SET_PED_COMBAT_ATTRIBUTES(zombie, 1, false); - + static Hash blipHash = GET_HASH("BLIP_STYLE_ENEMY"); - + /** BLIP_ADD_FOR_ENTITY */ Blip blip = RADAR::_0x23F74C2FDA6E7C61(blipHash, zombie); } @@ -856,47 +846,40 @@ void EffectUndeadNightmare::OnActivate() void EffectSpawnDogCompanion::OnActivate() { Effect::OnActivate(); - - static std::vector dogModels = { - "A_C_DogAmericanFoxhound_01", - "A_C_DogAustralianSheperd_01", - "A_C_DogBluetickCoonhound_01", - "A_C_DogCatahoulaCur_01", - "A_C_DogChesBayRetriever_01", - "A_C_DogCollie_01", - "A_C_DogHobo_01", - "A_C_DogHound_01", - "A_C_DogHusky_01" - }; - - Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)dogModels[rand() % dogModels.size()]); - + + static std::vector dogModels = {"A_C_DogAmericanFoxhound_01", "A_C_DogAustralianSheperd_01", + "A_C_DogBluetickCoonhound_01", "A_C_DogCatahoulaCur_01", + "A_C_DogChesBayRetriever_01", "A_C_DogCollie_01", "A_C_DogHobo_01", + "A_C_DogHound_01", "A_C_DogHusky_01"}; + + Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) dogModels[rand() % dogModels.size()]); + Ped ped = SpawnPedAroundPlayer(skinModel); - + MarkPedAsCompanion(ped); } void EffectSpawnCatCompanion::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Cat_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Cat_01"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + MarkPedAsCompanion(ped); } void EffectSpawnBearCompanion::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_BearBlack_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_BearBlack_01"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + MarkPedAsCompanion(ped); - + PED::SET_PED_COMBAT_ATTRIBUTES(ped, 17, false); PED::SET_PED_COMBAT_ATTRIBUTES(ped, 5, true); PED::SET_PED_COMBAT_ATTRIBUTES(ped, 46, true); @@ -905,18 +888,18 @@ void EffectSpawnBearCompanion::OnActivate() void EffectSpawnAngryCorpse::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"A_M_M_ARMCHOLERACORPSE_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_M_M_ARMCHOLERACORPSE_01"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 300); ENTITY::SET_ENTITY_HEALTH(ped, 300, 0); - + invoke(0x77FF8D35EEC6BBC4, ped, 13, false); - + MarkPedAsEnemy(ped); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -924,21 +907,21 @@ void EffectSpawnAngryCorpse::OnActivate() void EffectSpawnAngryCaveman::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"A_M_M_UniCorpse_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_M_M_UniCorpse_01"); + Ped ped = SpawnPedAroundPlayer(skinModel); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 500); ENTITY::SET_ENTITY_HEALTH(ped, 500, 0); - + invoke(0x77FF8D35EEC6BBC4, ped, 44, false); - + MarkPedAsEnemy(ped); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, ped, 1.1f); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -946,72 +929,72 @@ void EffectSpawnAngryCaveman::OnActivate() void EffectSpawnAngryTwin::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Ped ped = PED::CLONE_PED(playerPed, ENTITY::GET_ENTITY_HEADING(playerPed), true, false); - + if (ENTITY::DOES_ENTITY_EXIST(ped)) { ChaosMod::pedsSet.insert(ped); } - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, false)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + PED::SET_PED_INTO_VEHICLE(ped, veh, -2); } else if (PED::IS_PED_ON_MOUNT(playerPed)) { Ped mount = PED::GET_MOUNT(playerPed); - + bool bIsMountSeatFree = invoke(0xAAB0FE202E9FC9F0, mount, 0); - + if (bIsMountSeatFree) { SetPedOnMount(ped, mount, 0); } } - + ENTITY::SET_ENTITY_INVINCIBLE(ped, false); ENTITY::SET_ENTITY_PROOFS(ped, false, false); - - static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_UNARMED"); + + static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_UNARMED"); Hash weaponHash = 0; - + if (WEAPON::GET_CURRENT_PED_WEAPON(playerPed, &weaponHash, 0, 0, 0) && weaponHash != unarmed) { WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(ped, weaponHash, 100); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); } - + MarkPedAsEnemy(ped); } void EffectSpawnAngryCowboy::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"S_M_M_ValCowpoke_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "S_M_M_ValCowpoke_01"); + Ped ped = SpawnPedAroundPlayer(skinModel, false, true); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 500); ENTITY::SET_ENTITY_HEALTH(ped, 500, 0); - + invoke(0x77FF8D35EEC6BBC4, ped, rand() % 22, false); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_REVOLVER_SCHOFIELD"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_REVOLVER_SCHOFIELD"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 200, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(ped, weaponHash, 200); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + MarkPedAsEnemy(ped); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -1019,50 +1002,50 @@ void EffectSpawnAngryCowboy::OnActivate() void EffectSpawnUndeadBoss::OnActivate() { Effect::OnActivate(); - + TIME::SET_CLOCK_TIME(22, 0, 0); - - static Hash weatherHash = GAMEPLAY::GET_HASH_KEY((char*)"FOG"); - + + static Hash weatherHash = GAMEPLAY::GET_HASH_KEY((char*) "FOG"); + GAMEPLAY::CLEAR_OVERRIDE_WEATHER(); GAMEPLAY::SET_WEATHER_TYPE(weatherHash, 0, 1, 0, 0.0, 0); GAMEPLAY::CLEAR_WEATHER_TYPE_PERSIST(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"A_M_M_UniCorpse_01"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "A_M_M_UniCorpse_01"); + Ped ped = SpawnPedAroundPlayer(skinModel, false, false); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 700); ENTITY::SET_ENTITY_HEALTH(ped, 700, 0); - + /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, ped, rand() % 2 ? 68 : 45, false); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, ped, 1.6f); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_THROWN_TOMAHAWK_ANCIENT"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_THROWN_TOMAHAWK_ANCIENT"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 100, true, 0x2cd419dc); WEAPON::SET_PED_AMMO(ped, weaponHash, 100); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); - + /** SET_ALLOW_ANY_WEAPON_DROP */ WEAPON::_0x78030C7867D8B9B6(ped, false); - + Entity weaponEntity = WEAPON::GET_CURRENT_PED_WEAPON_ENTITY_INDEX(ped, 0); /** Set walking style */ invoke(0x89F5E7ADECCCB49C, ped, "injured_right_leg"); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); - + /** PCF_DisableAllMeleeTakedowns */ PED::SET_PED_CONFIG_FLAG(ped, 340, true); - + PED::_SET_PED_RAGDOLL_BLOCKING_FLAGS(ped, 1 | 2 | 16 | 128 | 512 | 8192); - + MarkPedAsEnemy(ped); - + PED::_0x1902C4CFCC5BE57C(ped, 0x48760F4A); PED::_0xCC8CA3E88256E58F(ped, 0, 1, 1, 1, false); } @@ -1070,64 +1053,64 @@ void EffectSpawnUndeadBoss::OnActivate() void EffectSpawnGrieferMicah::OnActivate() { Effect::OnActivate(); - - static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_MicahBell"); - + + static Hash skinModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_MicahBell"); + Ped ped = SpawnPedAroundPlayer(skinModel, false, true); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 500); ENTITY::SET_ENTITY_HEALTH(ped, 500, 0); - + invoke(0x77FF8D35EEC6BBC4, ped, 10, false); - + int randNum = rand() % 2; - + Hash weaponHash = randNum ? GET_HASH("WEAPON_THROWN_DYNAMITE") : GET_HASH("WEAPON_THROWN_MOLOTOV"); - + WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 20, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(ped, weaponHash, 20); - + WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); - + if (PED::IS_PED_ON_MOUNT(ped)) { - static Hash weaponHashRevolver = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_REVOLVER_SCHOFIELD_GOLDEN"); - + static Hash weaponHashRevolver = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_REVOLVER_SCHOFIELD_GOLDEN"); + WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHashRevolver, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(ped, weaponHashRevolver, 100); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHashRevolver, 1, 0, 0, 0); } - + MarkPedAsEnemy(ped); } void EffectDutchStealsPlayersVeh::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + bool bUsingVehicle = PED::IS_PED_IN_ANY_VEHICLE(playerPed, true); bool bUsingHorse = PED::IS_PED_ON_MOUNT(playerPed); - + if (!bUsingHorse && !bUsingVehicle) { return; } - + static Hash model = GET_HASH("CS_Dutch"); - + Ped ped = SpawnPedAroundPlayer(model, false, false); - + MarkPedAsCompanion(ped); if (bUsingHorse) { Ped mount = PED::GET_MOUNT(playerPed); - + bool bIsMountSeatFree = invoke(0xAAB0FE202E9FC9F0, mount, 0); - + if (bIsMountSeatFree) { SetPedOnMount(playerPed, mount, 0); @@ -1137,29 +1120,29 @@ void EffectDutchStealsPlayersVeh::OnActivate() /** _REMOVE_PED_FROM_MOUNT */ invoke(0x5337B721C51883A9, playerPed, 0, 0); } - + SetPedOnMount(ped, mount, -1); - + AI::TASK_WANDER_STANDARD(ped, 100.0f, 10); } else { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + Hash vehModel = ENTITY::GET_ENTITY_MODEL(veh); - + if (!VEHICLE::IS_VEHICLE_SEAT_FREE(veh, -1)) { Ped driver = VEHICLE::GET_PED_IN_VEHICLE_SEAT(veh, -1); - + int32_t seatsNum = VEHICLE::GET_VEHICLE_MODEL_NUMBER_OF_SEATS(vehModel) - 1; - + bool bFoundNewSeatForDriver = false; - + for (int32_t i = 0; i < seatsNum; i++) { bool bSeatFree = VEHICLE::IS_VEHICLE_SEAT_FREE(veh, i); - + if (bSeatFree) { PED::SET_PED_INTO_VEHICLE(driver, veh, i); @@ -1167,24 +1150,24 @@ void EffectDutchStealsPlayersVeh::OnActivate() break; } } - + if (!bFoundNewSeatForDriver) { Vector3 vec = ENTITY::GET_ENTITY_COORDS(veh, true, 0); - + ENTITY::SET_ENTITY_COORDS(driver, vec.x, vec.y, vec.z + 1.5f, false, false, false, false); } } - + PED::SET_PED_INTO_VEHICLE(ped, veh, -1); - + AI::TASK_VEHICLE_DRIVE_WANDER(ped, veh, 100000.0f, 0x400c0025); } - + PED::SET_PED_KEEP_TASK(ped, true); - + this->dutch = ped; - + invoke(0x77FF8D35EEC6BBC4, ped, 15, false); } @@ -1198,26 +1181,22 @@ void EffectDutchStealsPlayersVeh::OnDeactivate() void EffectSpawnPredator::OnActivate() { - static std::vector models = - { - "A_C_Alligator_01", - "A_C_Bear_01", "A_C_Cougar_01", - "A_C_LionMangy_01", "A_C_Panther_01", - "A_C_Wolf" - }; - - std::map> disabledOutfits; - - disabledOutfits.emplace("A_C_Bear_01", std::set({ 9, 10 })); - + static std::vector models = {"A_C_Alligator_01", "A_C_Bear_01", "A_C_Cougar_01", "A_C_LionMangy_01", + "A_C_Panther_01", "A_C_Wolf"}; + + std::map> + disabledOutfits; + + disabledOutfits.emplace("A_C_Bear_01", std::set({9, 10})); + auto modelName = models[rand() % models.size()]; Ped ped = SpawnPedAroundPlayer(GET_HASH(modelName), false, false); - + uint32_t maxOutfits = PED::_0x10C70A515BC03707(ped); - + uint32_t randOutfit = rand() % maxOutfits; - + if (disabledOutfits.contains(modelName)) { if (disabledOutfits[modelName].contains(randOutfit)) @@ -1225,9 +1204,9 @@ void EffectSpawnPredator::OnActivate() randOutfit = 0; } } - + invoke(0x77FF8D35EEC6BBC4, ped, randOutfit, false); - + MarkPedAsEnemy(ped); } @@ -1237,20 +1216,20 @@ void EffectPedsBhop::OnTick() { return; } - + auto nearbyPeds = GetNearbyPeds(50); - + for (auto ped : nearbyPeds) { if (!PED::IS_PED_HUMAN(ped)) { continue; } - + if (PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { Vector3 vec = ENTITY::GET_ENTITY_COORDS(ped, true, 0); - + ENTITY::SET_ENTITY_COORDS(ped, vec.x, vec.y, vec.z + 1.5f, false, false, false, false); } else if (PED::IS_PED_ON_MOUNT(ped)) @@ -1276,26 +1255,26 @@ void EffectPedsSpin::OnTick() if (TimerTick(500)) { peds.clear(); - + auto nearbyPeds = GetNearbyPeds(50); - + for (auto ped : nearbyPeds) { peds.insert(ped); } } - + heading += 625.0f * ChaosMod::GetDeltaTimeSeconds(); - + heading = fmod(heading, 360.0f); - + for (auto ped : peds) { if (PED::IS_PED_IN_ANY_VEHICLE(ped, true) || PED::IS_PED_ON_MOUNT(ped)) { continue; } - + ENTITY::SET_ENTITY_HEADING(ped, heading); } } @@ -1304,34 +1283,34 @@ void EffectCloneEnemy::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); auto nearbyPeds = GetNearbyPeds(50); - std::vector validPeds; - + std::vector validPeds; + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) { int relationships = PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped, playerPed); - + if (relationships == 5) { validPeds.push_back(ped); } } } - + if (!validPeds.size()) { return; } - + Ped ped = validPeds[rand() % validPeds.size()]; - + Ped clone = PED::CLONE_PED(ped, ENTITY::GET_ENTITY_HEADING(ped), false, false); - + if (PED::IS_PED_IN_ANY_VEHICLE(ped, false)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(ped, false); - + if (VEHICLE::ARE_ANY_VEHICLE_SEATS_FREE(veh)) { PED::SET_PED_INTO_VEHICLE(clone, veh, -2); @@ -1340,19 +1319,19 @@ void EffectCloneEnemy::OnActivate() if (PED::IS_PED_ON_MOUNT(ped)) { Ped mount = PED::GET_MOUNT(ped); - + bool bIsMountSeatFree = invoke(0xAAB0FE202E9FC9F0, mount, 0); - + if (bIsMountSeatFree) { SetPedOnMount(clone, mount, 0); } } - + ENTITY::SET_ENTITY_INVINCIBLE(clone, false); MarkPedAsEnemy(clone); - + if (ENTITY::DOES_ENTITY_EXIST(clone)) { ChaosMod::pedsSet.insert(clone); @@ -1370,18 +1349,18 @@ void EffectPedsFollowPlayer::OnTick() { return; } - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + auto nearbyPeds = GetNearbyPeds(50); - + for (auto ped : nearbyPeds) { if (peds.contains(ped) || ENTITY::IS_ENTITY_A_MISSION_ENTITY(ped)) { continue; } - + AI::TASK_FOLLOW_TO_OFFSET_OF_ENTITY(ped, playerPed, 0.0f, 0.0f, 0.0f, 4.5f, -1.0f, -1.0f, 0, 0, 0, 0, 0); peds.insert(ped); } @@ -1397,23 +1376,23 @@ void EffectPedsFollowPlayer::OnDeactivate() AI::TASK_WANDER_STANDARD(ped, 10.0f, 10); } } - + peds.clear(); } void EffectPedsFleeing::OnActivate() { auto nearbyPeds = GetNearbyPeds(50); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + for (auto ped : nearbyPeds) { if (ENTITY::IS_ENTITY_A_MISSION_ENTITY(ped)) { continue; } - + invoke(0x22B0D0E37CCB840D, ped, playerPed, 70.0f, 10000.0f, 0, 3.0f, 0); } } @@ -1421,7 +1400,7 @@ void EffectPedsFleeing::OnActivate() void EffectHealNearbyPeds::OnActivate() { auto nearbyPeds = GetNearbyPeds(45); - + for (auto ped : nearbyPeds) { int maxHealth = ENTITY::GET_ENTITY_MAX_HEALTH(ped, 0); @@ -1433,9 +1412,9 @@ void EffectReviveDeadPeds::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); int* worldPeds = new int[150]; - + int found = worldGetAllPeds(worldPeds, 150); - + for (int32_t i = 0; i < found; i++) { Ped ped = worldPeds[i]; @@ -1444,22 +1423,22 @@ void EffectReviveDeadPeds::OnActivate() if (PED::IS_PED_DEAD_OR_DYING(ped, 1)) { int relationships = PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped, playerPed); - + int health = ENTITY::GET_ENTITY_MAX_HEALTH(ped, 0); - + PED::RESURRECT_PED(ped); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, health); ENTITY::SET_ENTITY_HEALTH(ped, health, 0); - + PED::REVIVE_INJURED_PED(ped); - + AI::CLEAR_PED_TASKS_IMMEDIATELY(ped, 0, true); - + MarkPedAsEnemy(ped); - + PED::SET_PED_TO_RAGDOLL(ped, 500, 500, 0, true, true, false); - + } if (PED::IS_PED_INJURED(ped)) { @@ -1467,29 +1446,29 @@ void EffectReviveDeadPeds::OnActivate() } } } - + delete[] worldPeds; } void EffectSpawnAngryTommy::OnActivate() { Effect::OnActivate(); - + static Hash skinModel = GET_HASH("CS_mud2bigguy"); - + Ped ped = SpawnPedAroundPlayer(skinModel, false, true); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 1000); ENTITY::SET_ENTITY_HEALTH(ped, 1000, 0); - + MarkPedAsEnemy(ped); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, ped, 1.1f); - + /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, ped, 1, false); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); } @@ -1501,80 +1480,75 @@ void EffectPartyTime::OnActivate() } void EffectPartyTime::OnTick() -{ +{ DisableAllMovements(); - + if (!TimerTick(1000)) { return; } - - static char* animDict = (char*)"script_shows@cancandance@p1"; - static std::vector animNames = { - "cancandance_fem0", - "cancandance_fem1", - "cancandance_fem2", - "cancandance_fem3", - "cancandance_male" - }; - + + static char* animDict = (char*) "script_shows@cancandance@p1"; + static std::vector animNames = {"cancandance_fem0", "cancandance_fem1", "cancandance_fem2", + "cancandance_fem3", "cancandance_male"}; + STREAMING::REQUEST_ANIM_DICT(animDict); - + while (!STREAMING::HAS_ANIM_DICT_LOADED(animDict)) { WAIT(0); } - + auto nearbyPeds = GetNearbyPeds(50); Ped playerPed = PLAYER::PLAYER_PED_ID(); nearbyPeds.push_back(playerPed); - + for (auto ped : nearbyPeds) { if (!PED::IS_PED_HUMAN(ped)) { continue; } - + if (peds.contains(ped) && ENTITY::IS_ENTITY_PLAYING_ANIM(ped, animDict, pedAnimNames[ped], 1)) { continue; } - + if (ped != playerPed && ENTITY::IS_ENTITY_A_MISSION_ENTITY(ped)) { int relationhips = PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped, playerPed); - + if (relationhips < 4) { continue; } } - + RemovePedFromVeh(ped); - + AI::CLEAR_PED_TASKS_IMMEDIATELY(ped, 0, true); - - char* animName = (char*)(animNames[rand() % animNames.size()]); - + + char* animName = (char*) (animNames[rand() % animNames.size()]); + pedAnimNames.emplace(ped, animName); - - AI::TASK_PLAY_ANIM(ped, animDict, animName, 3.0f, -3.0f, -1, 1, 0, false, false, false, (Any*)"", 0); + + AI::TASK_PLAY_ANIM(ped, animDict, animName, 3.0f, -3.0f, -1, 1, 0, false, false, false, (Any*) "", 0); //PED::SET_PED_KEEP_TASK(ped, true); //PED::SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ped, true); - + peds.insert(ped); } - + STREAMING::REMOVE_ANIM_DICT(animDict); } void EffectPartyTime::OnDeactivate() { - static char* animDict = (char*)"script_shows@cancandance@p1"; - + static char* animDict = (char*) "script_shows@cancandance@p1"; + STREAMING::REMOVE_ANIM_DICT(animDict); - + for (auto ped : peds) { char* animName = pedAnimNames[ped]; @@ -1583,7 +1557,7 @@ void EffectPartyTime::OnDeactivate() AI::STOP_ANIM_TASK(ped, animDict, animName, 0); } } - + peds.clear(); pedAnimNames.clear(); } @@ -1591,32 +1565,32 @@ void EffectPartyTime::OnDeactivate() void EffectExplodeNearbyPeds::OnActivate() { const static int max = 15; - + auto peds = GetNearbyPeds(50); - + int i = 0; - + for (auto ped : peds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) { Hash pedModel = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, pedModel); if (bModelIsHorse) { continue; } - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(ped, true, 0); - + FIRE::ADD_EXPLOSION(vec.x, vec.y, vec.z, 27, 1.0f, true, false, 1.0f); - + ENTITY::SET_ENTITY_HEALTH(ped, 0, 0); - + i++; - + if (i >= max) { return; @@ -1628,36 +1602,36 @@ void EffectExplodeNearbyPeds::OnActivate() void EffectNearbyPedIsCompanion::OnActivate() { auto nearbyPeds = GetNearbyPeds(50); - - std::vector peds; - + + std::vector peds; + for (auto ped : nearbyPeds) { Hash pedModel = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, pedModel); bool bEntityIsBird = invoke(0xC346A546612C49A9, ped); - + if (!bModelIsHorse && !bEntityIsBird && !ENTITY::IS_ENTITY_A_MISSION_ENTITY(ped)) { peds.push_back(ped); } } - + if (!peds.size()) { return; } - + Ped ped = peds[rand() % peds.size()]; - + AI::CLEAR_PED_TASKS_IMMEDIATELY(ped, 0, true); - + MarkPedAsCompanion(ped); - + //AI::TASK_FOLLOW_TO_OFFSET_OF_ENTITY(ped, PLAYER::PLAYER_PED_ID(), 0.0f, 0.0f, 0.0f, 4.5f, -1.0f, -1.0f, 0, 0, 0, 0, 0); - + if (PED::IS_PED_HUMAN(ped)) { static Hash weaponHash = GET_HASH("WEAPON_REPEATER_CARBINE"); @@ -1677,27 +1651,27 @@ void EffectEveryoneRagdollsWhenShot::OnTick() if (TimerTick(500)) { peds.clear(); - + auto nearbyPeds = GetNearbyPeds(50); - + nearbyPeds.push_back(PLAYER::PLAYER_PED_ID()); - + for (auto ped : nearbyPeds) { peds.insert(ped); } } - + for (auto ped : peds) { if (!ENTITY::DOES_ENTITY_EXIST(ped) || ENTITY::IS_ENTITY_DEAD(ped)) { continue; } - + Vector3 vec; bool bCoordValid = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(ped, &vec); - + if (bCoordValid) { PED::SET_PED_TO_RAGDOLL(ped, 5000, 5000, 0, true, true, false); @@ -1708,9 +1682,9 @@ void EffectEveryoneRagdollsWhenShot::OnTick() void EffectNearbyPedIsEnemy::OnActivate() { auto nearbyPeds = GetNearbyPeds(50); - - std::vector peds; - + + std::vector peds; + for (auto ped : nearbyPeds) { if (PED::IS_PED_HUMAN(ped)) @@ -1718,14 +1692,14 @@ void EffectNearbyPedIsEnemy::OnActivate() peds.push_back(ped); } } - + if (!peds.size()) { return; } - + Ped ped = peds[rand() % peds.size()]; - + if (PED::IS_PED_HUMAN(ped)) { static Hash weaponHash = GET_HASH("WEAPON_REPEATER_CARBINE"); @@ -1733,11 +1707,11 @@ void EffectNearbyPedIsEnemy::OnActivate() WEAPON::SET_PED_AMMO(ped, weaponHash, 9999); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); } - + MarkPedAsEnemy(ped); - + static Hash blipHash = GET_HASH("BLIP_STYLE_ENEMY"); - + /** BLIP_ADD_FOR_ENTITY */ Blip blip = RADAR::_0x23F74C2FDA6E7C61(blipHash, ped); } @@ -1752,27 +1726,27 @@ void EffectExplosiveCombat::OnTick() if (TimerTick(500)) { peds.clear(); - + auto nearbyPeds = GetNearbyPeds(50); - + nearbyPeds.push_back(PLAYER::PLAYER_PED_ID()); - + for (auto ped : nearbyPeds) { peds.insert(ped); } } - + for (auto ped : peds) { if (!ENTITY::DOES_ENTITY_EXIST(ped) || ENTITY::IS_ENTITY_DEAD(ped)) { continue; } - + Vector3 vec; bool bCoordValid = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(ped, &vec); - + if (bCoordValid) { FIRE::ADD_EXPLOSION(vec.x, vec.y, vec.z, 27, 1.0f, true, false, 1.0f); @@ -1784,17 +1758,15 @@ void EffectODriscolls::OnActivate() { static Hash model = GET_HASH("g_m_m_uniduster_01"); static Hash horseModel = GET_HASH("A_C_Horse_Arabian_Black"); - + Ped ped1 = SpawnPedAroundPlayer(model, false, false); Ped ped2 = SpawnPedAroundPlayer(model, false, false); - - std::vector peds = { - ped1, ped2 - }; - + + std::vector peds = {ped1, ped2}; + Ped mount = SpawnPedAroundPlayer(horseModel, false, false); SetPedOnMount(ped1, mount, -1); - + for (auto ped : peds) { static Hash weaponHash = GET_HASH("WEAPON_REPEATER_CARBINE"); @@ -1803,41 +1775,41 @@ void EffectODriscolls::OnActivate() WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, ped, rand() % 184, false); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 300); ENTITY::SET_ENTITY_HEALTH(ped, 300, 0); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); - + MarkPedAsEnemy(ped); } } void EffectBanditoKidnapsPlayer::OnActivate() { - static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*)"G_M_M_UNIBANDITOS_01"); - static Hash donkeyModel = GAMEPLAY::GET_HASH_KEY((char*)"A_C_Donkey_01"); - + static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*) "G_M_M_UNIBANDITOS_01"); + static Hash donkeyModel = GAMEPLAY::GET_HASH_KEY((char*) "A_C_Donkey_01"); + Ped donkey = SpawnPedAroundPlayer(donkeyModel, false, false); Ped ped = SpawnPedAroundPlayer(pedModel, false, false); - + SetPedOnMount(ped, donkey, -1); - + MarkPedAsEnemy(ped); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_LASSO"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_LASSO"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** TASK_LASSO_PED */ invoke(0xC716EB2BD16370A3, ped, PLAYER::PLAYER_PED_ID()); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); - + /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, ped, 0, false); } @@ -1845,9 +1817,9 @@ void EffectBanditoKidnapsPlayer::OnActivate() void EffectSpawnTwitchViewer::OnActivate() { Effect::OnActivate(); - + bool bRequestSent = ChaosMod::Singleton->RequestTwitchViewerNameToSpawn(); - + //if (!bRequestSent) //{ // Spawn("Viewer_Name"); @@ -1856,110 +1828,102 @@ void EffectSpawnTwitchViewer::OnActivate() void EffectSpawnTwitchViewer::Spawn(std::string name) { - static std::vector skins = { - "a_m_m_vallaborer_01", "a_m_m_valtownfolk_01", - "a_m_m_valtownfolk_02", "a_m_m_tumtownfolk_01", - "a_f_m_valtownfolk_01", "a_m_m_asbtownfolk_01" - }; - + static std::vector skins = {"a_m_m_vallaborer_01", "a_m_m_valtownfolk_01", "a_m_m_valtownfolk_02", + "a_m_m_tumtownfolk_01", "a_f_m_valtownfolk_01", "a_m_m_asbtownfolk_01"}; + Hash model = GET_HASH(skins[rand() % skins.size()]); - + ped = SpawnPedAroundPlayer(model, false, true); - + uint32_t maxOutfits = PED::_0x10C70A515BC03707(ped); uint32_t randOutfit = rand() % maxOutfits; - + invoke(0x77FF8D35EEC6BBC4, ped, randOutfit, false); - - static std::vector faceIndices = - { - 0x84D6, 0x3303, 0x2FF9, 0x4AD1, 0xC04F, 0xB6CE, - 0x2844, 0xED30, 0x6A0B, 0xABCF, 0x358D, 0x8D0A, - 0xEBAE, 0x1DF6, 0x3C0F, 0xC3B2, 0xE323, 0x8B2B, - 0x1B6B, /*0xEE44, 0xD266, 0xA54E, 0xDDFB,*/ 0x6E7F, - 0x3471, 0x03F5, 0x34B1, 0xF156, 0x561E, 0xF065, - 0xAA69, 0x7AC3, 0x410D, 0x1A00, 0x91C1, 0xC375, - 0xBB4D, 0xB0B0, 0x5D16 - }; - + + static std::vector faceIndices = {0x84D6, 0x3303, 0x2FF9, 0x4AD1, 0xC04F, 0xB6CE, 0x2844, 0xED30, 0x6A0B, + 0xABCF, 0x358D, 0x8D0A, 0xEBAE, 0x1DF6, 0x3C0F, 0xC3B2, 0xE323, 0x8B2B, + 0x1B6B, /*0xEE44, 0xD266, 0xA54E, 0xDDFB,*/ 0x6E7F, 0x3471, 0x03F5, 0x34B1, + 0xF156, 0x561E, 0xF065, 0xAA69, 0x7AC3, 0x410D, 0x1A00, 0x91C1, 0xC375, + 0xBB4D, 0xB0B0, 0x5D16}; + for (auto ind : faceIndices) { float randNum = ((float(rand() % 101) / 100.0f) * 10.0f) - 5.0f; invoke(0x5653AB26C82938CF, ped, ind, randNum); } - + invoke(0x5653AB26C82938CF, ped, 0xEE44, ((float(rand() % 101) / 100.0f) * 2.0f) + 1.0f); - + PED::_0xCC8CA3E88256E58F(ped, 0, 1, 1, 1, 0); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_REVOLVER_SCHOFIELD"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_REVOLVER_SCHOFIELD"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 200, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(ped, weaponHash, 200); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, 1, 0, 0, 0); - - - PED::_0x4A48B6E03BABB4AC(ped, (Any*)name.c_str()); - + + + PED::_0x4A48B6E03BABB4AC(ped, (Any*) name.c_str()); + //Ped pedCopy = ped; - + //ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&pedCopy); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, ped, 0.9f + (float(rand() % 11) / 100.0f)); - + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 200); ENTITY::SET_ENTITY_HEALTH(ped, 200, 0); /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); - - + + MarkPedAsCompanion(ped); - + std::string str = "Spawned NPC with name " + name; - + ChaosMod::LogToFile(str.c_str()); } void EffectEveryoneIsLenny::OnActivate() { auto peds = GetNearbyPeds(70); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + for (auto ped : peds) { Hash model = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, model); - + if (bModelIsHorse) { continue; } - + int relationships = PED::GET_RELATIONSHIP_BETWEEN_PEDS(ped, playerPed); - + if ((ENTITY::IS_ENTITY_A_MISSION_ENTITY(ped) && !ChaosMod::pedsSet.contains(ped)) && relationships < 4) { continue; } - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(ped, true, 0); float heading = ENTITY::GET_ENTITY_HEADING(ped); - + Vehicle veh = 0; Ped mount = 0; int32_t seatID = -2; - + if (PED::IS_PED_IN_ANY_VEHICLE(ped, 0)) { veh = PED::GET_VEHICLE_PED_IS_IN(ped, 0); - + Hash vehModel = ENTITY::GET_ENTITY_MODEL(veh); - + int32_t seatsNum = VEHICLE::GET_VEHICLE_MODEL_NUMBER_OF_SEATS(vehModel) - 1; - + for (int32_t i = -1; i < seatsNum; i++) { if (VEHICLE::GET_PED_IN_VEHICLE_SEAT(veh, i) == ped) @@ -1972,7 +1936,7 @@ void EffectEveryoneIsLenny::OnActivate() else if (PED::IS_PED_ON_MOUNT(ped)) { mount = PED::GET_MOUNT(ped); - + if (PED::_0xB676EFDA03DADA52(mount, 0) == ped) { seatID = -1; @@ -1982,21 +1946,19 @@ void EffectEveryoneIsLenny::OnActivate() seatID = 0; } } - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(ped, 0, 0); - + PED::DELETE_PED(&ped); - - static std::vector skins = { - GAMEPLAY::GET_HASH_KEY((char*)"CS_lenny"), - GAMEPLAY::GET_HASH_KEY((char*)"MSP_SALOON1_MALES_01"), - GAMEPLAY::GET_HASH_KEY((char*)"MSP_SALOON1_FEMALES_01") - }; - + + static std::vector skins = {GAMEPLAY::GET_HASH_KEY((char*) "CS_lenny"), + GAMEPLAY::GET_HASH_KEY((char*) "MSP_SALOON1_MALES_01"), + GAMEPLAY::GET_HASH_KEY((char*) "MSP_SALOON1_FEMALES_01")}; + int32_t skinID = rand() % skins.size(); Ped lenny = SpawnPedAroundPlayer(skins[skinID]); int32_t outfitID = 0; - + switch (skinID) { case 0: @@ -2004,33 +1966,29 @@ void EffectEveryoneIsLenny::OnActivate() break; case 1: { - static std::vector outfits = { - 0, 2, 5, 7, 9, 11, 13, 15, 17, 21, 23, - 25, 27, 29, 31, 33, 35, 37, 39, 41, 43 - }; - + static std::vector outfits = {0, 2, 5, 7, 9, 11, 13, 15, 17, 21, 23, 25, 27, 29, 31, 33, 35, + 37, 39, 41, 43}; + outfitID = outfits[rand() % outfits.size()]; - + break; } case 2: { - static std::vector outfits = { - 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 - }; - + static std::vector outfits = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; + outfitID = outfits[rand() % outfits.size()]; break; } } - + invoke(0x77FF8D35EEC6BBC4, lenny, outfitID, false); - + ENTITY::SET_ENTITY_COORDS(lenny, vec.x, vec.y, vec.z, 0, 0, 0, 0); ENTITY::SET_ENTITY_HEADING(lenny, heading); - + if (seatID != -2) - { + { if (veh) { PED::SET_PED_INTO_VEHICLE(lenny, veh, seatID); @@ -2046,14 +2004,14 @@ void EffectEveryoneIsLenny::OnActivate() AI::TASK_WANDER_STANDARD(lenny, 10.0f, 10); AI::TASK_LOOK_AT_ENTITY(ped, playerPed, -1, 2048, 3, 1); } - + if (relationships == 5) { MarkPedAsEnemy(lenny); } - + ChaosMod::pedsSet.erase(lenny); - + ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&lenny); } } @@ -2061,32 +2019,32 @@ void EffectEveryoneIsLenny::OnActivate() void EffectSpawnExtremeEvilMicah::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - - static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*)"CS_MicahBell"); - + + static Hash pedModel = GAMEPLAY::GET_HASH_KEY((char*) "CS_MicahBell"); + Ped ped = SpawnPedAroundPlayer(pedModel, false, true); /** Set outfit */ invoke(0x77FF8D35EEC6BBC4, ped, 10, false); /** Set explosion proof */ invoke(0xFAEE099C6F890BB8, ped, 4, 0); - + MarkPedAsEnemy(ped); - + RemoveAllPedWeapons(ped); - + static Hash weaponHash = GET_HASH("WEAPON_BOW"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ped, weaponHash, 9999, true, 0x2cd419dc); WEAPON::SET_CURRENT_PED_WEAPON(ped, weaponHash, true, 0, 0, 0); - - + + ENTITY::SET_ENTITY_MAX_HEALTH(ped, 800); ENTITY::SET_ENTITY_HEALTH(ped, 800, 0); - + /** PCF_NoCriticalHits */ PED::SET_PED_CONFIG_FLAG(ped, 263, true); - + lastVec.x = lastVec.y = lastVec.z = 0; micahPed = ped; } @@ -2097,17 +2055,17 @@ void EffectSpawnExtremeEvilMicah::OnTick() { return; } - + Vector3 vec; - + bool bCoordValid = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(micahPed, &vec); - + if (!bCoordValid || (vec.x == lastVec.x && vec.y == lastVec.y && vec.z == lastVec.z)) { return; } - + lastVec = vec; - + FIRE::ADD_EXPLOSION(vec.x, vec.y, vec.z, 27, 1.0f, true, false, 1.0f); } diff --git a/src/Effects/peds.h b/src/Effects/peds.h index c34823b..b1846ed 100644 --- a/src/Effects/peds.h +++ b/src/Effects/peds.h @@ -16,7 +16,7 @@ class EffectSpawnSoldier : public Effect name = "Spawn Soldier Companion"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -29,7 +29,7 @@ class EffectSpawnDrunkardJon : public Effect name = "Spawn Drunkard Jon"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -42,7 +42,7 @@ class EffectSpawnLenny : public Effect name = "Spawn Companion Lenny"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -55,7 +55,20 @@ class EffectSpawnChicken : public Effect name = "Spawn Chicken Companion"; bTimed = false; } + + virtual void OnActivate() override; +}; +class EffectSpawnWolfPack : public Effect +{ +public: + EffectSpawnWolfPack() + { + ID = "spawn_wolf_pack"; + name = "Spawn Companion Wolf Pack"; + bTimed = false; + } + virtual void OnActivate() override; }; @@ -69,8 +82,9 @@ class EffectKidnapping : public Effect bTimed = true; EffectDuration = 15; } - + virtual void OnActivate() override; + virtual void OnTick() override; }; @@ -83,7 +97,7 @@ class EffectSpawnHorse : public Effect name = "Spawn Horse"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -96,7 +110,7 @@ class EffectSpawnMule : public Effect name = "Spawn Mule"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -109,7 +123,7 @@ class EffectSpawnDonkey : public Effect name = "Spawn Donkey"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -122,7 +136,7 @@ class EffectSpawnMiniDonkey : public Effect name = "Spawn Mini Donkey"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -135,7 +149,7 @@ class EffectSpawnGiantDonkey : public Effect name = "Spawn Giant Donkey"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -148,7 +162,7 @@ class EffectSpawnSerialKiller : public Effect name = "Spawn Serial Killer"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -161,7 +175,7 @@ class EffectSpawnVampire : public Effect name = "Spawn Vampire"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -174,7 +188,7 @@ class EffectSpawnGiantCop : public Effect name = "Spawn Giant Cop"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -187,7 +201,7 @@ class EffectSpawnAngrySkeleton : public Effect name = "Spawn Angry Skeleton"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -200,7 +214,7 @@ class EffectSpawnAngryDwarf : public Effect name = "Spawn Angry Dwarf"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -213,7 +227,7 @@ class EffectSpawnCompanionBertram : public Effect name = "Spawn Companion Bertram"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -226,7 +240,7 @@ class EffectSpawnFrozenCouple : public Effect name = "Spawn Frozen Couple"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -240,7 +254,7 @@ class EffectSpawnRobot : public Effect name = "Spawn Robot Companion"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -253,7 +267,7 @@ class EffectSpawnLassoGuy : public Effect name = "Spawn Lasso Guy"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -267,8 +281,9 @@ class EffectSkyrimIntro : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnTick() override; }; @@ -281,7 +296,7 @@ class EffectSpawnParrotCompanion : public Effect name = "Spawn Parrot Companion"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -294,7 +309,7 @@ class EffectSpawnShireHorse : public Effect name = "Spawn Shire Horse"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -307,7 +322,7 @@ class EffectUndeadNightmare : public Effect name = "Undead Nightmare"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -320,7 +335,7 @@ class EffectSpawnDogCompanion : public Effect name = "Spawn Dog Companion"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -333,7 +348,7 @@ class EffectSpawnCatCompanion : public Effect name = "Spawn Cat Companion"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -346,7 +361,7 @@ class EffectSpawnBearCompanion : public Effect name = "Spawn Bear Companion"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -359,7 +374,7 @@ class EffectSpawnAngryCorpse : public Effect name = "Spawn Angry Corpse"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -373,7 +388,7 @@ class EffectSpawnAngryCaveman : public Effect name = "Spawn Angry Caveman"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -386,7 +401,7 @@ class EffectSpawnAngryTwin : public Effect name = "Spawn Angry Twin"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -399,7 +414,7 @@ class EffectSpawnAngryCowboy : public Effect name = "Spawn Angry Cowboy"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -412,7 +427,7 @@ class EffectSpawnUndeadBoss : public Effect name = "Spawn Undead Boss"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -425,7 +440,7 @@ class EffectSpawnGrieferMicah : public Effect name = "Spawn Griefer Micah"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -439,9 +454,11 @@ class EffectDutchStealsPlayersVeh : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + private: Ped dutch; }; @@ -455,7 +472,7 @@ class EffectSpawnPredator : public Effect name = "Spawn Predator"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -470,7 +487,7 @@ class EffectPedsBhop : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnTick() override; }; @@ -484,12 +501,14 @@ class EffectPedsSpin : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; -private: - std::set peds; +private: + std::set peds; + float heading = 0.0f; }; @@ -502,7 +521,7 @@ class EffectCloneEnemy : public Effect name = "Clone Random Enemy"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -516,12 +535,15 @@ class EffectPedsFollowPlayer : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: - std::set peds; + std::set peds; }; class EffectPedsFleeing : public Effect @@ -533,7 +555,7 @@ class EffectPedsFleeing : public Effect name = "Nearby Peds Are Fleeing"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -546,7 +568,7 @@ class EffectHealNearbyPeds : public Effect name = "Heal Nearby Peds"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -559,7 +581,7 @@ class EffectReviveDeadPeds : public Effect name = "Revive Dead Peds"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -572,7 +594,7 @@ class EffectSpawnAngryTommy : public Effect name = "Spawn Angry Tommy"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -586,12 +608,15 @@ class EffectPartyTime : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: - std::set peds; + std::set peds; std::map pedAnimNames; }; @@ -604,7 +629,7 @@ class EffectExplodeNearbyPeds : public Effect name = "Explode Nearby Peds"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -617,7 +642,7 @@ class EffectNearbyPedIsCompanion : public Effect name = "Nearby Ped Is Player's Companion"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -631,11 +656,13 @@ class EffectEveryoneRagdollsWhenShot : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; + private: - std::set peds; + std::set peds; }; class EffectNearbyPedIsEnemy : public Effect @@ -647,7 +674,7 @@ class EffectNearbyPedIsEnemy : public Effect name = "Nearby Ped Is Player's Enemy"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -661,11 +688,13 @@ class EffectExplosiveCombat : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; + private: - std::set peds; + std::set peds; }; class EffectODriscolls : public Effect @@ -677,7 +706,7 @@ class EffectODriscolls : public Effect name = "Spawn O'Driscoll Boys"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -690,7 +719,7 @@ class EffectBanditoKidnapsPlayer : public Effect name = "Bandito Kidnaps Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -703,10 +732,11 @@ class EffectSpawnTwitchViewer : public Effect name = "Spawn Random Twitch Viewer"; bTimed = false; } - + virtual void OnActivate() override; - + void Spawn(std::string name); + private: Ped ped = 0; }; @@ -721,7 +751,7 @@ class EffectEveryoneIsLenny : public Effect name = "Nearby Peds Are Lenny"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -735,21 +765,25 @@ class EffectSpawnExtremeEvilMicah : public Effect bTimed = true; EffectDuration = 45; } - + virtual void OnActivate() override; + virtual void OnTick() override; + private: Vector3 lastVec; Ped micahPed; }; -std::vector GetNearbyPeds(int32_t Max); +std::vector GetNearbyPeds(int32_t Max); + void RemovePedFromVeh(Ped ped); void RemoveAllPedWeapons(Ped ped); void MarkPedAsCompanion(Ped ped); + void MarkPedAsEnemy(Ped ped); void FixEntityInCutscene(Entity entity); \ No newline at end of file diff --git a/src/Effects/player.cpp b/src/Effects/player.cpp index 60b03bb..591e9c1 100644 --- a/src/Effects/player.cpp +++ b/src/Effects/player.cpp @@ -7,11 +7,11 @@ void EffectLaunchPlayerUp::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Entity entityToUse = playerPed; - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { entityToUse = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); @@ -26,21 +26,21 @@ void EffectLaunchPlayerUp::OnActivate() WAIT(75); PED::SET_PED_TO_RAGDOLL(playerPed, 5000, 5000, 0, true, true, false); } - - + + Vector3 entityVelocity = ENTITY::GET_ENTITY_VELOCITY(entityToUse, 0); - + ENTITY::SET_ENTITY_VELOCITY(entityToUse, entityVelocity.x, entityVelocity.y, 35.0f); } void EffectToTheStars::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Entity entityToUse = playerPed; - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { entityToUse = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); @@ -53,18 +53,18 @@ void EffectToTheStars::OnActivate() { PED::SET_PED_TO_RAGDOLL(playerPed, 10000, 10000, 0, true, true, false); } - + Vector3 entityLocation = ENTITY::GET_ENTITY_COORDS(entityToUse, true, 0); - + ENTITY::SET_ENTITY_COORDS(entityToUse, entityLocation.x, entityLocation.y, 800.0f, 0, 0, 0, 0); } void TeleportPlayerTo(float X, float Y, float Z) { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Entity entityToUse = playerPed; - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { entityToUse = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); @@ -73,40 +73,39 @@ void TeleportPlayerTo(float X, float Y, float Z) { entityToUse = PED::GET_MOUNT(playerPed); } - + ENTITY::SET_ENTITY_COORDS(entityToUse, X, Y, Z, 0, 0, 0, 0); } void DisableAllMovements() { - static std::vector keys = { - GET_HASH("INPUT_MOVE_LEFT_ONLY"), GET_HASH("INPUT_MOVE_RIGHT_ONLY"), - GET_HASH("INPUT_MOVE_LR"), GET_HASH("INPUT_VEH_MOVE_LR"), - GET_HASH("INPUT_MOVE_LEFT"), GET_HASH("INPUT_MOVE_RIGHT"), - GET_HASH("INPUT_HORSE_MOVE_LEFT_ONLY"), GET_HASH("INPUT_VEH_CAR_TURN_LEFT_ONLY"), - GET_HASH("INPUT_VEH_DRAFT_TURN_LEFT_ONLY"), GET_HASH("INPUT_VEH_BOAT_TURN_LEFT_ONLY"), - GET_HASH("INPUT_VEH_MOVE_LEFT_ONLY"), GET_HASH("INPUT_FRONTEND_AXIS_X"), - GET_HASH("INPUT_HORSE_MOVE_LR"), GET_HASH("INPUT_HORSE_MOVE_RIGHT_ONLY"), - GET_HASH("INPUT_VEH_CAR_TURN_LR"), GET_HASH("INPUT_VEH_DRAFT_TURN_RIGHT_ONLY"), - GET_HASH("INPUT_VEH_CAR_TURN_RIGHT_ONLY"), GET_HASH("INPUT_VEH_MOVE_RIGHT_ONLY"), - GET_HASH("INPUT_VEH_DRAFT_TURN_LR"), GET_HASH("INPUT_VEH_BOAT_TURN_LR"), - GET_HASH("INPUT_VEH_BOAT_TURN_RIGHT_ONLY"), GET_HASH("INPUT_FRONTEND_NAV_RIGHT"), - - GET_HASH("INPUT_MOVE_UP_ONLY"), GET_HASH("INPUT_MOVE_DOWN_ONLY"), - GET_HASH("INPUT_VEH_ACCELERATE"), GET_HASH("INPUT_VEH_BRAKE"), - GET_HASH("INPUT_MOVE_UP"), GET_HASH("INPUT_MOVE_DOWN"), - GET_HASH("INPUT_MOVE_UD"), GET_HASH("INPUT_FRONTEND_AXIS_Y"), - GET_HASH("INPUT_HORSE_MOVE_DOWN_ONLY"), GET_HASH("INPUT_HORSE_MOVE_UD"), - GET_HASH("INPUT_VEH_MOVE_DOWN_ONLY"), GET_HASH("INPUT_VEH_DRAFT_MOVE_UD"), - GET_HASH("INPUT_HORSE_MOVE_UP_ONLY"), GET_HASH("INPUT_VEH_MOVE_UP_ONLY"), - GET_HASH("INPUT_VEH_MOVE_UD"), GET_HASH("INPUT_FRONTEND_NAV_UP"), - GET_HASH("INPUT_HORSE_SPRINT"), GET_HASH("INPUT_VEH_ACCELERATE"), - GET_HASH("INPUT_HORSE_STOP"), GET_HASH("INPUT_VEH_HANDCART_BRAKE"), - GET_HASH("INPUT_VEH_BOAT_BRAKE"), GET_HASH("INPUT_VEH_HANDBRAKE"), - GET_HASH("INPUT_VEH_BRAKE"), GET_HASH("INPUT_VEH_CAR_BRAKE") - }; - - + static std::vector keys = {GET_HASH("INPUT_MOVE_LEFT_ONLY"), GET_HASH("INPUT_MOVE_RIGHT_ONLY"), + GET_HASH("INPUT_MOVE_LR"), GET_HASH("INPUT_VEH_MOVE_LR"), + GET_HASH("INPUT_MOVE_LEFT"), GET_HASH("INPUT_MOVE_RIGHT"), + GET_HASH("INPUT_HORSE_MOVE_LEFT_ONLY"), GET_HASH("INPUT_VEH_CAR_TURN_LEFT_ONLY"), + GET_HASH("INPUT_VEH_DRAFT_TURN_LEFT_ONLY"), + GET_HASH("INPUT_VEH_BOAT_TURN_LEFT_ONLY"), GET_HASH("INPUT_VEH_MOVE_LEFT_ONLY"), + GET_HASH("INPUT_FRONTEND_AXIS_X"), GET_HASH("INPUT_HORSE_MOVE_LR"), + GET_HASH("INPUT_HORSE_MOVE_RIGHT_ONLY"), GET_HASH("INPUT_VEH_CAR_TURN_LR"), + GET_HASH("INPUT_VEH_DRAFT_TURN_RIGHT_ONLY"), + GET_HASH("INPUT_VEH_CAR_TURN_RIGHT_ONLY"), GET_HASH("INPUT_VEH_MOVE_RIGHT_ONLY"), + GET_HASH("INPUT_VEH_DRAFT_TURN_LR"), GET_HASH("INPUT_VEH_BOAT_TURN_LR"), + GET_HASH("INPUT_VEH_BOAT_TURN_RIGHT_ONLY"), GET_HASH("INPUT_FRONTEND_NAV_RIGHT"), + + GET_HASH("INPUT_MOVE_UP_ONLY"), GET_HASH("INPUT_MOVE_DOWN_ONLY"), + GET_HASH("INPUT_VEH_ACCELERATE"), GET_HASH("INPUT_VEH_BRAKE"), + GET_HASH("INPUT_MOVE_UP"), GET_HASH("INPUT_MOVE_DOWN"), GET_HASH("INPUT_MOVE_UD"), + GET_HASH("INPUT_FRONTEND_AXIS_Y"), GET_HASH("INPUT_HORSE_MOVE_DOWN_ONLY"), + GET_HASH("INPUT_HORSE_MOVE_UD"), GET_HASH("INPUT_VEH_MOVE_DOWN_ONLY"), + GET_HASH("INPUT_VEH_DRAFT_MOVE_UD"), GET_HASH("INPUT_HORSE_MOVE_UP_ONLY"), + GET_HASH("INPUT_VEH_MOVE_UP_ONLY"), GET_HASH("INPUT_VEH_MOVE_UD"), + GET_HASH("INPUT_FRONTEND_NAV_UP"), GET_HASH("INPUT_HORSE_SPRINT"), + GET_HASH("INPUT_VEH_ACCELERATE"), GET_HASH("INPUT_HORSE_STOP"), + GET_HASH("INPUT_VEH_HANDCART_BRAKE"), GET_HASH("INPUT_VEH_BOAT_BRAKE"), + GET_HASH("INPUT_VEH_HANDBRAKE"), GET_HASH("INPUT_VEH_BRAKE"), + GET_HASH("INPUT_VEH_CAR_BRAKE")}; + + for (Hash key : keys) { CONTROLS::DISABLE_CONTROL_ACTION(0, key, true); @@ -127,8 +126,8 @@ void EffectBankruptcy::OnActivate() void EffectGiveRifle::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_RIFLE_SPRINGFIELD"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_RIFLE_SPRINGFIELD"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 100); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, weaponHash, 1, 0, 0, 0); @@ -137,8 +136,8 @@ void EffectGiveRifle::OnActivate() void EffectGiveRevolver::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_REVOLVER_SCHOFIELD"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_REVOLVER_SCHOFIELD"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 100); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, weaponHash, 1, 0, 0, 0); @@ -147,44 +146,40 @@ void EffectGiveRevolver::OnActivate() void EffectNoAmmo::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** REMOVE_ALL_PED_AMMO */ invoke(0x1B83C0DEEBCBB214, playerPed); - - static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_UNARMED"); + + static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_UNARMED"); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, unarmed, 1, 0, 0, 0); } void EffectRemoveAllWeapons::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + RemoveAllPedWeapons(playerPed); } void EffectDropWeapon::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - - static std::set importantWeapons = - { - GET_HASH("WEAPON_KIT_CAMERA"), - GET_HASH("WEAPON_LASSO"), - GET_HASH("WEAPON_FISHINGROD"), - GET_HASH("WEAPON_MELEE_LANTERN_ELECTRIC"), - GET_HASH("WEAPON_MELEE_KNIFE") - }; - - static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_UNARMED"); + + static std::set importantWeapons = {GET_HASH("WEAPON_KIT_CAMERA"), GET_HASH("WEAPON_LASSO"), + GET_HASH("WEAPON_FISHINGROD"), GET_HASH("WEAPON_MELEE_LANTERN_ELECTRIC"), + GET_HASH("WEAPON_MELEE_KNIFE")}; + + static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_UNARMED"); Hash weaponHash = 0; - - if (WEAPON::GET_CURRENT_PED_WEAPON(playerPed, &weaponHash, 0, 0, 0) && WEAPON::IS_WEAPON_VALID(weaponHash) && weaponHash != unarmed) + + if (WEAPON::GET_CURRENT_PED_WEAPON(playerPed, &weaponHash, 0, 0, 0) && WEAPON::IS_WEAPON_VALID(weaponHash) && + weaponHash != unarmed) { if (importantWeapons.contains(weaponHash)) { return; } - + WEAPON::SET_PED_DROPS_INVENTORY_WEAPON(playerPed, weaponHash, 0.0f, 0.0f, 0.0f, 0); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, unarmed, 1, 0, 0, 0); } @@ -193,23 +188,23 @@ void EffectDropWeapon::OnActivate() void EffectHealPlayer::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + int maxHealth = PED::GET_PED_MAX_HEALTH(playerPed); - + ENTITY::SET_ENTITY_HEALTH(playerPed, maxHealth, 0); } void EffectAlmostDead::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + ENTITY::SET_ENTITY_HEALTH(playerPed, 1, 0); } void EffectRestoreStamina::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + PLAYER::RESTORE_PLAYER_STAMINA(PLAYER::PLAYER_ID(), 1.0f); } @@ -224,24 +219,19 @@ void EffectRagdoll::OnActivate() void EffectGiveRandomWeapon::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - - static std::set importantWeapons = - { - GET_HASH("WEAPON_KIT_CAMERA"), - GET_HASH("WEAPON_LASSO"), - GET_HASH("WEAPON_FISHINGROD"), - GET_HASH("WEAPON_MELEE_LANTERN_ELECTRIC"), - GET_HASH("WEAPON_MELEE_KNIFE") - }; - + + static std::set importantWeapons = {GET_HASH("WEAPON_KIT_CAMERA"), GET_HASH("WEAPON_LASSO"), + GET_HASH("WEAPON_FISHINGROD"), GET_HASH("WEAPON_MELEE_LANTERN_ELECTRIC"), + GET_HASH("WEAPON_MELEE_KNIFE")}; + for (auto wHash : importantWeapons) { WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, wHash, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, wHash, 100); } - + int32_t weaponID = rand() % Effect::WeaponHashes.size(); - + Hash weaponHash = Effect::WeaponHashes[weaponID]; WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 100); @@ -252,14 +242,14 @@ void EffectSetDrunk::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); AUDIO::SET_PED_IS_DRUNK(playerPed, true); - CAM::SHAKE_GAMEPLAY_CAM((char*)"DRUNK_SHAKE", 1.0f); + CAM::SHAKE_GAMEPLAY_CAM((char*) "DRUNK_SHAKE", 1.0f); PED::SET_PED_CONFIG_FLAG(playerPed, 100, true); - GRAPHICS::ANIMPOSTFX_PLAY((char*)"PlayerDrunk01"); - + GRAPHICS::ANIMPOSTFX_PLAY((char*) "PlayerDrunk01"); + invoke(0x406CCF555B04FAD3, playerPed, true, 1.0f); - + /** Set walking style */ - invoke(0x89F5E7ADECCCB49C, playerPed , "very_drunk"); + invoke(0x89F5E7ADECCCB49C, playerPed, "very_drunk"); } void EffectSetDrunk::OnDeactivate() @@ -268,8 +258,8 @@ void EffectSetDrunk::OnDeactivate() AUDIO::SET_PED_IS_DRUNK(playerPed, false); CAM::STOP_GAMEPLAY_CAM_SHAKING(true); PED::SET_PED_CONFIG_FLAG(playerPed, 100, false); - GRAPHICS::ANIMPOSTFX_STOP((char*)"PlayerDrunk01"); - + GRAPHICS::ANIMPOSTFX_STOP((char*) "PlayerDrunk01"); + invoke(0x406CCF555B04FAD3, playerPed, false, 0.0f); invoke(0x923583741DC87BCE, playerPed, "arthur_healthy"); invoke(0x89F5E7ADECCCB49C, playerPed, "default"); @@ -278,7 +268,7 @@ void EffectSetDrunk::OnDeactivate() void EffectSetDrunk::OnTick() { Effect::OnTick(); - + if (TimerTick(7000)) { PED::SET_PED_TO_RAGDOLL(PLAYER::PLAYER_PED_ID(), 1000, 1000, 0, true, true, false); @@ -303,26 +293,26 @@ void EffectIncreaseBounty::OnActivate() void EffectRemoveCurrentVehicle::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(veh, false, false); - + VEHICLE::DELETE_VEHICLE(&veh); } else if (PED::IS_PED_ON_MOUNT(playerPed)) { Ped mount = PED::GET_MOUNT(playerPed); - + /** _REMOVE_PED_FROM_MOUNT */ invoke(0x5337B721C51883A9, playerPed, 0, 0); - + if (!ENTITY::IS_ENTITY_A_MISSION_ENTITY(mount)) { ENTITY::SET_ENTITY_AS_MISSION_ENTITY(mount, false, false); - + PED::DELETE_PED(&mount); } } @@ -331,8 +321,8 @@ void EffectRemoveCurrentVehicle::OnActivate() void EffectGiveLasso::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_LASSO"); + + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_LASSO"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 100, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 100); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, weaponHash, 1, 0, 0, 0); @@ -348,52 +338,52 @@ void EffectIgnitePlayer::OnActivate() void EffectKickflip::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + ENTITY::SET_ENTITY_COORDS(playerPed, vec.x, vec.y, vec.z + 2.0f, false, false, false, false); - + Vector3 vel = ENTITY::GET_ENTITY_VELOCITY(veh, 0); - + ENTITY::SET_ENTITY_VELOCITY(playerPed, vel.x, vel.y, vel.z); } - + FixEntityInCutscene(playerPed); WAIT(75); - + PED::SET_PED_TO_RAGDOLL(playerPed, 1000, 1000, 0, true, true, false); - + ENTITY::APPLY_FORCE_TO_ENTITY(playerPed, 1, 0, 0, 10, 2, 0, 0, 0, true, true, true, false, true); } void SetPlayerModel(const char* model, uint64_t* ptr1_val, uint64_t* ptr2_val) { Hash hash = GET_HASH(model); - + LoadModel(hash); - + ChaosMod::Singleton->SavePlayerAttributes(); - + ChaosMod::UpdatePlayerSkinHash(); - + PLAYER::SET_PLAYER_MODEL(PLAYER::PLAYER_ID(), hash, 1); *getGlobalPtr(0x23) = PLAYER::PLAYER_PED_ID(); - - + + uint64_t* ptr1 = getGlobalPtr(0x28) + 0x27; uint64_t* ptr2 = getGlobalPtr(0x1D890E) + 2; - + *ptr1 = hash; *ptr2 = hash; Ped playerPed = PLAYER::PLAYER_PED_ID();; *getGlobalPtr(0x23) = playerPed; - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(hash); ENTITY::SET_ENTITY_COLLISION(playerPed, true, true); ENTITY::SET_ENTITY_DYNAMIC(playerPed, true); @@ -424,18 +414,18 @@ void EffectLightningWeapons::OnDeactivate() void EffectLightningWeapons::OnTick() { Vector3 vec; - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + bool bCoordValid = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(playerPed, &vec); - + if (!bCoordValid || (vec.x == lastVec.x && vec.y == lastVec.y && vec.z == lastVec.z)) { return; } - + lastVec = vec; - + /** _FORCE_LIGHTNING_FLASH_AT_COORDS */ invoke(0x67943537D179597C, vec.x, vec.y, vec.z); } @@ -443,108 +433,109 @@ void EffectLightningWeapons::OnTick() void IEffectSkinChange::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + ENTITY::SET_ENTITY_COORDS(playerPed, vec.x, vec.y, vec.z + 2.0f, false, false, false, false); } else if (PED::IS_PED_ON_MOUNT(playerPed)) { Ped mount = PED::GET_MOUNT(playerPed); - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(mount, true, true); - + /** _REMOVE_PED_FROM_MOUNT */ invoke(0x5337B721C51883A9, playerPed, 1, 0); } - + SetPlayerModel(this->skinToSet, &oldSkin1, &oldSkin2); } void IEffectSkinChange::OnDeactivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_ON_MOUNT(playerPed)) { Ped mount = PED::GET_MOUNT(playerPed); - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(mount, true, true); - + /** _REMOVE_PED_FROM_MOUNT */ invoke(0x5337B721C51883A9, playerPed, 0, 0); } - + ResetPlayerModel(oldSkin1, oldSkin2); } void EffectHonorGood::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + (*getGlobalPtr(0x2BA2)) = 0; - + int honor = *getGlobalPtr(0x2BA2); - + *getGlobalPtr(1347477 + 155 + 1) = 240; } -void EffectHonorBad::OnActivate() +void EffectHonorBad::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + (*getGlobalPtr(0x2BA2)) = 0; - + int honor = *getGlobalPtr(0x2BA2); - + *getGlobalPtr(1347477 + 155 + 1) = -240; } void EffectHonorReset::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + (*getGlobalPtr(0x2BA2)) = 0; - + int honor = *getGlobalPtr(0x2BA2); - + *getGlobalPtr(1347477 + 155 + 1) = 40; } void EffectPlayerSleep::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + ENTITY::SET_ENTITY_COORDS(playerPed, vec.x, vec.y, vec.z + 2.0f, false, false, false, false); } - + FixEntityInCutscene(playerPed); - + WAIT(75); - - PED::SET_PED_TO_RAGDOLL(playerPed, EffectDuration * 1000 + 3000, EffectDuration * 1000 + 3000, 0, true, true, false); + + PED::SET_PED_TO_RAGDOLL(playerPed, EffectDuration * 1000 + 3000, EffectDuration * 1000 + 3000, 0, true, true, + false); } void EffectPlayerIsMinion::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, playerPed, 0.4f); } @@ -554,7 +545,7 @@ void EffectPlayerIsMinion::OnTick() if (TimerTick(500)) { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, playerPed, 0.4f); } @@ -563,9 +554,9 @@ void EffectPlayerIsMinion::OnTick() void EffectPlayerIsMinion::OnDeactivate() { Effect::OnDeactivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + /** _SET_PED_SCALE */ invoke(0x25ACFC650B65C538, playerPed, 1.0f); } @@ -573,15 +564,15 @@ void EffectPlayerIsMinion::OnDeactivate() void EffectTeleportToWaypoint::OnActivate() { Effect::OnDeactivate(); - + Entity entity = PLAYER::PLAYER_PED_ID(); - - + + if (!RADAR::IS_WAYPOINT_ACTIVE()) { return; } - + if (PED::IS_PED_IN_ANY_VEHICLE(entity, true)) { entity = PED::GET_VEHICLE_PED_IS_IN(entity, false); @@ -590,18 +581,16 @@ void EffectTeleportToWaypoint::OnActivate() { entity = PED::GET_MOUNT(entity); } - + Vector3 coords = RADAR::GET_WAYPOINT_COORDS_3D(); - + bool bUpdatedCoords = GAMEPLAY::GET_GROUND_Z_FOR_3D_COORD(coords.x, coords.y, 100.0, &coords.z, FALSE); - + if (!bUpdatedCoords) { - static const float groundCheckHeight[] = { - 100.0, 150.0, 50.0, 0.0, 200.0, 250.0, 300.0, 350.0, 400.0, - 450.0, 500.0, 550.0, 600.0, 650.0, 700.0, 750.0, 800.0 - }; - + static const float groundCheckHeight[] = {100.0, 150.0, 50.0, 0.0, 200.0, 250.0, 300.0, 350.0, 400.0, 450.0, + 500.0, 550.0, 600.0, 650.0, 700.0, 750.0, 800.0}; + for (float height : groundCheckHeight) { ENTITY::SET_ENTITY_COORDS_NO_OFFSET(entity, coords.x, coords.y, height, 0, 0, 1); @@ -613,7 +602,7 @@ void EffectTeleportToWaypoint::OnActivate() } } } - + ENTITY::SET_ENTITY_COORDS(entity, coords.x, coords.y, coords.z, false, false, false, false); } @@ -631,18 +620,18 @@ void EffectExplosiveWeapons::OnDeactivate() void EffectExplosiveWeapons::OnTick() { Vector3 vec; - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + bool bCoordValid = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(playerPed, &vec); - + if (!bCoordValid || (vec.x == lastVec.x && vec.y == lastVec.y && vec.z == lastVec.z)) { return; } - + lastVec = vec; - + FIRE::ADD_EXPLOSION(vec.x, vec.y, vec.z, 27, 1.0f, true, false, 1.0f); } @@ -656,20 +645,13 @@ void EffectBloodTrails::OnTick() void EffectSetRandomWalkStyle::OnActivate() { - static std::vector walkStyles = { - "cower_known", - "injured_left_leg" - "injured_general", - "injured_right_leg", - "injured_left_arm", - "injured_right_arm", - "injured_torso", - "very_drunk", - "moderate_drunk" - }; - + static std::vector walkStyles = {"cower_known", "injured_left_leg" + "injured_general", "injured_right_leg", + "injured_left_arm", "injured_right_arm", "injured_torso", + "very_drunk", "moderate_drunk"}; + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + invoke(0x923583741DC87BCE, playerPed, "default"); invoke(0x89F5E7ADECCCB49C, playerPed, walkStyles[rand() % walkStyles.size()]); } @@ -677,7 +659,7 @@ void EffectSetRandomWalkStyle::OnActivate() void EffectSetRandomWalkStyle::OnDeactivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + invoke(0x923583741DC87BCE, playerPed, "arthur_healthy"); invoke(0x89F5E7ADECCCB49C, playerPed, "default"); } @@ -696,25 +678,25 @@ void EffectTeleportWeapons::OnDeactivate() void EffectTeleportWeapons::OnTick() { Vector3 vec; - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + bool bCoordValid = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(playerPed, &vec); - + if (!bCoordValid || (vec.x == lastVec.x && vec.y == lastVec.y && vec.z == lastVec.z)) { return; } - + lastVec = vec; - + ENTITY::SET_ENTITY_COORDS(playerPed, vec.x, vec.y, vec.z + 0.0f, false, false, false, false); } void EffectGiveSniperRifle::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_SNIPERRIFLE_ROLLINGBLOCK"); + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_SNIPERRIFLE_ROLLINGBLOCK"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 35, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 35); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, weaponHash, 1, 0, 0, 0); @@ -723,7 +705,7 @@ void EffectGiveSniperRifle::OnActivate() void EffectGiveDynamite::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_THROWN_DYNAMITE"); + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_THROWN_DYNAMITE"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 3, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 3); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, weaponHash, 1, 0, 0, 0); @@ -733,7 +715,7 @@ void EffectGiveDynamite::OnActivate() void EffectThrowingKnives::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_THROWN_THROWING_KNIVES"); + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_THROWN_THROWING_KNIVES"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 10, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 10); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, weaponHash, 1, 0, 0, 0); @@ -742,7 +724,7 @@ void EffectThrowingKnives::OnActivate() void EffectTeleportFewMeters::OnActivate() { Entity entity = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(entity, true)) { entity = PED::GET_VEHICLE_PED_IS_IN(entity, false); @@ -751,18 +733,16 @@ void EffectTeleportFewMeters::OnActivate() { entity = PED::GET_MOUNT(entity); } - + Vector3 vec = GetRandomCoordInRange(ENTITY::GET_ENTITY_COORDS(entity, true, 0), 10); - + bool bUpdatedCoords = GAMEPLAY::GET_GROUND_Z_FOR_3D_COORD(vec.x, vec.y, vec.z, &vec.z, FALSE); - + if (!bUpdatedCoords) { - static const float groundCheckHeight[] = { - 100.0, 150.0, 50.0, 0.0, 200.0, 250.0, 300.0, 350.0, 400.0, - 450.0, 500.0, 550.0, 600.0, 650.0, 700.0, 750.0, 800.0 - }; - + static const float groundCheckHeight[] = {100.0, 150.0, 50.0, 0.0, 200.0, 250.0, 300.0, 350.0, 400.0, 450.0, + 500.0, 550.0, 600.0, 650.0, 700.0, 750.0, 800.0}; + for (float height : groundCheckHeight) { ENTITY::SET_ENTITY_COORDS_NO_OFFSET(entity, vec.x, vec.y, height, 0, 0, 1); @@ -774,54 +754,54 @@ void EffectTeleportFewMeters::OnActivate() } } } - + ENTITY::SET_ENTITY_COORDS(entity, vec.x, vec.y, vec.z, false, false, false, false); } void EffectBlackingOut::OnActivate() { Effect::OnDeactivate(); - - GRAPHICS::ANIMPOSTFX_PLAY((char*)"PlayerWakeUpInterrogation"); - + + GRAPHICS::ANIMPOSTFX_PLAY((char*) "PlayerWakeUpInterrogation"); + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + ENTITY::SET_ENTITY_COORDS(playerPed, vec.x, vec.y, vec.z + 2.0f, false, false, false, false); } - + FixEntityInCutscene(playerPed); WAIT(75); - + PED::SET_PED_TO_RAGDOLL(playerPed, 5000, 5000, 0, true, true, false); } void EffectRandomClothes::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + int32_t outfitID = rand() % 58; - + if (outfitID == 25 || outfitID == 17 || outfitID == 14 || outfitID == 28) { outfitID = 0; } - + invoke(0x77FF8D35EEC6BBC4, playerPed, outfitID, false); } void EffectMostWanted::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Player player = PLAYER::PLAYER_ID(); - - invoke(0xF60386770878A98F, player, GAMEPLAY::GET_HASH_KEY((char*)"CRIME_ASSAULT_LAW"), 0, 0, 1); + + invoke(0xF60386770878A98F, player, GAMEPLAY::GET_HASH_KEY((char*) "CRIME_ASSAULT_LAW"), 0, 0, 1); int priceOnHead = PURSUIT::GET_PLAYER_PRICE_ON_A_HEAD(player); PURSUIT::SET_PLAYER_PRICE_ON_A_HEAD(player, priceOnHead + 50 * 100); } @@ -829,19 +809,19 @@ void EffectMostWanted::OnActivate() void EffectPigSkin::OnActivate() { IEffectSkinChange::OnActivate(); - + invoke(0x77FF8D35EEC6BBC4, PLAYER::PLAYER_PED_ID(), rand() % 4, false); } void EffectSetWinterOutfit::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Hash playerSkin = ENTITY::GET_ENTITY_MODEL(playerPed); - - static Hash skinArthur = GAMEPLAY::GET_HASH_KEY((char*)"PLAYER_ZERO"); - static Hash skinJohn = GAMEPLAY::GET_HASH_KEY((char*)"PLAYER_THREE"); - + + static Hash skinArthur = GAMEPLAY::GET_HASH_KEY((char*) "PLAYER_ZERO"); + static Hash skinJohn = GAMEPLAY::GET_HASH_KEY((char*) "PLAYER_THREE"); + if (playerSkin == skinArthur) { invoke(0x77FF8D35EEC6BBC4, playerPed, 1, false); @@ -860,21 +840,21 @@ void EffectSuperJump::OnTick() void EffectDisableLeftRight::OnTick() { - static std::vector keys = { - GET_HASH("INPUT_MOVE_LEFT_ONLY"), GET_HASH("INPUT_MOVE_RIGHT_ONLY"), - GET_HASH("INPUT_MOVE_LR"), GET_HASH("INPUT_VEH_MOVE_LR"), - GET_HASH("INPUT_MOVE_LEFT"), GET_HASH("INPUT_MOVE_RIGHT"), - GET_HASH("INPUT_HORSE_MOVE_LEFT_ONLY"), GET_HASH("INPUT_VEH_CAR_TURN_LEFT_ONLY"), - GET_HASH("INPUT_VEH_DRAFT_TURN_LEFT_ONLY"), GET_HASH("INPUT_VEH_BOAT_TURN_LEFT_ONLY"), - GET_HASH("INPUT_VEH_MOVE_LEFT_ONLY"), GET_HASH("INPUT_FRONTEND_AXIS_X"), - GET_HASH("INPUT_HORSE_MOVE_LR"), GET_HASH("INPUT_HORSE_MOVE_RIGHT_ONLY"), - GET_HASH("INPUT_VEH_CAR_TURN_LR"), GET_HASH("INPUT_VEH_DRAFT_TURN_RIGHT_ONLY"), - GET_HASH("INPUT_VEH_CAR_TURN_RIGHT_ONLY"), GET_HASH("INPUT_VEH_MOVE_RIGHT_ONLY"), - GET_HASH("INPUT_VEH_DRAFT_TURN_LR"), GET_HASH("INPUT_VEH_BOAT_TURN_LR"), - GET_HASH("INPUT_VEH_BOAT_TURN_RIGHT_ONLY"), GET_HASH("INPUT_FRONTEND_NAV_RIGHT") - + static std::vector keys = {GET_HASH("INPUT_MOVE_LEFT_ONLY"), GET_HASH("INPUT_MOVE_RIGHT_ONLY"), + GET_HASH("INPUT_MOVE_LR"), GET_HASH("INPUT_VEH_MOVE_LR"), + GET_HASH("INPUT_MOVE_LEFT"), GET_HASH("INPUT_MOVE_RIGHT"), + GET_HASH("INPUT_HORSE_MOVE_LEFT_ONLY"), GET_HASH("INPUT_VEH_CAR_TURN_LEFT_ONLY"), + GET_HASH("INPUT_VEH_DRAFT_TURN_LEFT_ONLY"), + GET_HASH("INPUT_VEH_BOAT_TURN_LEFT_ONLY"), GET_HASH("INPUT_VEH_MOVE_LEFT_ONLY"), + GET_HASH("INPUT_FRONTEND_AXIS_X"), GET_HASH("INPUT_HORSE_MOVE_LR"), + GET_HASH("INPUT_HORSE_MOVE_RIGHT_ONLY"), GET_HASH("INPUT_VEH_CAR_TURN_LR"), + GET_HASH("INPUT_VEH_DRAFT_TURN_RIGHT_ONLY"), + GET_HASH("INPUT_VEH_CAR_TURN_RIGHT_ONLY"), GET_HASH("INPUT_VEH_MOVE_RIGHT_ONLY"), + GET_HASH("INPUT_VEH_DRAFT_TURN_LR"), GET_HASH("INPUT_VEH_BOAT_TURN_LR"), + GET_HASH("INPUT_VEH_BOAT_TURN_RIGHT_ONLY"), GET_HASH("INPUT_FRONTEND_NAV_RIGHT") + }; - + for (Hash key : keys) { CONTROLS::DISABLE_CONTROL_ACTION(0, key, true); @@ -883,21 +863,19 @@ void EffectDisableLeftRight::OnTick() void EffectDisableForwardBackward::OnTick() { - static std::vector keys = { - GET_HASH("INPUT_MOVE_UP_ONLY"), GET_HASH("INPUT_MOVE_DOWN_ONLY"), - GET_HASH("INPUT_VEH_ACCELERATE"), GET_HASH("INPUT_VEH_BRAKE"), - GET_HASH("INPUT_MOVE_UP"), GET_HASH("INPUT_MOVE_DOWN"), - GET_HASH("INPUT_MOVE_UD"), GET_HASH("INPUT_FRONTEND_AXIS_Y"), - GET_HASH("INPUT_HORSE_MOVE_DOWN_ONLY"), GET_HASH("INPUT_HORSE_MOVE_UD"), - GET_HASH("INPUT_VEH_MOVE_DOWN_ONLY"), GET_HASH("INPUT_VEH_DRAFT_MOVE_UD"), - GET_HASH("INPUT_HORSE_MOVE_UP_ONLY"), GET_HASH("INPUT_VEH_MOVE_UP_ONLY"), - GET_HASH("INPUT_VEH_MOVE_UD"), GET_HASH("INPUT_FRONTEND_NAV_UP"), - GET_HASH("INPUT_HORSE_SPRINT"), GET_HASH("INPUT_VEH_ACCELERATE"), - GET_HASH("INPUT_HORSE_STOP"), GET_HASH("INPUT_VEH_HANDCART_BRAKE"), - GET_HASH("INPUT_VEH_BOAT_BRAKE"), GET_HASH("INPUT_VEH_HANDBRAKE"), - GET_HASH("INPUT_VEH_BRAKE"), GET_HASH("INPUT_VEH_CAR_BRAKE") - }; - + static std::vector keys = {GET_HASH("INPUT_MOVE_UP_ONLY"), GET_HASH("INPUT_MOVE_DOWN_ONLY"), + GET_HASH("INPUT_VEH_ACCELERATE"), GET_HASH("INPUT_VEH_BRAKE"), + GET_HASH("INPUT_MOVE_UP"), GET_HASH("INPUT_MOVE_DOWN"), GET_HASH("INPUT_MOVE_UD"), + GET_HASH("INPUT_FRONTEND_AXIS_Y"), GET_HASH("INPUT_HORSE_MOVE_DOWN_ONLY"), + GET_HASH("INPUT_HORSE_MOVE_UD"), GET_HASH("INPUT_VEH_MOVE_DOWN_ONLY"), + GET_HASH("INPUT_VEH_DRAFT_MOVE_UD"), GET_HASH("INPUT_HORSE_MOVE_UP_ONLY"), + GET_HASH("INPUT_VEH_MOVE_UP_ONLY"), GET_HASH("INPUT_VEH_MOVE_UD"), + GET_HASH("INPUT_FRONTEND_NAV_UP"), GET_HASH("INPUT_HORSE_SPRINT"), + GET_HASH("INPUT_VEH_ACCELERATE"), GET_HASH("INPUT_HORSE_STOP"), + GET_HASH("INPUT_VEH_HANDCART_BRAKE"), GET_HASH("INPUT_VEH_BOAT_BRAKE"), + GET_HASH("INPUT_VEH_HANDBRAKE"), GET_HASH("INPUT_VEH_BRAKE"), + GET_HASH("INPUT_VEH_CAR_BRAKE")}; + for (Hash key : keys) { CONTROLS::DISABLE_CONTROL_ACTION(0, key, true); @@ -939,7 +917,7 @@ void EffectDisableAiming::OnDeactivate() void EffectDisableAiming::OnTick() { - CONTROLS::DISABLE_CONTROL_ACTION(0, GAMEPLAY::GET_HASH_KEY((char*)"INPUT_AIM"), true); + CONTROLS::DISABLE_CONTROL_ACTION(0, GAMEPLAY::GET_HASH_KEY((char*) "INPUT_AIM"), true); } void EffectRandomHonor::OnActivate() @@ -950,9 +928,9 @@ void EffectRandomHonor::OnActivate() void EffectInvertVelocity::OnActivate() { Entity entity = PLAYER::PLAYER_PED_ID(); - + bool bUsingVehicle = PED::IS_PED_IN_ANY_VEHICLE(entity, true); - + if (bUsingVehicle) { entity = PED::GET_VEHICLE_PED_IS_IN(entity, false); @@ -961,11 +939,11 @@ void EffectInvertVelocity::OnActivate() { entity = PED::GET_MOUNT(entity); } - + float multiplier = -3.0f; - + Vector3 vel = ENTITY::GET_ENTITY_VELOCITY(entity, 0); - + if (!bUsingVehicle) { FixEntityInCutscene(entity); @@ -976,21 +954,21 @@ void EffectInvertVelocity::OnActivate() { multiplier = -5.0f; } - + vel.x *= multiplier; vel.y *= multiplier; vel.z *= multiplier; - - + + ENTITY::SET_ENTITY_VELOCITY(entity, vel.x, vel.y, vel.z); } void EffectIncreaseVelocity::OnActivate() { Entity entity = PLAYER::PLAYER_PED_ID(); - + bool bUsingVehicle = PED::IS_PED_IN_ANY_VEHICLE(entity, true); - + if (bUsingVehicle) { entity = PED::GET_VEHICLE_PED_IS_IN(entity, false); @@ -999,22 +977,22 @@ void EffectIncreaseVelocity::OnActivate() { entity = PED::GET_MOUNT(entity); } - + float multiplier = 3.0f; Vector3 vel = ENTITY::GET_ENTITY_VELOCITY(entity, 0); - + if (!bUsingVehicle) { FixEntityInCutscene(entity); WAIT(75); PED::SET_PED_TO_RAGDOLL(entity, 1000, 1000, 0, true, true, false); } - - + + vel.x *= multiplier; vel.y *= multiplier; vel.z *= multiplier; - + ENTITY::SET_ENTITY_VELOCITY(entity, vel.x, vel.y, vel.z); } @@ -1024,13 +1002,13 @@ void EffectBunnyhop::OnTick() { return; } - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + ENTITY::SET_ENTITY_COORDS(playerPed, vec.x, vec.y, vec.z + 1.5f, false, false, false, false); } else if (PED::IS_PED_ON_MOUNT(playerPed)) @@ -1046,46 +1024,38 @@ void EffectBunnyhop::OnTick() void EffectEyeDisorder::OnActivate() { - GRAPHICS::ANIMPOSTFX_PLAY((char*)"OJDominoBlur"); + GRAPHICS::ANIMPOSTFX_PLAY((char*) "OJDominoBlur"); } void EffectEyeDisorder::OnDeactivate() { - GRAPHICS::ANIMPOSTFX_STOP((char*)"OJDominoBlur"); + GRAPHICS::ANIMPOSTFX_STOP((char*) "OJDominoBlur"); } void EffectBirdSkin::OnActivate() { - static std::vector birds = { - "A_C_BlueJay_01", "A_C_Cardinal_01", - "A_C_CarolinaParakeet_01", "A_C_CedarWaxwing_01", - "A_C_Chicken_01", "A_C_Cormorant_01", - "A_C_CraneWhooping_01", "A_C_Crow_01", - "A_C_Duck_01", "A_C_Eagle_01", - "A_C_Egret_01", "A_C_Hawk_01", - "A_C_Heron_01", "A_C_Loon_01", - "A_C_Owl_01", "A_C_Parrot_01", - "A_C_Pelican_01", "A_C_Pheasant_01", - "A_C_Pigeon", "A_C_PrairieChicken_01", - "A_C_Quail_01", "A_C_Raven_01", - "A_C_RedFootedBooby_01", "A_C_Rooster_01", - "A_C_RoseateSpoonbill_01", "A_C_Seagull_01", - "A_C_TurkeyWild_01", "A_C_Vulture_01", - "A_C_Woodpecker_01", "A_C_Woodpecker_02" - }; - + static std::vector birds = {"A_C_BlueJay_01", "A_C_Cardinal_01", "A_C_CarolinaParakeet_01", + "A_C_CedarWaxwing_01", "A_C_Chicken_01", "A_C_Cormorant_01", + "A_C_CraneWhooping_01", "A_C_Crow_01", "A_C_Duck_01", "A_C_Eagle_01", + "A_C_Egret_01", "A_C_Hawk_01", "A_C_Heron_01", "A_C_Loon_01", "A_C_Owl_01", + "A_C_Parrot_01", "A_C_Pelican_01", "A_C_Pheasant_01", "A_C_Pigeon", + "A_C_PrairieChicken_01", "A_C_Quail_01", "A_C_Raven_01", + "A_C_RedFootedBooby_01", "A_C_Rooster_01", "A_C_RoseateSpoonbill_01", + "A_C_Seagull_01", "A_C_TurkeyWild_01", "A_C_Vulture_01", + "A_C_Woodpecker_01", "A_C_Woodpecker_02"}; + auto modelName = birds[rand() % birds.size()]; this->skinToSet = modelName; - + IEffectSkinChange::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + uint32_t maxOutfits = PED::_0x10C70A515BC03707(playerPed); - + uint32_t randOutfit = rand() % maxOutfits; - + invoke(0x77FF8D35EEC6BBC4, playerPed, randOutfit, false); } @@ -1100,14 +1070,14 @@ void EffectBodySwap::OnActivate() pedSkin = 0; clone = 0; auto nearbyPeds = GetNearbyPeds(50); - - std::vector validPeds; - std::vector missionPeds; - - + + std::vector validPeds; + std::vector missionPeds; + + bool bUseMissionPed = false; bool bUseRandomSkin = false; - + for (auto ped : nearbyPeds) { if (PED::IS_PED_HUMAN(ped)) @@ -1122,7 +1092,7 @@ void EffectBodySwap::OnActivate() } } } - + if (!validPeds.size()) { if (missionPeds.size()) @@ -1134,11 +1104,11 @@ void EffectBodySwap::OnActivate() bUseRandomSkin = true; } } - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Ped ped = 0; - + if (!bUseRandomSkin) { if (bUseMissionPed) @@ -1149,133 +1119,131 @@ void EffectBodySwap::OnActivate() { ped = validPeds[rand() % validPeds.size()]; } - + if (!ENTITY::DOES_ENTITY_EXIST(ped)) { return; } } - - + + Vector3 playerVec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); Vector3 pedVec; pedVec.x = pedVec.y = pedVec.z = 0; - + auto pedHeading = 0; - + Vehicle playerVehicle = 0; Ped playerMount = 0; uint32_t playerSeat = -2; - + Vehicle pedVehicle = 0; Ped pedMount = 0; uint32_t pedSeat = -2; - + if (!bUseRandomSkin) { pedSkin = ENTITY::GET_ENTITY_MODEL(ped); } else { - static std::vector skins = { - "a_m_m_vallaborer_01", "a_m_m_valtownfolk_01", - "a_m_m_valtownfolk_02", "a_m_m_tumtownfolk_01", - "a_f_m_valtownfolk_01", "a_m_m_asbtownfolk_01" - }; - + static std::vector skins = {"a_m_m_vallaborer_01", "a_m_m_valtownfolk_01", "a_m_m_valtownfolk_02", + "a_m_m_tumtownfolk_01", "a_f_m_valtownfolk_01", + "a_m_m_asbtownfolk_01"}; + pedSkin = GET_HASH(skins[rand() % skins.size()]); } - - + + if (!bUseMissionPed && !bUseRandomSkin) { pedVec = ENTITY::GET_ENTITY_COORDS(ped, true, 0); pedHeading = ENTITY::GET_ENTITY_HEADING(ped); ENTITY::SET_ENTITY_COORDS(playerPed, pedVec.x, pedVec.y, pedVec.z, false, false, false, false); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { playerVehicle = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + playerSeat = PED::_0x4E76CB57222A00E5(playerPed); - + ENTITY::SET_ENTITY_COORDS(playerPed, playerVec.x, playerVec.y, playerVec.z, false, false, false, false); } else if (PED::IS_PED_ON_MOUNT(playerPed)) { playerMount = PED::GET_MOUNT(playerPed); - + playerSeat = PED::_0x4E76CB57222A00E5(playerPed); - + /** _REMOVE_PED_FROM_MOUNT */ invoke(0x5337B721C51883A9, playerPed, 0, 0); - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(playerMount, true, true); } - + if (PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { pedVehicle = PED::GET_VEHICLE_PED_IS_IN(ped, false); - + pedSeat = PED::_0x4E76CB57222A00E5(ped); } else if (PED::IS_PED_ON_MOUNT(ped)) { pedMount = PED::GET_MOUNT(ped); - + pedSeat = PED::_0x4E76CB57222A00E5(ped); } - + PED::DELETE_PED(&ped); - + clone = PED::CLONE_PED(playerPed, ENTITY::GET_ENTITY_HEADING(playerPed), true, false); - + if (playerVehicle) { PED::SET_PED_INTO_VEHICLE(clone, playerVehicle, playerSeat); AI::TASK_VEHICLE_DRIVE_WANDER(clone, playerVehicle, 100000.0f, 0x400c0025); - + } else if (playerMount) { invoke(0x028F76B6E78246EB, clone, playerMount, playerSeat, true); AI::TASK_WANDER_STANDARD(clone, 100.0f, 10); - + } else { ENTITY::SET_ENTITY_COORDS(clone, playerVec.x, playerVec.y, playerVec.z, false, false, false, false); AI::TASK_WANDER_STANDARD(clone, 100.0f, 10); } - + if (ENTITY::DOES_ENTITY_EXIST(clone)) { ChaosMod::pedsSet.insert(clone); } } - + LoadModel(pedSkin); - + ChaosMod::Singleton->SavePlayerAttributes(); - + ChaosMod::UpdatePlayerSkinHash(); - + PLAYER::SET_PLAYER_MODEL(PLAYER::PLAYER_ID(), pedSkin, 1); - + *getGlobalPtr(0x23) = PLAYER::PLAYER_PED_ID(); - + uint64_t* ptr1 = getGlobalPtr(0x28) + 0x27; uint64_t* ptr2 = getGlobalPtr(0x1D890E) + 2; - + *ptr1 = *ptr2 = pedSkin; - + *getGlobalPtr(0x23) = PLAYER::PLAYER_PED_ID(); - + playerPed = PLAYER::PLAYER_PED_ID(); - + ENTITY::SET_ENTITY_COLLISION(playerPed, true, true); ENTITY::SET_ENTITY_DYNAMIC(playerPed, true); - + if (!bUseMissionPed && !bUseRandomSkin) { if (pedVehicle) @@ -1292,7 +1260,7 @@ void EffectBodySwap::OnActivate() ENTITY::SET_ENTITY_HEADING(playerPed, pedHeading); } } - + if (bUseRandomSkin) { uint32_t maxOutfits = PED::_0x10C70A515BC03707(playerPed); @@ -1305,22 +1273,22 @@ void EffectBodySwap::OnDeactivate() if (ENTITY::DOES_ENTITY_EXIST(clone)) { Ped ped = SpawnPedAroundPlayer(pedSkin, false, false); - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(clone, true, 0); - + ENTITY::SET_ENTITY_COORDS(ped, vec.x, vec.y, vec.z, false, false, false, false); - + AI::TASK_WANDER_STANDARD(ped, 100.0f, 10); - + ChaosMod::pedsSet.erase(clone); - + ENTITY::SET_ENTITY_AS_MISSION_ENTITY(clone, false, false); - + PED::DELETE_PED(&clone); } - + ResetPlayerModel(0, 0); - + pedSkin = 0; clone = 0; } @@ -1333,7 +1301,7 @@ void EffectPlayerSpin::OnActivate() void EffectPlayerSpin::OnTick() { Entity entity = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(entity, true)) { entity = PED::GET_VEHICLE_PED_IS_IN(entity, false); @@ -1342,27 +1310,28 @@ void EffectPlayerSpin::OnTick() { entity = PED::GET_MOUNT(entity); } - + heading += 625.0f * ChaosMod::GetDeltaTimeSeconds(); - + heading = fmod(heading, 360.0f); - + ENTITY::SET_ENTITY_HEADING(entity, heading); } void EffectPlayerLosesWeight::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + PED::_0x1902C4CFCC5BE57C(playerPed, 0x63F130D5); PED::_0x1902C4CFCC5BE57C(playerPed, 0x86155956); PED::_0x1902C4CFCC5BE57C(playerPed, 0x652668B6); PED::_0xCC8CA3E88256E58F(playerPed, 0, 1, 1, 1, false); } + void EffectPlayerGainsWeight::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + PED::_0x1902C4CFCC5BE57C(playerPed, 0x63F130D5); PED::_0x1902C4CFCC5BE57C(playerPed, 0x74D74B1C); PED::_0x1902C4CFCC5BE57C(playerPed, 0xBB7091D9); @@ -1371,22 +1340,13 @@ void EffectPlayerGainsWeight::OnActivate() void EffectSetRandomHat::OnActivate() { - static std::vector hats = { - 0x2514B2B9, - 0x05A94693, - 0xB2A7CB98, - 0x2968E73D, - 0xAE8ACE4E, - 0xD16013FC, - 0x3D9CEC78, - 0x5F74300A, - 0x48760F4A - }; - + static std::vector hats = {0x2514B2B9, 0x05A94693, 0xB2A7CB98, 0x2968E73D, 0xAE8ACE4E, 0xD16013FC, + 0x3D9CEC78, 0x5F74300A, 0x48760F4A}; + Hash hat = hats[rand() % hats.size()]; - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + PED::_0x1902C4CFCC5BE57C(playerPed, hat); PED::_0xCC8CA3E88256E58F(playerPed, 0, 1, 1, 1, false); } @@ -1394,15 +1354,15 @@ void EffectSetRandomHat::OnActivate() void EffectGravityGun::OnActivate() { lastVec.x = lastVec.y = lastVec.z = 0.0f; - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - - static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_UNARMED"); + + static Hash unarmed = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_UNARMED"); Hash weaponHash = 0; - + if (WEAPON::GET_CURRENT_PED_WEAPON(playerPed, &weaponHash, 0, 0, 0) && weaponHash == unarmed) { - static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*)"WEAPON_PISTOL_MAUSER_DRUNK"); + static Hash weaponHash = GAMEPLAY::GET_HASH_KEY((char*) "WEAPON_PISTOL_MAUSER_DRUNK"); WEAPON::GIVE_DELAYED_WEAPON_TO_PED(playerPed, weaponHash, 35, 1, 0x2cd419dc); WEAPON::SET_PED_AMMO(playerPed, weaponHash, 35); WEAPON::SET_CURRENT_PED_WEAPON(playerPed, weaponHash, 1, 0, 0, 0); @@ -1417,72 +1377,72 @@ void EffectGravityGun::OnDeactivate() void EffectGravityGun::OnTick() { Vector3 vec; - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + bool bCoordValid = WEAPON::GET_PED_LAST_WEAPON_IMPACT_COORD(playerPed, &vec); - + if (!bCoordValid || (vec.x == lastVec.x && vec.y == lastVec.y && vec.z == lastVec.z)) { return; } - + lastVec = vec; - - std::vector entities = GetNearbyPeds(50); - + + std::vector entities = GetNearbyPeds(50); + auto nearbyVehs = GetNearbyVehs(45); - + for (auto veh : nearbyVehs) { entities.push_back(veh); } - + auto props = GetNearbyProps(45); - + for (auto prop : props) { ENTITY::SET_ENTITY_DYNAMIC(prop, true); ENTITY::SET_ENTITY_HAS_GRAVITY(prop, true); entities.push_back(prop); } - + Vector3 pVec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + for (auto entity : entities) { Vector3 vec2 = ENTITY::GET_ENTITY_COORDS(entity, true, 0); float dist = GetDistance3D(vec, vec2); - + const float maxDist = 5.0f; - + if (dist >= maxDist) { continue; } - + if (ENTITY::IS_ENTITY_A_PED(entity)) { PED::SET_PED_TO_RAGDOLL(entity, 5000, 5000, 0, true, true, false); } - + float scale = 15.0f * (1.0f - (dist / maxDist)); - + Vector3 diff = vec2; diff.x -= pVec.x; diff.y -= pVec.y; diff.z -= pVec.z; - + const float squareSum = (diff.x * diff.x) + (diff.y * diff.y) + (diff.z * diff.z); const float length = sqrt(squareSum); diff.x /= length; diff.y /= length; diff.z /= length; - + diff.x *= scale; diff.y *= scale; diff.y *= scale; - + ENTITY::SET_ENTITY_VELOCITY(entity, diff.x, diff.y, diff.z); } } @@ -1500,9 +1460,9 @@ void EffectDisableDeadEye::OnDeactivate() void EffectSetRandomVelocity::OnActivate() { Entity entity = PLAYER::PLAYER_PED_ID(); - + bool bInVehicle = false; - + if (PED::IS_PED_IN_ANY_VEHICLE(entity, true)) { entity = PED::GET_VEHICLE_PED_IS_IN(entity, false); @@ -1512,25 +1472,25 @@ void EffectSetRandomVelocity::OnActivate() { entity = PED::GET_MOUNT(entity); } - - + + if (!bInVehicle) { FixEntityInCutscene(entity); - + WAIT(75); PED::SET_PED_TO_RAGDOLL(entity, 2000, 2000, 0, true, true, false); } - + Vector3 vel; - + vel.x = float((rand() % 15) + 5); vel.y = float((rand() % 15) + 5); vel.z = float((rand() % 10) + 0); - + vel.x *= rand() % 2 ? -1 : 1; vel.y *= rand() % 2 ? -1 : 1; - + ENTITY::SET_ENTITY_VELOCITY(entity, vel.x, vel.y, vel.y); } @@ -1541,9 +1501,9 @@ void EffectFirstPerson::OnTick() void EffectTopDownCamera::OnActivate() { - this->cam = CAM::CREATE_CAM((char*)"DEFAULT_SCRIPTED_CAMERA", 1); + this->cam = CAM::CREATE_CAM((char*) "DEFAULT_SCRIPTED_CAMERA", 1); CAM::RENDER_SCRIPT_CAMS(true, true, 500, 1, 1, 1); - + /** Should remove reticle */ UI::_0x4CC5F2FC1332577F(GET_HASH("HUD_CTX_IN_FAST_TRAVEL_MENU")); } @@ -1551,16 +1511,16 @@ void EffectTopDownCamera::OnActivate() void EffectTopDownCamera::OnTick() { CAM::SET_CAM_ACTIVE(this->cam, true); - + Vector3 camCoord = CAM::GET_GAMEPLAY_CAM_COORD(); Vector3 camRotation = CAM::GET_GAMEPLAY_CAM_ROT(2); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + Vector3 vec = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + vec.z += 10.0f; - + CAM::SET_CAM_ROT(cam, -90.0f, 0.0f, 0.0f, 2); CAM::SET_CAM_COORD(cam, vec.x, vec.y, vec.z); CAM::SET_CAM_AFFECTS_AIMING(cam, false); @@ -1579,7 +1539,7 @@ void EffectTopDownCamera::OnDeactivate() void EffectAgitateHorse::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_ON_MOUNT(playerPed)) { Ped mount = PED::GET_MOUNT(playerPed); @@ -1589,43 +1549,42 @@ void EffectAgitateHorse::OnActivate() void EffectTpRandomLocation::OnActivate() { - static std::vector> coords = { - { -301.0f, 790.0f, 119.0f }, /** Valentine */ - { -1303.0f, 395.0f, 96.0f }, /** Wallace station */ - { -1790.0f, -372.5f, 160.0f }, /** Strawberry */ - { 2432.8f, -1216.0f, 46.0f }, /** Saint Denis */ - { 1526.5f, 431.0f, 91.0f }, /** Emerald Station */ - { 1264.4f, -1311.0f, 77.0f }, /** Rhoads */ - { 2958.6f, 518.0f, 45.0f }, /** Van Horn */ - { 2927.0f, 1325.9f, 44.0f } /** Annesburg */ + static std::vector > coords = {{-301.0f, 790.0f, 119.0f}, /** Valentine */ + {-1303.0f, 395.0f, 96.0f}, /** Wallace station */ + {-1790.0f, -372.5f, 160.0f}, /** Strawberry */ + {2432.8f, -1216.0f, 46.0f}, /** Saint Denis */ + {1526.5f, 431.0f, 91.0f}, /** Emerald Station */ + {1264.4f, -1311.0f, 77.0f}, /** Rhoads */ + {2958.6f, 518.0f, 45.0f}, /** Van Horn */ + {2927.0f, 1325.9f, 44.0f} /** Annesburg */ }; auto randomCoord = coords[rand() % coords.size()]; - + if (randomCoord.size() != 3) { return; } - + TeleportPlayerTo(randomCoord[0], randomCoord[1], randomCoord[2]); } void EffectFakeTeleport::OnActivate() { oldName = this->name; - + auto* chaosMod = ChaosMod::Singleton; - + if (chaosMod) { auto* originalEffect = chaosMod->EffectsMap["tp_to_random"]; - + if (originalEffect) { this->name = originalEffect->name; } } - + bTeleportedBack = false; Effect::OnActivate(); oldCoord = ENTITY::GET_ENTITY_COORDS(PLAYER::PLAYER_PED_ID(), true, 0); @@ -1647,7 +1606,7 @@ void EffectFakeTeleport::OnDeactivate() { TeleportToOldCoord(); } - + bTeleportedBack = false; } diff --git a/src/Effects/player.h b/src/Effects/player.h index a71db9e..48654b9 100644 --- a/src/Effects/player.h +++ b/src/Effects/player.h @@ -15,7 +15,7 @@ class EffectLaunchPlayerUp : public Effect name = "Launch Player Up"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -28,7 +28,7 @@ class EffectToTheStars : public Effect name = "To The Stars"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -41,7 +41,7 @@ class EffectGivePlayerMoney : public Effect name = "Give 300$ to Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -54,7 +54,7 @@ class EffectBankruptcy : public Effect name = "Bankruptcy"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -67,7 +67,7 @@ class EffectGiveRifle : public Effect name = "Give a Rifle to Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -80,7 +80,7 @@ class EffectGiveRevolver : public Effect name = "Give a Revolver To Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -94,7 +94,7 @@ class EffectNoAmmo : public Effect name = "No ammo"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -107,7 +107,7 @@ class EffectRemoveAllWeapons : public Effect name = "Remove All Player Weapons"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -121,7 +121,7 @@ class EffectHonorGood : public Effect name = "Set Good Honor"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -134,7 +134,7 @@ class EffectHonorBad : public Effect name = "Set Bad Honor"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -147,7 +147,7 @@ class EffectHonorReset : public Effect name = "Reset Player's Honor"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -161,7 +161,7 @@ class EffectDropWeapon : public Effect name = "Drop current weapon"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -174,7 +174,7 @@ class EffectHealPlayer : public Effect name = "Heal Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -187,7 +187,7 @@ class EffectAlmostDead : public Effect name = "Almost Dead"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -200,7 +200,7 @@ class EffectRestoreStamina : public Effect name = "Restore Player Stamina"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -213,7 +213,7 @@ class EffectRagdoll : public Effect name = "Ragdoll"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -227,7 +227,7 @@ class EffectGiveRandomWeapon : public Effect name = "Give Random Weapon"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -241,10 +241,11 @@ class EffectSetDrunk : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; }; @@ -257,7 +258,7 @@ class EffectClearPursuit : public Effect name = "Stop Pursuit"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -270,7 +271,7 @@ class EffectIncreaseBounty : public Effect name = "Increase Bounty for Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -283,7 +284,7 @@ class EffectRemoveCurrentVehicle : public Effect name = "Remove Current Vehicle"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -296,7 +297,7 @@ class EffectGiveLasso : public Effect name = "Give Lasso to Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -310,7 +311,7 @@ class EffectIgnitePlayer : public Effect name = "Ignite Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -323,7 +324,7 @@ class EffectKickflip : public Effect name = "Kickflip"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -337,11 +338,13 @@ class EffectLightningWeapons : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; + private: Vector3 lastVec; }; @@ -354,10 +357,11 @@ class IEffectSkinChange : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + const char* skinToSet = "A_C_COW"; private: uint64_t oldSkin1{}; @@ -396,7 +400,7 @@ class EffectPigSkin : public IEffectSkinChange name = "Player Is a Pig"; skinToSet = "A_C_Pig_01"; } - + virtual void OnActivate() override; }; @@ -433,7 +437,7 @@ class EffectPlayerSleep : public IEffectSkinChange bTimed = true; EffectDuration = 15; } - + virtual void OnActivate() override; }; @@ -447,9 +451,11 @@ class EffectPlayerIsMinion : public IEffectSkinChange bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; }; @@ -463,11 +469,12 @@ class EffectTeleportToWaypoint : public IEffectSkinChange name = "Teleport To Waypoint"; bTimed = false; } - + virtual void OnActivate() override; }; void SetPlayerModel(const char* model, uint64_t* ptr1_val, uint64_t* ptr2_val); + void ResetPlayerModel(uint64_t ptr1_val, uint64_t ptr2_val); class EffectExplosiveWeapons : public Effect @@ -480,11 +487,13 @@ class EffectExplosiveWeapons : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; + private: Vector3 lastVec; }; @@ -499,11 +508,13 @@ class EffectTeleportWeapons : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; + private: Vector3 lastVec; }; @@ -519,7 +530,7 @@ class EffectBloodTrails : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnTick() override; }; @@ -534,8 +545,9 @@ class EffectSetRandomWalkStyle : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; @@ -548,7 +560,7 @@ class EffectGiveSniperRifle : public Effect name = "Give a Sniper Rifle To Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -561,7 +573,7 @@ class EffectGiveDynamite : public Effect name = "Give a Dynamite To Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -574,7 +586,7 @@ class EffectThrowingKnives : public Effect name = "Give Throwing Knives To Player"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -587,7 +599,7 @@ class EffectTeleportFewMeters : public Effect name = "Teleport Player a Few Meters"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -601,7 +613,7 @@ class EffectBlackingOut : public Effect name = "Blacking Out"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -614,7 +626,7 @@ class EffectRandomClothes : public Effect name = "Set Random Clothes"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -627,7 +639,7 @@ class EffectMostWanted : public Effect name = "Most Wanted"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -640,7 +652,7 @@ class EffectSetWinterOutfit : public Effect name = "Set Winter Outfit"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -654,7 +666,7 @@ class EffectSuperJump : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnTick() override; }; @@ -668,7 +680,7 @@ class EffectDisableLeftRight : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnTick() override; }; @@ -682,7 +694,7 @@ class EffectDisableForwardBackward : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnTick() override; }; @@ -696,7 +708,7 @@ class EffectDisableSprintJump : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnTick() override; }; @@ -710,7 +722,7 @@ class EffectDisableAllMovements : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnTick() override; }; @@ -725,7 +737,7 @@ class EffectDisableAttackButton : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnTick() override; }; @@ -739,9 +751,11 @@ class EffectDisableAiming : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + virtual void OnTick() override; }; @@ -754,7 +768,7 @@ class EffectRandomHonor : public Effect name = "Random Honor Change"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -767,7 +781,7 @@ class EffectInvertVelocity : public Effect name = "Invert And Increase Current Velocity"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -781,7 +795,7 @@ class EffectIncreaseVelocity : public Effect name = "Increase Current Velocity"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -796,7 +810,7 @@ class EffectBunnyhop : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnTick() override; }; @@ -811,8 +825,9 @@ class EffectEyeDisorder : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; @@ -825,8 +840,9 @@ class EffectBirdSkin : public IEffectSkinChange name = "Player Is a Bird"; skinToSet = "A_C_BlueJay_01"; } - + virtual void OnActivate() override; + virtual void OnTick() override; }; @@ -840,9 +856,11 @@ class EffectBodySwap : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + private: Ped clone = 0; Hash pedSkin = 0; @@ -858,9 +876,11 @@ class EffectPlayerSpin : public Effect bTimed = true; EffectDuration = 20; } - + virtual void OnActivate() override; + virtual void OnTick() override; + private: float heading = 0.0f; }; @@ -874,7 +894,7 @@ class EffectPlayerLosesWeight : public Effect name = "Player Loses Weight"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -888,7 +908,7 @@ class EffectPlayerGainsWeight : public Effect name = "Player Gains Weight"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -902,7 +922,7 @@ class EffectSetRandomHat : public Effect name = "Set Random Hat"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -916,11 +936,13 @@ class EffectGravityGun : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; + private: Vector3 lastVec; }; @@ -935,8 +957,9 @@ class EffectDisableDeadEye : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; }; @@ -949,7 +972,7 @@ class EffectSetRandomVelocity : public Effect name = "Set Random Velocity"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -963,7 +986,7 @@ class EffectFirstPerson : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnTick() override; }; @@ -978,10 +1001,13 @@ class EffectTopDownCamera : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: Camera cam; }; @@ -995,7 +1021,7 @@ class EffectAgitateHorse : public Effect name = "Agitate Player's Horse"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -1008,7 +1034,7 @@ class EffectTpRandomLocation : public Effect name = "Teleport To Random Location"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -1023,15 +1049,18 @@ class EffectFakeTeleport : public EffectTpRandomLocation EffectDuration = 20; bIsFake = true; } - + virtual void OnActivate() override; + virtual void OnTick() override; + virtual void OnDeactivate() override; + private: Vector3 oldCoord; std::string oldName; - + bool bTeleportedBack = false; - + void TeleportToOldCoord(); }; diff --git a/src/Effects/vehs.cpp b/src/Effects/vehs.cpp index fcf454f..5610fdd 100644 --- a/src/Effects/vehs.cpp +++ b/src/Effects/vehs.cpp @@ -5,34 +5,34 @@ #include #include "misc.h" -std::vector GetNearbyVehs(int32_t Max) +std::vector GetNearbyVehs(int32_t Max) { - std::vector vehsOut; + std::vector vehsOut; Ped playerPed = PLAYER::PLAYER_PED_ID(); - + NearbyEntities vehs; vehs.size = 100; - + if (Max > 100) { Max = 100; } - - int pedsFound = PED::GET_PED_NEARBY_VEHICLES(playerPed, (int*)&vehs); - + + int pedsFound = PED::GET_PED_NEARBY_VEHICLES(playerPed, (int*) &vehs); + if (Max > pedsFound) { Max = pedsFound; } - + bool bPlayerInVehicle = PED::IS_PED_IN_ANY_VEHICLE(playerPed, true); - + Vehicle playerVeh = 0; if (bPlayerInVehicle) { playerVeh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); } - + for (int32_t i = 0; i < Max; i++) { Entity veh = vehs.entities[i]; @@ -41,7 +41,7 @@ std::vector GetNearbyVehs(int32_t Max) vehsOut.push_back(veh); } } - + return vehsOut; } @@ -49,22 +49,23 @@ void EffectSpawnWagon::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerLocation = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - - static Hash model = GAMEPLAY::GET_HASH_KEY((char*)"COACH3"); - + + static Hash model = GAMEPLAY::GET_HASH_KEY((char*) "COACH3"); + LoadModel(model); - + float playerHeading = ENTITY::GET_ENTITY_HEADING(playerPed); - Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, playerHeading, false, false, false, false); - DECORATOR::DECOR_SET_BOOL(veh, (char*)"wagon_block_honor", true); - + Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, playerHeading, + false, false, false, false); + DECORATOR::DECOR_SET_BOOL(veh, (char*) "wagon_block_honor", true); + Vehicle vehCopy = veh; ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&vehCopy); - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); - + PED::SET_PED_INTO_VEHICLE(playerPed, veh, -1); - + if (ENTITY::DOES_ENTITY_EXIST(veh)) { ChaosMod::vehsSet.insert(veh); @@ -75,47 +76,92 @@ void EffectFlipAllVehs::OnActivate() { auto nearbyPeds = GetNearbyPeds(45); auto nearbyVehs = GetNearbyVehs(45); - - std::vector entities = nearbyVehs; - + + std::vector entities = nearbyVehs; + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + entities.push_back(veh); } - + for (auto ped : nearbyPeds) { Hash pedModel = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, pedModel); - + if (bModelIsHorse) { PED::SET_PED_TO_RAGDOLL(ped, 5000, 5000, 0, true, true, false); entities.push_back(ped); } } - + for (auto entity : entities) { if (ENTITY::DOES_ENTITY_EXIST(entity)) { Vector3 rotation = ENTITY::GET_ENTITY_ROTATION(entity, 2); - + Vector3 velocity = ENTITY::GET_ENTITY_VELOCITY(entity, 0); - + ENTITY::SET_ENTITY_ROTATION(entity, rotation.x + 180.0f, rotation.y, rotation.z, 2, true); - + ENTITY::SET_ENTITY_VELOCITY(entity, velocity.x, velocity.y, velocity.z + 5.0f); } } } +void EffectTrainsawLaser::OnActivate() +{ + vehs.clear(); +} + +void EffectTrainsawLaser::OnDeactivate() +{ + for (auto veh : vehs) + { + if (ENTITY::DOES_ENTITY_EXIST(veh)) + { + VEHICLE::DELETE_VEHICLE(&veh); + } + } + + vehs.clear(); +} + +void EffectTrainsawLaser::OnTick() +{ + Effect::OnTick(); + + if (!TimerTick(500)) + { + return; + } + + static Hash trainHash = GAMEPLAY::GET_HASH_KEY((char*) "CABOOSE01X"); + + LoadModel(trainHash); + + Vehicle veh = VEHICLE::CREATE_VEHICLE(trainHash, 0, 0, 35.0f, rand() % 360, false, false, false, false); + + ENTITY::SET_ENTITY_VELOCITY(veh, 0.0f, 0.0f, -100.0f); + + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(trainHash); + + vehs.push_back(veh); + + if (ENTITY::DOES_ENTITY_EXIST(veh)) + { + ChaosMod::vehsSet.insert(veh); + } +} + void EffectMinecartRain::OnActivate() { vehs.clear(); @@ -130,33 +176,34 @@ void EffectMinecartRain::OnDeactivate() VEHICLE::DELETE_VEHICLE(&veh); } } - + vehs.clear(); } void EffectMinecartRain::OnTick() { Effect::OnTick(); - + if (!TimerTick(500)) { return; } - - static Hash cartHash = GAMEPLAY::GET_HASH_KEY((char*)"mineCart01x"); - + + static Hash cartHash = GAMEPLAY::GET_HASH_KEY((char*) "mineCart01x"); + LoadModel(cartHash); - + Vector3 vec = GetRandomCoordAroundPlayer(float(rand() % 20)); - - Vehicle veh = VEHICLE::CREATE_VEHICLE(cartHash, vec.x, vec.y, vec.z + 35.0f, rand() % 360, false, false, false, false); - + + Vehicle veh = VEHICLE::CREATE_VEHICLE(cartHash, vec.x, vec.y, vec.z + 35.0f, rand() % 360, false, false, false, + false); + ENTITY::SET_ENTITY_VELOCITY(veh, 0.0f, 0.0f, -150.0f); - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(cartHash); - + vehs.push_back(veh); - + if (ENTITY::DOES_ENTITY_EXIST(veh)) { ChaosMod::vehsSet.insert(veh); @@ -180,7 +227,7 @@ void EffectFullAcceleration::OnDeactivate() ENTITY::SET_ENTITY_INVINCIBLE(horse, false); } } - + horses.clear(); } @@ -189,54 +236,54 @@ void EffectFullAcceleration::OnTick() if (TimerTick(1000)) { vehs.clear(); - + vehs = GetNearbyVehs(45); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { vehs.push_back(PED::GET_VEHICLE_PED_IS_IN(playerPed, false)); } - + auto peds = GetNearbyPeds(45); - + for (auto ped : peds) { Hash pedModel = ENTITY::GET_ENTITY_MODEL(ped); /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, pedModel); - + if (bModelIsHorse) { Vector3 horseForwardVec = ENTITY::GET_ENTITY_FORWARD_VECTOR(ped); - + float acceleration = 1000.0f; - + horseForwardVec.x *= acceleration; horseForwardVec.y *= acceleration; horseForwardVec.z *= acceleration; - + ENTITY::SET_ENTITY_INVINCIBLE(ped, true); horses.insert(ped); - + PED::SET_PED_TO_RAGDOLL(ped, 1000, 1000, 0, true, true, false); - + ENTITY::SET_ENTITY_VELOCITY(ped, horseForwardVec.x, horseForwardVec.y, horseForwardVec.z); } } } - + for (auto veh : vehs) { if (ENTITY::DOES_ENTITY_EXIST(veh)) { VEHICLE::SET_VEHICLE_FORWARD_SPEED(veh, 100.0f); - + Hash vehModel = ENTITY::GET_ENTITY_MODEL(veh); - + bool bModelIsTrain = invoke(0xFC08C8F8C1EDF174, vehModel); - + if (bModelIsTrain) { VEHICLE::SET_VEHICLE_FORWARD_SPEED(veh, 1000.0f); @@ -250,11 +297,11 @@ void EffectFullAcceleration::OnTick() void EffectEveryoneExitsVehs::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + auto peds = GetNearbyPeds(45); - + peds.push_back(playerPed); - + for (auto ped : peds) { if (PED::IS_PED_IN_ANY_VEHICLE(ped, true)) @@ -273,45 +320,45 @@ void EffectEveryoneExitsVehs::OnActivate() void EffectSetPlayerIntoRandomVeh::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - - std::vector entities; - + + std::vector entities; + auto peds = GetNearbyPeds(45); auto vehs = GetNearbyVehs(45); - + entities = vehs; - + for (auto ped : peds) { Hash pedModel = ENTITY::GET_ENTITY_MODEL(ped); /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, pedModel); - + if (bModelIsHorse) { entities.push_back(ped); } } - + /** No vehicles nearby */ if (entities.size() == 0) { return; } - + auto randomEngine = std::default_random_engine{}; std::shuffle(std::begin(entities), std::end(entities), randomEngine); - + for (auto entity : entities) { if (ENTITY::IS_ENTITY_A_PED(entity)) { - std::vector seatIndices = { -1, 0 }; - + std::vector seatIndices = {-1, 0}; + for (auto index : seatIndices) { bool bIsMountSeatFree = invoke(0xAAB0FE202E9FC9F0, entity, index); - + if (bIsMountSeatFree) { /** __SET_PED_ON_MOUNT */ @@ -319,22 +366,22 @@ void EffectSetPlayerIntoRandomVeh::OnActivate() return; } } - + } else { bool bSeatFree = VEHICLE::IS_VEHICLE_SEAT_FREE(entity, -1); - + if (bSeatFree) { PED::SET_PED_INTO_VEHICLE(playerPed, entity, -1); return; } - + auto hash = ENTITY::GET_ENTITY_MODEL(entity); - + int32_t seatsNum = VEHICLE::GET_VEHICLE_MODEL_NUMBER_OF_SEATS(hash) - 1; - + for (int32_t i = 0; i < seatsNum; i++) { bSeatFree = VEHICLE::IS_VEHICLE_SEAT_FREE(entity, i); @@ -352,33 +399,34 @@ void EffectSetPlayerIntoRandomVeh::OnActivate() void EffectSpawnHotAirBalloon::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerLocation = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - + playerLocation.z += 2.0f; - - static Hash model = GAMEPLAY::GET_HASH_KEY((char*)"hotAirBalloon01"); - + + static Hash model = GAMEPLAY::GET_HASH_KEY((char*) "hotAirBalloon01"); + LoadModel(model); - - Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, rand() % 360, false, false, false, false); - + + Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, rand() % 360, + false, false, false, false); + Vehicle vehCopy = veh; ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&vehCopy); - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); - + PED::SET_PED_INTO_VEHICLE(playerPed, veh, -1); - + Vector3 windDirection = GAMEPLAY::GET_WIND_DIRECTION(); - + windDirection.x *= 25.0f; windDirection.y *= 25.0f; windDirection.z = 25.0f; - + ENTITY::SET_ENTITY_VELOCITY(veh, windDirection.x, windDirection.y, 25.0f); - + if (ENTITY::DOES_ENTITY_EXIST(veh)) { ChaosMod::vehsSet.insert(veh); @@ -389,11 +437,11 @@ void EffectIgnitePlayersWagon::OnActivate() { Effect::OnActivate(); Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + VEHICLE::EXPLODE_VEHICLE(veh, true, false, 0); } } @@ -401,9 +449,9 @@ void EffectIgnitePlayersWagon::OnActivate() void EffectIgniteNearbyWagons::OnActivate() { Effect::OnActivate(); - + auto vehs = GetNearbyVehs(45); - + for (auto veh : vehs) { VEHICLE::EXPLODE_VEHICLE(veh, true, false, 0); @@ -413,23 +461,24 @@ void EffectIgniteNearbyWagons::OnActivate() void EffectSpawnCanoe::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerLocation = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); - - static Hash model = GAMEPLAY::GET_HASH_KEY((char*)"CANOE"); - + + static Hash model = GAMEPLAY::GET_HASH_KEY((char*) "CANOE"); + LoadModel(model); - - Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, rand() % 360, false, false, false, false); - + + Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, rand() % 360, + false, false, false, false); + Vehicle vehCopy = veh; ENTITY::SET_ENTITY_AS_NO_LONGER_NEEDED(&vehCopy); - + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); - + PED::SET_PED_INTO_VEHICLE(playerPed, veh, -1); - + if (ENTITY::DOES_ENTITY_EXIST(veh)) { ChaosMod::vehsSet.insert(veh); @@ -439,14 +488,14 @@ void EffectSpawnCanoe::OnActivate() void EffectHorsesRain::OnActivate() { Effect::OnActivate(); - + horses.clear(); } void EffectHorsesRain::OnDeactivate() { Effect::OnDeactivate(); - + for (auto horse : horses) { if (ENTITY::DOES_ENTITY_EXIST(horse)) @@ -455,52 +504,47 @@ void EffectHorsesRain::OnDeactivate() PED::DELETE_PED(&horse); } } - + horses.clear(); } void EffectHorsesRain::OnTick() { Effect::OnTick(); - + if (!TimerTick(1000)) { return; } - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - - std::vector models = { - "A_C_Horse_Morgan_Bay", - "A_C_Horse_Arabian_Black", - "A_C_Horse_Arabian_Grey", - "A_C_Horse_Arabian_White", - "A_C_Horse_Shire_DarkBay", - "A_C_Horse_TennesseeWalker_DappleBay" - }; - - Hash skinHash = GAMEPLAY::GET_HASH_KEY((char*)models[rand() % models.size()]); - + + std::vector models = {"A_C_Horse_Morgan_Bay", "A_C_Horse_Arabian_Black", "A_C_Horse_Arabian_Grey", + "A_C_Horse_Arabian_White", "A_C_Horse_Shire_DarkBay", + "A_C_Horse_TennesseeWalker_DappleBay"}; + + Hash skinHash = GAMEPLAY::GET_HASH_KEY((char*) models[rand() % models.size()]); + Ped horse = SpawnPedAroundPlayer(skinHash, false); ENTITY::SET_ENTITY_INVINCIBLE(horse, true); PED::SET_PED_CAN_RAGDOLL(horse, false); - + Vector3 vec = GetRandomCoordAroundPlayer(float(rand() % 20)); - + ENTITY::SET_ENTITY_COORDS(horse, vec.x, vec.y, vec.z + 35.0f, false, false, false, false); ENTITY::SET_ENTITY_VELOCITY(horse, 0.0f, 0.0f, -40.0f); - + horses.push_back(horse); } void EffectDetachWheels::OnActivate() { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + for (int32_t i = 0; i < 4; i++) { invoke(0xd4f5efb55769d272, veh, i); @@ -511,22 +555,22 @@ void EffectDetachWheels::OnActivate() void EffectSetPedsIntoPlayerVehicle::OnActivate() { Effect::OnActivate(); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + auto nearbyPeds = GetNearbyPeds(30); - + bool bIsMount = false; - + Entity veh = 0; int32_t seatsNum = 0; - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + auto hash = ENTITY::GET_ENTITY_MODEL(veh); - + seatsNum = VEHICLE::GET_VEHICLE_MODEL_NUMBER_OF_SEATS(hash) - 1; } else if (PED::IS_PED_ON_MOUNT(playerPed)) @@ -538,21 +582,21 @@ void EffectSetPedsIntoPlayerVehicle::OnActivate() { return; } - + for (auto ped : nearbyPeds) { if (ENTITY::DOES_ENTITY_EXIST(ped)) { auto hash = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, hash); - + if (bModelIsHorse) { continue; } - + if (bIsMount) { bool bIsMountSeatFree = invoke(0xAAB0FE202E9FC9F0, veh, 0); @@ -561,7 +605,7 @@ void EffectSetPedsIntoPlayerVehicle::OnActivate() /** __SET_PED_ON_MOUNT */ invoke(0x028F76B6E78246EB, ped, veh, 0, true); } - + return; } else @@ -569,13 +613,13 @@ void EffectSetPedsIntoPlayerVehicle::OnActivate() for (int32_t i = 0; i < seatsNum; i++) { bool bIsSeatFree = VEHICLE::IS_VEHICLE_SEAT_FREE(veh, i); - + if (bIsSeatFree) { PED::SET_PED_INTO_VEHICLE(ped, veh, i); break; } - + if (i == seatsNum - 1) { return; @@ -589,35 +633,35 @@ void EffectSetPedsIntoPlayerVehicle::OnActivate() void EffectFastPlayersWagon::OnTick() { float maxSpeed = 25.0f; - + Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { Vehicle veh = PED::GET_VEHICLE_PED_IS_IN(playerPed, false); - + float speed = ENTITY::GET_ENTITY_SPEED(veh); - + float newSpeed = speed * 2.0f; - - + + Hash vehModel = ENTITY::GET_ENTITY_MODEL(veh); - + bool bModelIsTrain = invoke(0xFC08C8F8C1EDF174, vehModel); - + if (bModelIsTrain) { maxSpeed = 1000.0f; } - + if (newSpeed > maxSpeed) { newSpeed = maxSpeed; } - + VEHICLE::SET_VEHICLE_FORWARD_SPEED(veh, newSpeed); - - + + if (bModelIsTrain) { VEHICLE::SET_TRAIN_SPEED(veh, newSpeed); @@ -629,14 +673,14 @@ void EffectFastPlayersWagon::OnTick() void EffectRandomWheelsDetaching::OnActivate() { auto nearbyVehs = GetNearbyVehs(50); - + auto playerPed = PLAYER::PLAYER_PED_ID(); - + if (PED::IS_PED_IN_ANY_VEHICLE(playerPed, true)) { nearbyVehs.push_back(PED::GET_VEHICLE_PED_IS_IN(playerPed, false)); } - + for (auto veh : nearbyVehs) { for (int32_t i = 0; i < 4; i++) @@ -651,52 +695,47 @@ void EffectRandomWheelsDetaching::OnActivate() void EffectSpawnRandomVeh::OnActivate() { - static std::vector vehs = { - "CART01", "CART02", "CART03", "CART04", - "CART05", "CART06", "CART07", "CART08", - "ARMYSUPPLYWAGON", "BUGGY01", "BUGGY02", - "BUGGY03", "CHUCKWAGON000X", "CHUCKWAGON002X", - "COACH2", "COACH3", "COACH4", "COACH5", "COACH6", - "coal_wagon", "OILWAGON01X", "POLICEWAGON01X", - "WAGON02X", "WAGON04X", "LOGWAGON", "WAGON03X", - "WAGON05X", "WAGON06X", "WAGONPRISON01X", - "STAGECOACH001X", "STAGECOACH002X", "UTILLIWAG", - "GATCHUCK", "GATCHUCK_2", "wagonCircus01x", - "wagonDairy01x", "wagonWork01x", "wagonTraveller01x", - "KEELBOAT", "CANOE", "CANOETREETRUNK", "SKIFF", - "BREACH_CANNON", "trolley01x" - }; - + static std::vector vehs = {"CART01", "CART02", "CART03", "CART04", "CART05", "CART06", "CART07", + "CART08", "ARMYSUPPLYWAGON", "BUGGY01", "BUGGY02", "BUGGY03", + "CHUCKWAGON000X", "CHUCKWAGON002X", "COACH2", "COACH3", "COACH4", "COACH5", + "COACH6", "coal_wagon", "OILWAGON01X", "POLICEWAGON01X", "WAGON02X", + "WAGON04X", "LOGWAGON", "WAGON03X", "WAGON05X", "WAGON06X", + "WAGONPRISON01X", "STAGECOACH001X", "STAGECOACH002X", "UTILLIWAG", + "GATCHUCK", "GATCHUCK_2", "wagonCircus01x", "wagonDairy01x", "wagonWork01x", + "wagonTraveller01x", "KEELBOAT", "CANOE", "CANOETREETRUNK", "SKIFF", + "BREACH_CANNON", "trolley01x"}; + Hash model = GET_HASH(vehs[rand() % vehs.size()]); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 playerLocation = ENTITY::GET_ENTITY_COORDS(playerPed, true, 0); float playerHeading = ENTITY::GET_ENTITY_HEADING(playerPed); - + LoadModel(model); - - Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, playerHeading, false, false, false, false); - + + Vehicle veh = VEHICLE::CREATE_VEHICLE(model, playerLocation.x, playerLocation.y, playerLocation.z, playerHeading, + false, false, false, false); + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); - + if (ENTITY::DOES_ENTITY_EXIST(veh)) { ChaosMod::vehsSet.insert(veh); } - + PED::SET_PED_INTO_VEHICLE(playerPed, veh, -1); } void EffectHorsesAreDonkeys::OnActivate() { auto nearbyPeds = GetNearbyPeds(140); - + static Hash donkeyModel = GET_HASH("A_C_Donkey_01"); - + for (auto ped : nearbyPeds) { Hash model = ENTITY::GET_ENTITY_MODEL(ped); - + /** IS_MODEL_A_HORSE */ bool bModelIsHorse = invoke(0x772A1969F649E902, model); if (bModelIsHorse) @@ -704,9 +743,9 @@ void EffectHorsesAreDonkeys::OnActivate() Vector3 vec = ENTITY::GET_ENTITY_COORDS(ped, true, 0); Vector3 vel = ENTITY::GET_ENTITY_VELOCITY(ped, 1); float heading = ENTITY::GET_ENTITY_HEADING(ped); - + Ped rider = 0; - + /** _IS_MOUNT_SEAT_FREE */ if (!PED::_0xAAB0FE202E9FC9F0(ped, -1)) { @@ -715,19 +754,19 @@ void EffectHorsesAreDonkeys::OnActivate() /** _REMOVE_PED_FROM_MOUNT */ invoke(0x5337B721C51883A9, rider, 0, 0); } - + if (!ENTITY::IS_ENTITY_A_MISSION_ENTITY(ped)) { ENTITY::SET_ENTITY_AS_MISSION_ENTITY(ped, false, false); - + PED::DELETE_PED(&ped); } - + Ped donkey = SpawnPedAroundPlayer(donkeyModel, false, false); ENTITY::SET_ENTITY_COORDS(donkey, vec.x, vec.y, vec.z, false, false, false, false); ENTITY::SET_ENTITY_VELOCITY(donkey, vel.x, vel.y, vel.z); ENTITY::SET_ENTITY_HEADING(donkey, heading); - + if (rider) { /** __SET_PED_ON_MOUNT */ @@ -752,7 +791,7 @@ void EffectOilWagonsRain::OnDeactivate() VEHICLE::DELETE_VEHICLE(&veh); } } - + vehs.clear(); notExplodedVehs.clear(); } @@ -763,26 +802,26 @@ void EffectOilWagonsRain::OnTick() { static Hash model = GET_HASH("OilWagon01X"); LoadModel(model); - + Ped playerPed = PLAYER::PLAYER_PED_ID(); Vector3 vec = GetRandomCoordAroundPlayer(float(rand() % 50)); Vehicle veh = VEHICLE::CREATE_VEHICLE(model, vec.x, vec.y, vec.z + 175.0f, 0.0f, 0, 0, true, 0); - + ENTITY::SET_ENTITY_ROTATION(veh, 0.0f, 180.0f, 0.0f, 2, 1); ENTITY::SET_ENTITY_VELOCITY(veh, 0.0f, 0.0f, -150.0f); - + vehs.push_back(veh); notExplodedVehs.insert(veh); - + if (ENTITY::DOES_ENTITY_EXIST(veh)) { ChaosMod::vehsSet.insert(veh); } - - + + STREAMING::SET_MODEL_AS_NO_LONGER_NEEDED(model); } - + for (auto veh : notExplodedVehs) { Vector3 vel = ENTITY::GET_ENTITY_VELOCITY(veh, 0); diff --git a/src/Effects/vehs.h b/src/Effects/vehs.h index fd41fba..41de73e 100644 --- a/src/Effects/vehs.h +++ b/src/Effects/vehs.h @@ -4,7 +4,7 @@ #include #include -std::vector GetNearbyVehs(int32_t Max); +std::vector GetNearbyVehs(int32_t Max); class EffectSpawnWagon : public Effect { @@ -26,8 +26,30 @@ class EffectFlipAllVehs : public Effect ID = "flip_vehs"; name = "Flip All Vehicles"; } + + virtual void OnActivate() override; +}; +class EffectTrainsawLaser : public Effect +{ +public: + EffectTrainsawLaser() + { + ID = "trainsaw_laser"; + name = "Trainsaw Laser"; + bTimed = true; + EffectDuration = 30; + } + virtual void OnActivate() override; + + virtual void OnDeactivate() override; + + virtual void OnTick() override; + +private: + std::vector vehs; + }; class EffectMinecartRain : public Effect @@ -40,15 +62,16 @@ class EffectMinecartRain : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; private: - std::vector vehs; - + std::vector vehs; + }; class EffectFullAcceleration : public Effect @@ -61,15 +84,17 @@ class EffectFullAcceleration : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; -private: - std::vector vehs; - std::set horses; +private: + std::vector vehs; + + std::set horses; }; class EffectEveryoneExitsVehs : public Effect @@ -80,7 +105,7 @@ class EffectEveryoneExitsVehs : public Effect ID = "everyone_exits_vehs"; name = "Everyone Exits Their Vehicles"; } - + virtual void OnActivate() override; }; @@ -92,7 +117,7 @@ class EffectSetPlayerIntoRandomVeh : public Effect ID = "set_to_random_veh"; name = "Set Player Into Random Vehicle"; } - + virtual void OnActivate() override; }; @@ -104,7 +129,7 @@ class EffectSpawnHotAirBalloon : public Effect ID = "spawn_balloon"; name = "Spawn Hot Air Balloon"; } - + virtual void OnActivate() override; }; @@ -116,7 +141,7 @@ class EffectIgnitePlayersWagon : public Effect ID = "ignite_wagon"; name = "Ignite Player's Wagon"; } - + virtual void OnActivate() override; }; @@ -128,7 +153,7 @@ class EffectIgniteNearbyWagons : public Effect ID = "ignite_nearby_wagons"; name = "Ignite Nearby Wagons"; } - + virtual void OnActivate() override; }; @@ -140,10 +165,10 @@ class EffectSpawnCanoe : public Effect ID = "spawn_canoe"; name = "Spawn Canoe"; } - - virtual void OnActivate() override; + + virtual void OnActivate() override; }; - + class EffectHorsesRain : public Effect { public: @@ -154,14 +179,16 @@ class EffectHorsesRain : public Effect bTimed = true; EffectDuration = 25; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; + virtual void OnTick() override; private: - std::vector horses; - + std::vector horses; + }; class EffectDetachWheels : public Effect @@ -172,7 +199,7 @@ class EffectDetachWheels : public Effect ID = "detach_wheels"; name = "Detach Wheels From Player's Veh"; } - + virtual void OnActivate() override; }; @@ -184,7 +211,7 @@ class EffectSetPedsIntoPlayerVehicle : public Effect ID = "set_peds_into_player_veh"; name = "Teleport Peds Into Player's Veh"; } - + virtual void OnActivate() override; }; @@ -198,7 +225,7 @@ class EffectFastPlayersWagon : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnTick() override; }; @@ -211,7 +238,7 @@ class EffectRandomWheelsDetaching : public Effect name = "Random Wheels Detaching"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -224,7 +251,7 @@ class EffectSpawnRandomVeh : public Effect name = "Spawn Random Vehicle"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -237,7 +264,7 @@ class EffectHorsesAreDonkeys : public Effect name = "Every Horse Is A Donkey"; bTimed = false; } - + virtual void OnActivate() override; }; @@ -251,13 +278,14 @@ class EffectOilWagonsRain : public Effect bTimed = true; EffectDuration = 30; } - + virtual void OnActivate() override; + virtual void OnDeactivate() override; - + virtual void OnTick() override; private: - std::vector vehs; - std::set notExplodedVehs; + std::vector vehs; + std::set notExplodedVehs; }; diff --git a/src/Misc/config.cpp b/src/Misc/config.cpp index 2464551..96a8075 100644 --- a/src/Misc/config.cpp +++ b/src/Misc/config.cpp @@ -13,70 +13,84 @@ Config::~Config() void Config::Read() { auto path = Config::GetFilePath(); - + if (!std::filesystem::exists(path)) { MessageBeep(MB_ICONERROR); MessageBox(NULL, "Config file not found", "Chaos Mod", MB_OK); return; } - + std::ifstream fileStream(path); - - std::string fileContent( (std::istreambuf_iterator(fileStream)), - (std::istreambuf_iterator()) ); - + + std::string fileContent((std::istreambuf_iterator(fileStream)), (std::istreambuf_iterator())); + if (!fileContent.size()) { MessageBeep(MB_ICONERROR); MessageBox(NULL, "Failed to parse config.json", "Chaos Mod", MB_OK); return; } - + rapidjson::Document document; - + document.Parse(fileContent.c_str()); - + if (document.HasParseError()) { MessageBeep(MB_ICONERROR); MessageBox(NULL, "Failed to parse config.json", "Chaos Mod", MB_OK); return; } - + auto* chaosMod = ChaosMod::Get(); - + if (!chaosMod) { return; } - + if (document.HasMember("interval")) { intervalTime = document["interval"].GetUint(); chaosMod->effectsInterval = intervalTime; } - + if (document.HasMember("votingDuration")) { votingTime = document["votingDuration"].GetUint(); chaosMod->effectsVoteTime = votingTime; } - + if (document.HasMember("twitch")) { bTwitch = document["twitch"].GetBool(); } - + + if (document.HasMember("subEffects")) + { + bSubs = document["subEffects"].GetBool(); + } + + if (document.HasMember("singleEffectPerSub")) + { + bSingleShotSub = document["singleEffectPerSub"].GetBool(); + } + if (document.HasMember("metaInterval")) { metaInterval = document["metaInterval"].GetUint(); } - + + if (document.HasMember("effectDisplayTime")) + { + effectDisplayTime = document["effectDisplayTime"].GetUint(); + } + if (document.HasMember("controls")) { - auto &controlsObject = document["controls"]; - + auto& controlsObject = document["controls"]; + if (controlsObject.IsObject()) { auto parseControl = [&controlsObject](const char* keyName, uint8_t* keyPtr) @@ -84,15 +98,16 @@ void Config::Read() if (controlsObject.HasMember(keyName)) { int keyValue = controlsObject[keyName].GetUint(); - - if (keyValue >= 0 && keyValue <= 0xFF && keyValue != VK_MENU && keyValue != VK_CONTROL && keyValue != VK_SHIFT) + + if (keyValue >= 0 && keyValue <= 0xFF && keyValue != VK_MENU && keyValue != VK_CONTROL && + keyValue != VK_SHIFT) { *keyPtr = uint8_t(keyValue); } - + } }; - + parseControl("activate", &controls.activateMod); parseControl("toggleEffects", &controls.toggleEffects); parseControl("testEffect", &controls.testEffect); @@ -100,34 +115,34 @@ void Config::Read() parseControl("instakill", &controls.instaKill); } } - + if (!document.HasMember("effects")) { return; } - + this->effects.clear(); - + auto effectsList = document["effects"].GetArray(); - + for (auto& effect : effectsList) { ConfigEffect configEffect; - + if (!effect.IsObject() || !effect.HasMember("id")) { continue; } - + configEffect.id = effect["id"].GetString(); configEffect.name = effect["name"].GetString(); configEffect.bEnabled = effect["enabled"].GetBool(); - + if (configEffect.id == "spawn_twitch_viewer" && this->bTwitch == false) { configEffect.bEnabled = false; } - + if (effect.HasMember("chance")) { configEffect.chance = effect["chance"].GetUint(); @@ -141,21 +156,21 @@ void Config::Read() configEffect.chance = 1; } } - + if (effect.HasMember("duration")) { configEffect.duration = effect["duration"].GetUint(); } - + effects.push_back(configEffect); - + if (!configEffect.bEnabled) { continue; } - + auto* effect = chaosMod->EffectsMap[configEffect.id]; - + if (effect) { if (configEffect.name.size()) @@ -173,21 +188,21 @@ void Config::Read() if (document.HasMember("meta")) { auto metaList = document["meta"].GetArray(); - + for (auto& meta : metaList) { ConfigEffect configMetaEffect; - + if (!meta.IsObject() || !meta.HasMember("id")) { continue; } - + configMetaEffect.id = meta["id"].GetString(); configMetaEffect.name = meta["name"].GetString(); configMetaEffect.bEnabled = meta["enabled"].GetBool(); configMetaEffect.duration = meta["duration"].GetUint(); - + auto* metaEffect = chaosMod->MetaEffectsMap[configMetaEffect.id]; if (metaEffect) { @@ -197,7 +212,7 @@ void Config::Read() } } } - + } std::filesystem::path Config::GetFilePath() diff --git a/src/Misc/config.h b/src/Misc/config.h index 691919d..18901a0 100644 --- a/src/Misc/config.h +++ b/src/Misc/config.h @@ -27,23 +27,27 @@ class Config { public: Config(); + ~Config(); - + /** Reads config file and saves data to this object */ void Read(); public: - + uint32_t intervalTime = 60; uint32_t votingTime = 30; uint32_t metaInterval = 900; - + uint32_t effectDisplayTime = 15; + bool bTwitch = false; - - std::vector effects; - + bool bSubs = false; + bool bSingleShotSub = false; + + std::vector effects; + ConfigControls controls; public: static std::filesystem::path GetFilePath(); - + }; \ No newline at end of file diff --git a/src/Misc/menu.cpp b/src/Misc/menu.cpp index 756578e..e266849 100644 --- a/src/Misc/menu.cpp +++ b/src/Misc/menu.cpp @@ -18,11 +18,11 @@ bool ModMenu::IsVisible() void ModMenu::ToggleVisibility() { bMenuEnabled = !bMenuEnabled; - + if (bMenuEnabled) { OpenSubmenu(EModSubmenu::Main); - + buttons = {}; menuTitle = "Main menu"; prevSubMenu = EModSubmenu::Main; @@ -37,13 +37,13 @@ void ModMenu::Draw() { /** Black background */ GRAPHICS::DRAW_RECT(0.5f, 0.5f, 450.0f / 1920.0f, 450.0f / 1080.0f, 0, 0, 0, 205, 0, 0); - + /** Draw menu title */ GRAPHICS::DRAW_RECT(0.5f, 0.5f - (245.0f / 1080.0f), 450.0f / 1920.0f, 40.0f / 1080.0f, 0, 0, 0, 255, 0, 0); - + /** Draw menu header */ GRAPHICS::DRAW_RECT(0.5f, 0.5f - (307.5 / 1080.0f), 450.0f / 1920.0f, 125.0f / 1080.0f, 143, 6, 6, 255, 0, 0); - + } void ModMenu::OnKeyPressed(uint8_t key) @@ -55,23 +55,23 @@ void ModMenu::OpenSubmenu(EModSubmenu menu) this->buttons.clear(); switch (menu) { - case EModSubmenu::Main: - - for (int32_t i = 0; i < 50; i++) - { - ModMenuButton button; - button.text = "Button Test "; - button.text += std::to_string(i + 1); - - buttons.push_back(button); - } - break; - case EModSubmenu::Effects: - break; - case EModSubmenu::Settings: - break; - default: - break; + case EModSubmenu::Main: + + for (int32_t i = 0; i < 50; i++) + { + ModMenuButton button; + button.text = "Button Test "; + button.text += std::to_string(i + 1); + + buttons.push_back(button); + } + break; + case EModSubmenu::Effects: + break; + case EModSubmenu::Settings: + break; + default: + break; } } diff --git a/src/Misc/menu.h b/src/Misc/menu.h index b32262a..7668669 100644 --- a/src/Misc/menu.h +++ b/src/Misc/menu.h @@ -6,21 +6,22 @@ enum class EModSubmenu : uint8_t { - Main, - Effects, - Settings + Main, Effects, Settings }; class ModMenuButton { public: ModMenuButton(); + ~ModMenuButton(); - + std::string text = ""; - + virtual void Draw(uint8_t index); + virtual void OnKeyPressed(uint8_t key); + virtual void OnSelected(); }; @@ -28,30 +29,31 @@ class ModMenu { public: ModMenu(); + ~ModMenu(); - + bool IsVisible(); - + void ToggleVisibility(); - + void Draw(); - + void OnKeyPressed(uint8_t key); private: bool bMenuEnabled = false; EModSubmenu submenu; - - std::vector buttons; - + + std::vector buttons; + uint32_t buttonSelectedID = 0; - + EModSubmenu prevSubMenu; - + std::string menuTitle; - + uint32_t maxButtons = 9; - + void OpenSubmenu(EModSubmenu menu); }; diff --git a/src/Twitch/src/core/config.ts b/src/Twitch/src/core/config.ts index dc4ceae..9856e01 100644 --- a/src/Twitch/src/core/config.ts +++ b/src/Twitch/src/core/config.ts @@ -1,63 +1,65 @@ -import { promises as fsPromises } from 'fs'; +import {promises as fsPromises} from 'fs'; export interface IConfig { - /** Twitch auth token */ - token: string; - /** Use 127.0.0.1 for internal resources when true. */ - local_ip: boolean; - max_options: 4 | 8; -}; + /** Twitch auth token */ + token: string; + /** Use 127.0.0.1 for internal resources when true. */ + local_ip: boolean; + max_options: 4 | 8; + weighted_voting: boolean; +} let _config: IConfig = { - token: "", - local_ip: true, - max_options: 4 + token: "", + local_ip: true, + max_options: 4, + weighted_voting: false }; let configPath = 'config.json'; -export function getConfig(): IConfig +export function getConfig(): IConfig { - return _config; + return _config; } export async function readConfig(): Promise { - try - { - const fileData = await fsPromises.readFile(configPath, { encoding: 'utf-8' }); - - if (fileData) - { - _config = JSON.parse(fileData); - - if (_config.max_options != 4 && _config.max_options != 8) - { - _config.max_options = 4; - } - } - } - catch (err) - { - console.log(err); - } + try + { + const fileData = await fsPromises.readFile(configPath, {encoding: 'utf-8'}); + + if (fileData) + { + _config = JSON.parse(fileData); + + if (_config.max_options != 4 && _config.max_options != 8) + { + _config.max_options = 4; + } + } + } + catch (err) + { + console.log(err); + } } export async function saveConfig(): Promise { - try - { - await fsPromises.writeFile(configPath, JSON.stringify(_config, null, '\t'), { encoding: 'utf-8' }); - } - catch (err) - { - console.log(err); - } -}; + try + { + await fsPromises.writeFile(configPath, JSON.stringify(_config, null, '\t'), {encoding: 'utf-8'}); + } + catch (err) + { + console.log(err); + } +} export async function updateToken(newToken: string): Promise { - _config.token = newToken; - await saveConfig(); + _config.token = newToken; + await saveConfig(); } \ No newline at end of file diff --git a/src/Twitch/src/core/index.ts b/src/Twitch/src/core/index.ts index c5fb0b5..1e9af45 100644 --- a/src/Twitch/src/core/index.ts +++ b/src/Twitch/src/core/index.ts @@ -1,30 +1,30 @@ -import { getConfig, readConfig } from "./config"; -import { startHTTPServer } from "./server"; -import { connectWebsocketClient, startWSServer } from "./sockets"; -import { getTwitchUser, startListeningChat } from "./twitch"; +import {getConfig, readConfig} from "./config"; +import {startHTTPServer} from "./server"; +import {connectWebsocketClient, getWebSocket, startWSServer} from "./sockets"; +import {getTwitchUser, startListeningChat} from "./twitch"; export function randomInteger(min: number, max: number): number { - const rand = min - 0.5 + Math.random() * (max - min + 1); - return Math.round(rand); + const rand = min - 0.5 + Math.random() * (max - min + 1); + return Math.round(rand); } async function Init(): Promise { - await readConfig(); - const _conf = getConfig(); - const bUseLocalHost = _conf.local_ip != undefined ? _conf.local_ip : true; - startHTTPServer(bUseLocalHost); - startWSServer(bUseLocalHost); - - const login = await getTwitchUser(); - - if (login) - { - startListeningChat(login); - } - - connectWebsocketClient(); -}; + await readConfig(); + const _conf = getConfig(); + const bUseLocalHost = _conf.local_ip != undefined ? _conf.local_ip : true; + startHTTPServer(bUseLocalHost); + startWSServer(bUseLocalHost); + + const login = await getTwitchUser(); + + if (login) + { + startListeningChat(login, getWebSocket); + } + + connectWebsocketClient(); +} Init(); diff --git a/src/Twitch/src/core/server.ts b/src/Twitch/src/core/server.ts index 28f8f22..7f3c181 100644 --- a/src/Twitch/src/core/server.ts +++ b/src/Twitch/src/core/server.ts @@ -1,66 +1,69 @@ import Fastify from "fastify"; import path from 'path'; import fs from 'fs'; -import { updateToken } from "./config"; +import {updateToken} from "./config"; const fastify = Fastify({ - logger: false + logger: false }); fastify.get('/', (req, reply) => { - const stream = fs.createReadStream(path.join(__dirname, '../', 'front/index.html')); - reply.type('text/html').send(stream); + const stream = fs.createReadStream(path.join(__dirname, '../', 'front/index.html')); + reply.type('text/html').send(stream); }); fastify.get('/index.js', (req, reply) => { - const stream = fs.createReadStream(path.join(__dirname, '../', 'front/index.js')); - reply.type('text/javascript').send(stream); + const stream = fs.createReadStream(path.join(__dirname, '../', 'front/index.js')); + reply.type('text/javascript').send(stream); }); fastify.get('/style.css', (req, reply) => { - const stream = fs.createReadStream(path.join(__dirname, '../', 'front/style.css')); - reply.type('text/css').send(stream); + const stream = fs.createReadStream(path.join(__dirname, '../', 'front/style.css')); + reply.type('text/css').send(stream); }); fastify.get('/login', (req, reply) => { - const url = `https://id.twitch.tv/oauth2/authorize?response_type=token&client_id=sdyeqfly1o09e63sfohhbcfuptzdu2&redirect_uri=http://localhost:9148/token&scope=chat:read`; - reply.redirect(url); + const url = `https://id.twitch.tv/oauth2/authorize?response_type=token&client_id=sdyeqfly1o09e63sfohhbcfuptzdu2&redirect_uri=http://localhost:9148/token&scope=chat:read`; + reply.redirect(url); }); fastify.get('/token', (req, reply) => { - const stream = fs.createReadStream(path.join(__dirname, '../', 'front/token.html')); - reply.type('text/html').send(stream); + const stream = fs.createReadStream(path.join(__dirname, '../', 'front/token.html')); + reply.type('text/html').send(stream); }); fastify.post('/token-update', (req, reply) => { - reply.send('OK'); - - console.log(req.query); - - if (req.query) - { - const query = req.query as Record; - - if (query['token'] && query['token'].length) - { - updateToken(query['token']); - } - } + reply.send('OK'); + + console.log(req.query); + + if (req.query) + { + const query = req.query as Record; + + if (query['token'] && query['token'].length) + { + updateToken(query['token']); + } + } }); export function startHTTPServer(bLocalIP: boolean = true): void { - const ip = bLocalIP ? '127.0.0.1' : '0.0.0.0'; - fastify.listen({ port: 9148, host: ip }, (err, addr) => - { - if (err) throw err; - - console.log('[Server] Server is listening on ' + addr); - }); + const ip = bLocalIP ? '127.0.0.1' : '0.0.0.0'; + fastify.listen({port: 9148, host: ip}, (err, addr) => + { + if (err) + { + throw err; + } + + console.log('[Server] Server is listening on ' + addr); + }); } \ No newline at end of file diff --git a/src/Twitch/src/core/sockets.ts b/src/Twitch/src/core/sockets.ts index 8133b42..31b991f 100644 --- a/src/Twitch/src/core/sockets.ts +++ b/src/Twitch/src/core/sockets.ts @@ -1,8 +1,15 @@ -import { WebSocketServer, WebSocket } from 'ws'; -import { getConfig, readConfig } from './config'; -import { randomInteger } from './index'; -import { clearChatUsernames, getRandomTwitchNickname, getTwitchUser, startListeningChat } from './twitch'; -import { getPollNames, getVotesArray, getWInnerIndex, IsVotingEnabled, resetPoll, setVotingActive, updateEffectNamesFromGame } from './voting'; +import {WebSocket, WebSocketServer} from 'ws'; +import {getConfig, readConfig} from './config'; +import {clearChatUsernames, getRandomTwitchNickname, getTwitchUser, startListeningChat} from './twitch'; +import { + getPollNames, + getVotesArray, + getWinnerIndex, + IsVotingEnabled, + resetPoll, + setVotingActive, + updateEffectNamesFromGame +} from './voting'; let gameWebSocketClient: WebSocket | null = null; let clientReconnectInterval: NodeJS.Timer | null = null; @@ -13,12 +20,12 @@ async function onModEnabled(): Promise try { await readConfig(); - + const login = await getTwitchUser(); - + if (login) { - startListeningChat(login); + startListeningChat(login, getWebSocket); } } catch (err) @@ -28,12 +35,17 @@ async function onModEnabled(): Promise } let reconnectsCount = 0; -/** +/** * False - send 1-4 options * True - send 5-8 options */ let bPrevOptionsType = false; +export function getWebSocket(): WebSocket | null +{ + return gameWebSocketClient; +} + export function connectWebsocketClient(): void { const _config = getConfig(); @@ -42,9 +54,9 @@ export function connectWebsocketClient(): void { maxOptions = 4; } - + gameWebSocketClient = new WebSocket('ws://127.0.0.1:9149'); - + gameWebSocketClient.on('open', () => { if (clientReconnectInterval) @@ -52,34 +64,34 @@ export function connectWebsocketClient(): void clearInterval(clientReconnectInterval); clientReconnectInterval = null; } - + reconnectsCount = 0; }); - + gameWebSocketClient.on('error', (err) => { // console.error(err); }); - + gameWebSocketClient.on('message', async (data) => { if (!gameWebSocketClient) { return; } - + try { const msg = data.toString(); console.log(msg); - + function resetPollAndSend() { resetPoll(); - sendVotes(getVotesArray()); - updatePollOptions(getPollNames()); + sendVotes(getVotesArray(), _config.weighted_voting); + updatePollOptions(getPollNames(), _config.weighted_voting); } - + switch (msg) { case 'mod_enabled': @@ -90,68 +102,69 @@ export function connectWebsocketClient(): void bPrevOptionsType = false; break; case 'mod_disabled': - { - setVotingActive(false); - resetPollAndSend(); - setPollVisible(false); - clearChatUsernames(); - break; - } + { + setVotingActive(false); + resetPollAndSend(); + setPollVisible(false); + clearChatUsernames(); + break; + } case 'vote_ended': - { - setPollVisible(true); - sendVotes(getVotesArray()); - setVotingActive(false); - - const winner: number = getWInnerIndex(); - - updateWinner(winner); - - gameWebSocketClient.send(JSON.stringify({ - type: "activate-effect", - index: winner, - })); - - setPollFadeOut(); - break; - } + { + setPollVisible(true); + sendVotes(getVotesArray(), _config.weighted_voting); + setVotingActive(false); + + const winner: number = getWinnerIndex(_config.weighted_voting); + + updateWinner(winner); + + gameWebSocketClient.send(JSON.stringify({ + type: "activate-effect", + index: winner, + })); + + setPollFadeOut(); + break; + } case 'request-twitch-viewer-name': - { - gameWebSocketClient.send(JSON.stringify({ - type: "spawn-twitch-viewer", - name: getRandomTwitchNickname(), - })); - break; - } + { + gameWebSocketClient.send(JSON.stringify({ + type: "spawn-twitch-viewer", + name: getRandomTwitchNickname(), + })); + break; + } default: + { + try { - try + const parsedJSON = JSON.parse(msg); + + switch (parsedJSON['type']) { - const parsedJSON = JSON.parse(msg); - - switch (parsedJSON['type']) { - case 'vote_activate': - const effectNames = parsedJSON['data']; + case 'vote_activate': + const effectNames = parsedJSON['data']; + + updateEffectNamesFromGame(effectNames); + setVotingActive(true); + sendVotes(getVotesArray(), _config.weighted_voting); + updatePollOptions(getPollNames(), _config.weighted_voting); + setPollVisible(true); + if (maxOptions != 4) + { + setPollOptionsNumber(bPrevOptionsType); - updateEffectNamesFromGame(effectNames); - setVotingActive(true); - sendVotes(getVotesArray()); - updatePollOptions(getPollNames()); - setPollVisible(true); - if (maxOptions != 4) - { - setPollOptionsNumber(bPrevOptionsType); - - bPrevOptionsType = !bPrevOptionsType; - } - break; - } - } - catch (err) - { - console.error(err); + bPrevOptionsType = !bPrevOptionsType; + } + break; } } + catch (err) + { + console.error(err); + } + } break; } } @@ -160,26 +173,26 @@ export function connectWebsocketClient(): void console.error(error); } }); - + gameWebSocketClient.on('close', () => { reconnectsCount++; - + if (reconnectsCount >= 20) { process.exit(0); return; } - - + + if (clientReconnectInterval) { clearInterval(clientReconnectInterval); clientReconnectInterval = null; } - + console.log('[GameSocket] Reconnecting..'); - + clientReconnectInterval = setInterval(() => { connectWebsocketClient(); @@ -191,24 +204,24 @@ const overlayClients: Array = []; let overlayServer: WebSocketServer | null = null; -function sendVotes(votes: Array) +function sendVotes(votes: Array, weighted_voting: boolean) { if (overlayServer) { for (let ws of overlayServer.clients) { - ws.send(JSON.stringify({ type: 'update-votes', data: votes })); + ws.send(JSON.stringify({type: 'update-votes', data: votes, weighted_voting: weighted_voting})); } } } -function updatePollOptions(options: Array) +function updatePollOptions(options: Array, weighted_voting: boolean) { if (overlayServer) { for (let ws of overlayServer.clients) { - ws.send(JSON.stringify({ type: 'new-options', data: options })); + ws.send(JSON.stringify({type: 'new-options', data: options, weighted_voting: weighted_voting})); } } } @@ -219,7 +232,7 @@ function updateWinner(winner: number) { for (let ws of overlayServer.clients) { - ws.send(JSON.stringify({ type: 'set-winner', data: winner })); + ws.send(JSON.stringify({type: 'set-winner', data: winner})); } } } @@ -231,7 +244,7 @@ function setPollStarted() { for (let ws of overlayServer.clients) { - ws.send(JSON.stringify({ type: 'poll-started' })); + ws.send(JSON.stringify({type: 'poll-started'})); } } } @@ -242,7 +255,7 @@ function setPollVisible(bVisible: boolean) { for (let ws of overlayServer.clients) { - ws.send(JSON.stringify({ type: 'set-poll-visible', data: bVisible })); + ws.send(JSON.stringify({type: 'set-poll-visible', data: bVisible})); } } } @@ -253,7 +266,7 @@ function setPollFadeOut() { for (let ws of overlayServer.clients) { - ws.send(JSON.stringify({ type: 'set-poll-fade-out' })); + ws.send(JSON.stringify({type: 'set-poll-fade-out'})); } } } @@ -264,49 +277,51 @@ function setPollOptionsNumber(bMoreOptions: boolean) { for (let ws of overlayServer.clients) { - ws.send(JSON.stringify({ type: 'set-poll-options-number', data: bMoreOptions })); + ws.send(JSON.stringify({type: 'set-poll-options-number', data: bMoreOptions})); } } } export function startWSServer(bLocalIP: boolean = true) { - const ip = bLocalIP ? '127.0.0.1' : '0.0.0.0'; - overlayServer = new WebSocketServer({ port: 9147, host: ip }); - - // setVotingActive(true); - // setRandomPollOptions(); - - overlayServer.on('connection', (ws) => { - + const ip = bLocalIP ? '127.0.0.1' : '0.0.0.0'; + overlayServer = new WebSocketServer({port: 9147, host: ip}); + + // setVotingActive(true); + // setRandomPollOptions(); + + overlayServer.on('connection', (ws) => + { + overlayClients.push(ws); - let votesInterval: NodeJS.Timer | null = null; - - ws.on('message', function message(data) { - console.log('received: %s', data); - }); + let votesInterval: NodeJS.Timer | null = null; - ws.on('close', () => - { + ws.on('message', function message(data) + { + console.log('received: %s', data); + }); + + ws.on('close', () => + { if (votesInterval) { clearInterval(votesInterval); votesInterval = null; } - + const index = overlayClients.indexOf(ws); - + if (index != -1) { overlayClients.splice(index, 1); } - }); - + }); + function sendVotes(votes: Array): void { - ws.send(JSON.stringify({ type: 'update-votes', data: votes })); + ws.send(JSON.stringify({type: 'update-votes', data: votes})); } - + votesInterval = setInterval(() => { if (IsVotingEnabled()) @@ -314,10 +329,10 @@ export function startWSServer(bLocalIP: boolean = true) sendVotes(getVotesArray()); } }, 1000); - - ws.send(JSON.stringify({ type: 'new-options', data: getPollNames() })); - - }); + + ws.send(JSON.stringify({type: 'new-options', data: getPollNames()})); + + }); } diff --git a/src/Twitch/src/core/twitch.ts b/src/Twitch/src/core/twitch.ts index 658ecda..9258e6c 100644 --- a/src/Twitch/src/core/twitch.ts +++ b/src/Twitch/src/core/twitch.ts @@ -1,20 +1,21 @@ import tmi from 'tmi.js'; -import { getConfig } from './config'; -import { newVote } from './voting'; +import {WebSocket} from "ws"; +import {getConfig} from './config'; +import {newVote} from './voting'; import axios from 'axios'; -import { randomInteger } from '.'; +import {randomInteger} from '.'; let client: tmi.Client | null = null; interface ITwitchProfile { - error: undefined | true, - data: [{ - id: number, - login: string, - display_name: string, - profile_image_url: string - }]; + error: undefined | true, + data: [{ + id: number, + login: string, + display_name: string, + profile_image_url: string + }]; } export let chatUsernames: Array = []; @@ -22,131 +23,170 @@ export let chatUsernames: Array = []; export async function getTwitchUser(): Promise { - try - { - const conf = getConfig(); - - if (!conf.token) - { - return null; - } - - const fetchedData = await axios.get('https://api.twitch.tv/helix/users', { - headers: { - 'Client-ID': 'sdyeqfly1o09e63sfohhbcfuptzdu2', - 'Authorization': `Bearer ${conf.token}` - }, - responseType: 'json' - }); - - const jsonData = (await fetchedData.data) as ITwitchProfile; - - if (jsonData && !jsonData.error) - { - const profile = jsonData.data[0]; - return profile.login; - } - - } - catch (err) - { - console.error(err); - } - - return null; + try + { + const conf = getConfig(); + + if (!conf.token) + { + return null; + } + + const fetchedData = await axios.get('https://api.twitch.tv/helix/users', { + headers: { + 'Client-ID': 'sdyeqfly1o09e63sfohhbcfuptzdu2', + 'Authorization': `Bearer ${conf.token}` + }, + responseType: 'json' + }); + + const jsonData = (await fetchedData.data) as ITwitchProfile; + + if (jsonData && !jsonData.error) + { + const profile = jsonData.data[0]; + return profile.login; + } + + } + catch (err) + { + console.error(err); + } + + return null; } - -export function startListeningChat(login: string): void +export function handleSub(ws: WebSocket, channel: string, username: string, num_subs: number): void { - if (client) - { - client.disconnect(); - client = null; - } - - const conf = getConfig(); - - if (!conf.token) - { - return; - } - - client = new tmi.Client({ - connection: - { - reconnect: true, - secure: true - }, - identity: - { - username: login, - password: conf.token, - }, - channels: - [ - login - ] - }); - - client.connect(); - - client.on('message', (target, context, msg, self) => - { - msg = msg.trim(); - - if (!context) - { - context = {}; - } - - if (context['message-type'] === 'chat' && context['user-id']) - { - let num = Number(msg); - - if (isFinite(num) && num >= 1 && num <= 8) - { - if (num >= 5) - { - num -= 4; - } - - newVote(Math.floor(num) - 1, context['user-id']); - - const displayName = context['display-name'] || ''; - const username = context.username || ''; - - const name = username == displayName.toLowerCase() ? displayName : username; - - if (!chatUsernames.includes(name)) - { - chatUsernames.push(name); - - if (chatUsernames.length >= 50) - { - chatUsernames.splice(0, 1); - } - } - } - } - }); + if (ws !== null) + { + ws.send(JSON.stringify({ + type: "subscribe-event", + channel: channel, + username: username, + num_subs: num_subs + })); + } +} - client.on('connected', (addr, port) => { +export function startListeningChat(login: string, ws_provider: Function): void +{ + if (client) + { + client.disconnect(); + client = null; + } + + const conf = getConfig(); + + if (!conf.token) + { + return; + } + + client = new tmi.Client({ + connection: + { + reconnect: true, + secure: true + }, + identity: + { + username: login, + password: conf.token, + }, + channels: + [ + login + ] + }); + + client.connect(); + + client.on("giftpaidupgrade", (channel: string, username: string, sender: string, userstate: any) => + { + handleSub(ws_provider(), channel, username, 1); + }); + + client.on("resub", (channel: string, username: string, months: number, message: string, userstate: any, methods: any) => + { + handleSub(ws_provider(), channel, username, 1); + }); + + client.on("subgift", (channel: string, username: string, months: number, recipient: string, methods: any, userstate: any) => + { + handleSub(ws_provider(), channel, username, 1); + }); + + /* + client.on("submysterygift", (channel: string, username: string, num_subs: number, methods: any, userstate: any) => { + handleSub(ws_provider(), channel, username, num_subs); + }); + */ + + client.on("subscription", (channel: string, username: string, method: any, message: string, userstate: any) => + { + handleSub(ws_provider(), channel, username, 1) + }); + + client.on('message', (target: string, context: any, msg: string, self: boolean) => + { + msg = msg.trim(); + + if (!context) + { + context = {}; + } + + if (context['message-type'] === 'chat' && context['user-id']) + { + let num = Number(msg); + + if (isFinite(num) && num >= 1 && num <= 8) + { + if (num >= 5) + { + num -= 4; + } + + newVote(Math.floor(num) - 1, context['user-id']); + + const displayName = context['display-name'] || ''; + const username = context.username || ''; + + const name = username == displayName.toLowerCase() ? displayName : username; + + if (!chatUsernames.includes(name)) + { + chatUsernames.push(name); + + if (chatUsernames.length >= 50) + { + chatUsernames.splice(0, 1); + } + } + } + } + }); + + client.on('connected', (addr: string, port: number) => + { console.log(`[Twitch] Connected to ${addr}:${port}`) }); } export function getRandomTwitchNickname(): string { - if (!chatUsernames.length) - { - return ""; - } - - return chatUsernames[randomInteger(0, chatUsernames.length - 1)]; -}; + if (!chatUsernames.length) + { + return ""; + } + + return chatUsernames[randomInteger(0, chatUsernames.length - 1)]; +} export function clearChatUsernames(): void { - chatUsernames = []; + chatUsernames = []; } \ No newline at end of file diff --git a/src/Twitch/src/core/voting.ts b/src/Twitch/src/core/voting.ts index d88a8de..b554a27 100644 --- a/src/Twitch/src/core/voting.ts +++ b/src/Twitch/src/core/voting.ts @@ -1,142 +1,165 @@ -interface IEffectVotingData +interface IEffectVotingData { - name: string, - /** Array of twitch user ids */ - votes: Array + name: string, + /** Array of twitch user ids */ + votes: Array } const poll: [IEffectVotingData, IEffectVotingData, IEffectVotingData, IEffectVotingData] = [ - { - name: '', - votes: [] - }, - { - name: '', - votes: [] - }, - { - name: '', - votes: [] - }, - { - name: '', - votes: [] - } + { + name: '', + votes: [] + }, + { + name: '', + votes: [] + }, + { + name: '', + votes: [] + }, + { + name: '', + votes: [] + } ]; let bVotingActive = false; export function newVote(optionNum: number, userID: string) { - if (!bVotingActive) - { - return; - } - - for (let i = 0; i < poll.length; i++) - { - const index = poll[i].votes.indexOf(userID); - if (index !== -1) - { - poll[i].votes.splice(index, 1); - } - } - - if (poll[optionNum]) - { - poll[optionNum].votes.push(userID); - } + if (!bVotingActive) + { + return; + } + + for (let i = 0; i < poll.length; i++) + { + const index = poll[i].votes.indexOf(userID); + if (index !== -1) + { + poll[i].votes.splice(index, 1); + } + } + + if (poll[optionNum]) + { + poll[optionNum].votes.push(userID); + } } -export function getWinnerIDByVotes(votes: Array): number +export function getWinnerIDByVotes(votes: Array, weighted_random: boolean): number { - const total = votes.reduce((prev, cur) => { return prev + cur; }); - - /** Return random effect if no votes */ - if (!total) - { - return votes.length - 1; - } - - let max = 0; - let indexMax = 0; - - for (let i = 0; i < votes.length; i++) - { - if (votes[i] > max) - { - indexMax = i; - max = votes[i]; - } - } - - return indexMax; + if (!weighted_random) + { + const total = votes.reduce((prev, cur) => + { + return prev + cur; + }); + + /** Return random effect if no votes */ + if (!total) + { + return votes.length - 1; + } + + let max = 0; + let indexMax = 0; + + for (let i = 0; i < votes.length; i++) + { + if (votes[i] > max) + { + indexMax = i; + max = votes[i]; + } + } + return indexMax; + } + + let i: number; + let weights: number[] = []; + + for (i = 0; i < votes.length; i++) + { + weights[i] = votes[i] + (weights[i - 1] || 0); + } + + let rand = Math.random() * weights[weights.length - 1]; + + for (i = 0; i < weights.length; i++) + { + if (weights[i] > rand) + { + break; + } + } + + return i; } -export function getWInnerIndex(): number +export function getWinnerIndex(weighted_random: boolean): number { - let arrVotes = []; - - for (let i = 0; i < poll.length; i++) - { - arrVotes.push(poll[i].votes.length); - } - - const winnerId = getWinnerIDByVotes(arrVotes); - - return winnerId; + let arrVotes = []; + + for (let i = 0; i < poll.length; i++) + { + arrVotes.push(poll[i].votes.length); + } + + return getWinnerIDByVotes(arrVotes, weighted_random); } export function setVotingActive(value: boolean): void { - bVotingActive = value; -}; + bVotingActive = value; +} export function getPollNames(): Array { - const names: Array = []; - for (let i = 0; i < poll.length; i++) - { - names.push(poll[i].name); - } - - return names; + const names: Array = []; + for (let i = 0; i < poll.length; i++) + { + names.push(poll[i].name); + } + + return names; } export function getVotesArray(): Array { - const arrVotes = []; - - for (let i = 0; i < poll.length; i++) - { - arrVotes.push(poll[i].votes.length); - } - return arrVotes; + const arrVotes = []; + + for (let i = 0; i < poll.length; i++) + { + arrVotes.push(poll[i].votes.length); + } + return arrVotes; } export function IsVotingEnabled() { - return bVotingActive; + return bVotingActive; } export function resetPoll(): void -{ - for (let i = 0; i < 3; i++) - { - poll[i].name = `Effect ${i+1}`; - poll[i].votes = []; - } - - poll[3].name = 'Random Effect'; - poll[3].votes = []; +{ + for (let i = 0; i < 3; i++) + { + poll[i].name = `Effect ${i + 1}`; + poll[i].votes = []; + } + + poll[3].name = 'Random Effect'; + poll[3].votes = []; } export function updateEffectNamesFromGame(names: Array) { - for (let i = 0; i < poll.length; i++) - { - poll[i].name = names[i]; - poll[i].votes = []; - } + for (let i = 0; i < poll.length; i++) + { + poll[i].name = names[i]; + poll[i].votes = []; + } } \ No newline at end of file diff --git a/src/Twitch/src/front/index.html b/src/Twitch/src/front/index.html index 13e74eb..3bc2ca3 100644 --- a/src/Twitch/src/front/index.html +++ b/src/Twitch/src/front/index.html @@ -1,21 +1,21 @@ - - - - - - ChaosModRDR + + + + + + ChaosModRDR -
-
- Votes: 0 -
-
- -
-
+
+
+ Votes: 0 +
+
+ +
+
\ No newline at end of file diff --git a/src/Twitch/src/front/index.ts b/src/Twitch/src/front/index.ts index 79135dd..aaee6b7 100644 --- a/src/Twitch/src/front/index.ts +++ b/src/Twitch/src/front/index.ts @@ -4,160 +4,174 @@ const options: Array = []; interface IData { - votes: number; - options: Array<[number, HTMLDivElement]>; -}; + votes: number; + options: Array<[number, HTMLDivElement]>; +} -const data: IData = -{ - votes: 0, - options: [] -}; +const data: IData = + { + votes: 0, + options: [] + }; function addEffectOption() { - const container = document.getElementById('container'); - - if (container) - { - const newOption = document.createElement('div'); - data.options.push([0, newOption]); - - newOption.classList.add('vote-option'); - - const progressBar = document.createElement('div'); - progressBar.classList.add('vote-option-progress-bar'); - // progressBar.style.transform = 'scaleX(0.0)'; - newOption.appendChild(progressBar); - - const wrapper = document.createElement('div'); - wrapper.classList.add('vote-option-wrapper'); - newOption.appendChild(wrapper); - - const optionID = data.options.length; - - const optionIndexElem = document.createElement('div'); - optionIndexElem.innerText = `${optionID}`; - optionIndexElem.classList.add('vote-index'); - wrapper.appendChild(optionIndexElem); - - const optionNameElem = document.createElement('div'); - optionNameElem.innerText = `Effect #${optionID}`; - optionNameElem.classList.add('vote-option-name'); - wrapper.appendChild(optionNameElem); - - const optionVotes = document.createElement('div'); - optionVotes.innerText = `0`; - optionVotes.classList.add('vote-count'); - wrapper.appendChild(optionVotes); - - container.appendChild(newOption); - } + const container = document.getElementById('container'); + + if (container) + { + const newOption = document.createElement('div'); + data.options.push([0, newOption]); + + newOption.classList.add('vote-option'); + + const progressBar = document.createElement('div'); + progressBar.classList.add('vote-option-progress-bar'); + // progressBar.style.transform = 'scaleX(0.0)'; + newOption.appendChild(progressBar); + + const wrapper = document.createElement('div'); + wrapper.classList.add('vote-option-wrapper'); + newOption.appendChild(wrapper); + + const optionID = data.options.length; + + const optionIndexElem = document.createElement('div'); + optionIndexElem.innerText = `${optionID}`; + optionIndexElem.classList.add('vote-index'); + wrapper.appendChild(optionIndexElem); + + const optionNameElem = document.createElement('div'); + optionNameElem.innerText = `Effect #${optionID}`; + optionNameElem.classList.add('vote-option-name'); + wrapper.appendChild(optionNameElem); + + const optionVotes = document.createElement('div'); + optionVotes.innerText = `0`; + optionVotes.classList.add('vote-count'); + wrapper.appendChild(optionVotes); + + container.appendChild(newOption); + } } function initOptions(num: number) { - for (let i = 0; i < num; i++) - { - addEffectOption(); - } + for (let i = 0; i < num; i++) + { + addEffectOption(); + } } initOptions(4); -function updateEffects(effects: Array): void +function updateEffects(effects: Array, weighted_voting: boolean): void { - for (let i = 0; i < effects.length; i++) - { - if (data.options[i]) - { - data.options[i][0] = 0; - const wrapper = data.options[i][1]; - (wrapper.children[0] as HTMLDivElement).style.transform = 'scaleX(0.0)'; - (wrapper as HTMLDivElement).style.opacity = '1.0'; - (wrapper.children[1].children[1] as HTMLDivElement).innerText = effects[i]; - (wrapper.children[1].children[2] as HTMLDivElement).innerText = `0`; - } - } - - data.votes = 0; + let start_value = weighted_voting ? Math.round(100.0 / effects.length) + "%" : "0"; + for (let i = 0; i < effects.length; i++) + { + if (data.options[i]) + { + data.options[i][0] = weighted_voting ? 1 : 0; + const wrapper = data.options[i][1]; + (wrapper.children[0] as HTMLDivElement).style.transform = 'scaleX(0.0)'; + (wrapper as HTMLDivElement).style.opacity = '1.0'; + (wrapper.children[1].children[1] as HTMLDivElement).innerText = effects[i]; + (wrapper.children[1].children[2] as HTMLDivElement).innerText = start_value; + } + } + + data.votes = 0; } -function updateVotes(votes: Array) +function updateVotes(votes: Array, weighted_voting: boolean) { - data.votes = votes.reduce((prev, now) => { return now+prev; }); - - const votesElem = document.getElementById('votes'); - - if (votesElem) - { - votesElem.innerText = `Votes: ${data.votes}`; - } - - for (let i = 0; i < votes.length; i++) - { - const option = data.options[i]; - option[0] = votes[i]; - - let percent = 0; - - if (votes[i]) - { - percent = votes[i] / data.votes; - - if (percent > 1) - { - percent = 1; - } - } - - (option[1].children[0] as HTMLDivElement).style.transform = `scaleX(${percent})`; - - (option[1].children[1].children[2] as HTMLDivElement).innerText = `${votes[i]}`; - } + data.votes = votes.reduce((prev, now) => + { + return now + prev; + }); + + const votesElem = document.getElementById('votes'); + + if (votesElem) + { + votesElem.innerText = `Votes: ${data.votes}`; + } + + for (let i = 0; i < votes.length; i++) + { + const option = data.options[i]; + option[0] = votes[i]; + + + let percent = 0; + let value = ""; + + if (votes[i]) + { + percent = votes[i] / data.votes; + + if (percent > 1) + { + percent = 1; + } + + if (!weighted_voting) + { + value = votes[i].toString(); + } + else + { + value = Math.round(percent * 100) + "%"; + } + } + + (option[1].children[0] as HTMLDivElement).style.transform = `scaleX(${percent})`; + (option[1].children[1].children[2] as HTMLDivElement).innerText = `${value}`; + } } function updateWinner(winnerID: number): void { - for (let i = 0; i < data.options.length; i++) - { - const option = data.options[i]; - - let opacity = 1; - - if (winnerID != i) - { - opacity = 0.5; - } - - (option[1] as HTMLDivElement).style.opacity = `${opacity}`; - } + for (let i = 0; i < data.options.length; i++) + { + const option = data.options[i]; + + let opacity = 1; + + if (winnerID != i) + { + opacity = 0.5; + } + + (option[1] as HTMLDivElement).style.opacity = `${opacity}`; + } } function pollStarted() { - const wrapper = document.getElementById('wrapper'); - - if (wrapper) - { - wrapper.animate( - [ - { - opacity: 0 - }, - { - opacity: 1 - } - ], - { - duration: 1000, - easing: 'linear', - iterations: 1 - } - ); - } + const wrapper = document.getElementById('wrapper'); + + if (wrapper) + { + wrapper.animate( + [ + { + opacity: 0 + }, + { + opacity: 1 + } + ], + { + duration: 1000, + easing: 'linear', + iterations: 1 + } + ); + } } let fadeOutTimeout: NodeJS.Timer | null = null; @@ -165,131 +179,132 @@ let fadeOutTimeout: NodeJS.Timer | null = null; function setPollVisible(bVisible: boolean): void { - const wrapper = document.getElementById('wrapper'); - - if (fadeOutTimeout) - { - clearTimeout(fadeOutTimeout); - fadeOutTimeout = null; - } - - if (wrapper) - { - wrapper.style.opacity = bVisible ? '1' : '0'; - } + const wrapper = document.getElementById('wrapper'); + + if (fadeOutTimeout) + { + clearTimeout(fadeOutTimeout); + fadeOutTimeout = null; + } + + if (wrapper) + { + wrapper.style.opacity = bVisible ? '1' : '0'; + } } function setPollFadeOut() { - if (fadeOutTimeout) - { - clearTimeout(fadeOutTimeout); - fadeOutTimeout = null; - } - - fadeOutTimeout = setTimeout(() => - { - const wrapper = document.getElementById('wrapper'); - - if (wrapper) - { - wrapper.style.opacity = '0'; - } - }, 10000); + if (fadeOutTimeout) + { + clearTimeout(fadeOutTimeout); + fadeOutTimeout = null; + } + + fadeOutTimeout = setTimeout(() => + { + const wrapper = document.getElementById('wrapper'); + + if (wrapper) + { + wrapper.style.opacity = '0'; + } + }, 10000); } -/** +/** * @param bMoreOptions If true, options = 1-4, else options = 5-8 */ function setPollHasMoreOptions(bMoreOptions: boolean): void { - for (let i = 0; i < data.options.length; i++) - { - if (data.options[i] && data.options[i][1]) - { - const wrapper = data.options[i][1]; - const optionNum = bMoreOptions ? i + 5 : i + 1; - (wrapper.children[1].children[0] as HTMLDivElement).innerText = `${optionNum}`; - } - } - - data.votes = 0; + for (let i = 0; i < data.options.length; i++) + { + if (data.options[i] && data.options[i][1]) + { + const wrapper = data.options[i][1]; + const optionNum = bMoreOptions ? i + 5 : i + 1; + (wrapper.children[1].children[0] as HTMLDivElement).innerText = `${optionNum}`; + } + } + + data.votes = 0; } let connectionInterval: NodeJS.Timer | null = null; function connectWS() { - const ws = new WebSocket(`ws://${window && window.location && window.location.host ? window.location.hostname : `127.0.0.1`}:9147`); - - ws.onclose = (ev) => - { - console.log(ev); - - if (connectionInterval) - { - clearInterval(connectionInterval); - connectionInterval = null; - } - - connectionInterval = setInterval(connectWS, 2000); - } - - ws.onerror = (ev) => - { - console.log(ev); - } - - ws.onmessage = (ev) => - { - try - { - const msg = JSON.parse(ev.data); - - console.log(msg); - if (msg && msg.type) - { - switch (msg.type) { - case "new-options": - updateEffects(msg.data); - break; - case "update-votes": - updateVotes(msg.data); - break; - case "set-winner": - updateWinner(msg.data); - break; - case "poll-started": - pollStarted(); - break; - case "set-poll-visible": - setPollVisible(msg.data); - break; - case 'set-poll-fade-out': - setPollFadeOut(); - break; - case 'set-poll-options-number': - setPollHasMoreOptions(msg.data); - break; - } - } - - } - catch (err) - { - console.error(err); - } - } - - ws.onopen = (ev) => - { - if (connectionInterval) - { - clearInterval(connectionInterval); - connectionInterval = null; - } - } + const ws = new WebSocket(`ws://${window && window.location && window.location.host ? window.location.hostname : `127.0.0.1`}:9147`); + + ws.onclose = (ev) => + { + console.log(ev); + + if (connectionInterval) + { + clearInterval(connectionInterval); + connectionInterval = null; + } + + connectionInterval = setInterval(connectWS, 2000); + } + + ws.onerror = (ev) => + { + console.log(ev); + } + + ws.onmessage = (ev) => + { + try + { + const msg = JSON.parse(ev.data); + + console.log(msg); + if (msg && msg.type) + { + switch (msg.type) + { + case "new-options": + updateEffects(msg.data, msg.weighted_voting); + break; + case "update-votes": + updateVotes(msg.data, msg.weighted_voting); + break; + case "set-winner": + updateWinner(msg.data); + break; + case "poll-started": + pollStarted(); + break; + case "set-poll-visible": + setPollVisible(msg.data); + break; + case 'set-poll-fade-out': + setPollFadeOut(); + break; + case 'set-poll-options-number': + setPollHasMoreOptions(msg.data); + break; + } + } + + } + catch (err) + { + console.error(err); + } + } + + ws.onopen = (ev) => + { + if (connectionInterval) + { + clearInterval(connectionInterval); + connectionInterval = null; + } + } } connectWS(); \ No newline at end of file diff --git a/src/Twitch/src/front/style.css b/src/Twitch/src/front/style.css index 9ebdceb..317996b 100644 --- a/src/Twitch/src/front/style.css +++ b/src/Twitch/src/front/style.css @@ -1,5 +1,4 @@ -body, html, #wrapper -{ +body, html, #wrapper { margin: 0; padding: 0; background: transparent; @@ -7,13 +6,11 @@ body, html, #wrapper user-select: none; } -#wrapper -{ +#wrapper { transition: opacity 500ms ease; } -#votes -{ +#votes { font-size: 24px; color: white; text-shadow: -2px -2px 0 #000, 0 -2px 0 #000, 2px -2px 0 #000, 2px 0 0 #000, 2px 2px 0 #000, 0 2px 0 #000, -2px 2px 0 #000, -2px 0 0 #000; @@ -22,8 +19,7 @@ body, html, #wrapper margin-bottom: 16px; } -.vote-option -{ +.vote-option { --width: 400px; --height: 35px; @@ -39,12 +35,11 @@ body, html, #wrapper position: relative; - margin-bottom: 10px; + margin-bottom: 2px; transition: opacity 300ms linear; } -.vote-option-progress-bar -{ +.vote-option-progress-bar { position: absolute; width: 100%; height: 100%; @@ -57,25 +52,23 @@ body, html, #wrapper transition: transform 300ms linear; } -.vote-option-wrapper -{ +.vote-option-wrapper { width: 100%; height: 100%; - + text-shadow: 2px 2px 6px #000000; display: flex; flex-direction: row; align-items: center; justify-content: space-between; color: white; - font-weight: bold; - font-size: 16px; + font-weight: bold; + font-size: 20px; position: absolute; z-index: 2; } -.vote-option-name -{ - font-size: 15px; +.vote-option-name { + font-size: 25px; left: 0; right: 0; text-align: center; @@ -89,8 +82,7 @@ body, html, #wrapper white-space: nowrap; } -.vote-count -{ +.vote-count { position: absolute; right: 9px; margin: auto; @@ -100,8 +92,7 @@ body, html, #wrapper height: fit-content; } -.vote-index -{ +.vote-index { position: absolute; left: 9px; margin: auto; diff --git a/src/Twitch/src/front/token.html b/src/Twitch/src/front/token.html index bdf7524..f2b2242 100644 --- a/src/Twitch/src/front/token.html +++ b/src/Twitch/src/front/token.html @@ -1,23 +1,22 @@ - - - - ChaosModRDR + + + + ChaosModRDR - OK - +OK + \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8090df6..4eb3268 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,26 +6,26 @@ BOOL APIENTRY DllMain(HMODULE hInstance, DWORD reason, LPVOID lpReserved) { switch (reason) { - case DLL_PROCESS_ATTACH: - ChaosMod::hInstance = hInstance; - scriptRegister(hInstance, ChaosMod::ScriptMain); - keyboardHandlerRegister(ChaosMod::OnKeyboardMessage); - break; - case DLL_PROCESS_DETACH: - - if (ChaosMod::Singleton) - { - if (ChaosMod::Singleton->wsServer) + case DLL_PROCESS_ATTACH: + ChaosMod::hInstance = hInstance; + scriptRegister(hInstance, ChaosMod::ScriptMain); + keyboardHandlerRegister(ChaosMod::OnKeyboardMessage); + break; + case DLL_PROCESS_DETACH: + + if (ChaosMod::Singleton) { - ChaosMod::Singleton->wsServer->Stop(); + if (ChaosMod::Singleton->wsServer) + { + ChaosMod::Singleton->wsServer->Stop(); + } } - } - - ChaosMod::TerminateNodeProcess(); - - scriptUnregister(hInstance); - keyboardHandlerUnregister(ChaosMod::OnKeyboardMessage); - break; + + ChaosMod::TerminateNodeProcess(); + + scriptUnregister(hInstance); + keyboardHandlerUnregister(ChaosMod::OnKeyboardMessage); + break; } return TRUE; } diff --git a/src/script.cpp b/src/script.cpp index dffbf17..1cbb13c 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -14,9 +14,9 @@ uint64_t ChaosMod::ThreadID = 0; Ped ChaosMod::PLAYER_PED = 0; HMODULE ChaosMod::hInstance = 0; -std::set ChaosMod::pedsSet = std::set(); -std::set ChaosMod::vehsSet = std::set(); -std::set ChaosMod::propsSet = std::set(); +std::set ChaosMod::pedsSet = std::set(); +std::set ChaosMod::vehsSet = std::set(); +std::set ChaosMod::propsSet = std::set(); Hash ChaosMod::PlayerSkin1 = 0; Hash ChaosMod::PlayerSkin2 = 0; @@ -36,7 +36,7 @@ ChaosMod::~ChaosMod() { delete notificationData; } - + if (notificationDuration) { delete notificationDuration; @@ -46,10 +46,10 @@ ChaosMod::~ChaosMod() void ChaosMod::ScriptMain() { srand(GetTickCount()); - + /** Create mod instance and activate it */ ChaosMod::Singleton = new ChaosMod(); - + ChaosMod::Get()->Main(); } @@ -63,29 +63,32 @@ bool ChaosMod::IsModEnabled() return bEnabled; } -void ChaosMod::DrawText(char* text, Vector2 position, Vector2 scale, LinearColor color, bool bCenter, int shadowSize, LinearColor shadowColor) +void ChaosMod::DrawText(char* text, Vector2 position, Vector2 scale, LinearColor color, bool bCenter, int shadowSize, + LinearColor shadowColor) { UI::SET_TEXT_SCALE(scale.X, scale.Y); UI::SET_TEXT_COLOR_RGBA(color.R, color.G, color.B, color.A); UI::SET_TEXT_CENTRE(bCenter); UI::SET_TEXT_DROPSHADOW(shadowSize, shadowColor.R, shadowColor.G, shadowColor.B, shadowColor.A);; - - char* varString = GAMEPLAY::CREATE_STRING(10, (char*)"LITERAL_STRING", text); - + + char* varString = GAMEPLAY::CREATE_STRING(10, (char*) "LITERAL_STRING", text); + UI::DRAW_TEXT(varString, 0.5f, 0.5f); } -void ChaosMod::OnKeyboardMessage(DWORD key, WORD repeats, BYTE scanCode, BOOL isExtended, BOOL isWithAlt, BOOL wasDownBefore, BOOL isUpNow) +void +ChaosMod::OnKeyboardMessage(DWORD key, WORD repeats, BYTE scanCode, BOOL isExtended, BOOL isWithAlt, BOOL wasDownBefore, + BOOL isUpNow) { if (key < 0xFF) { auto* modInstance = ChaosMod::Get(); - + if (!modInstance) { return; } - + modInstance->keyStates[key].time = GetTickCount(); modInstance->keyStates[key].bPressed = isUpNow; } @@ -95,20 +98,20 @@ void ChaosMod::OnKeyboardMessage(DWORD key, WORD repeats, BYTE scanCode, BOOL is void ChaosMod::ToggleModStatus() { ChaosMod::globalMutex.lock(); - + bEnabled = !bEnabled; - - + + if (bEnabled) { bool bPrevTwitchStatus = config.bTwitch; - + config.Read(); - + ResetEffectsTimeout(); - + ResetMetaTimer(); - + if (bPrevTwitchStatus != config.bTwitch) { if (config.bTwitch) @@ -127,10 +130,11 @@ void ChaosMod::ToggleModStatus() wsServer->SendMessageToClient("mod_enabled"); } } - + std::string effectsNumStr = "~q~Loaded ~COLOR_GOLD~" + std::to_string(AllEffects.size()) + "~q~ effects"; - - ShowNotification2("~COLOR_GREEN~Chaos Mod Enabled", effectsNumStr.c_str(), 3500, "scoretimer_textures", "scoretimer_generic_tick", LinearColor(77, 170, 104, 255)); + + ShowNotification2("~COLOR_GREEN~Chaos Mod Enabled", effectsNumStr.c_str(), 3500, "scoretimer_textures", + "scoretimer_generic_tick", LinearColor(77, 170, 104, 255)); } else { @@ -138,16 +142,18 @@ void ChaosMod::ToggleModStatus() { effect->OnDeactivate(); } - + activeEffects = {}; - + subEffects = {}; + if (config.bTwitch && wsServer) { wsServer->SendMessageToClient("mod_disabled"); } - - ShowNotification2("~COLOR_PLAYER_STATUS_NEGATIVE~Chaos Mod Disabled", "", 3500, "scoretimer_textures", "scoretimer_generic_cross", LinearColor(204, 0, 0, 255)); - + + ShowNotification2("~COLOR_PLAYER_STATUS_NEGATIVE~Chaos Mod Disabled", "", 3500, "scoretimer_textures", + "scoretimer_generic_cross", LinearColor(204, 0, 0, 255)); + for (auto ped : ChaosMod::pedsSet) { if (ENTITY::DOES_ENTITY_EXIST(ped)) @@ -156,7 +162,7 @@ void ChaosMod::ToggleModStatus() PED::DELETE_PED(&ped); } } - + for (auto veh : ChaosMod::vehsSet) { if (ENTITY::DOES_ENTITY_EXIST(veh)) @@ -165,7 +171,7 @@ void ChaosMod::ToggleModStatus() VEHICLE::DELETE_VEHICLE(&veh); } } - + for (auto prop : ChaosMod::propsSet) { if (ENTITY::DOES_ENTITY_EXIST(prop)) @@ -174,40 +180,77 @@ void ChaosMod::ToggleModStatus() OBJECT::DELETE_OBJECT(&prop); } } - + ChaosMod::ResetPlayerSkin(); } - - AUDIO::PLAY_SOUND_FRONTEND((char*)"SELECT", (char*)"HUD_SHOP_SOUNDSET", true, 0); + + AUDIO::PLAY_SOUND_FRONTEND((char*) "SELECT", (char*) "HUD_SHOP_SOUNDSET", true, 0); ChaosMod::pedsSet.clear(); ChaosMod::vehsSet.clear(); ChaosMod::propsSet.clear(); - + oldEffects.clear(); - + activeMeta = nullptr; - + ChaosMod::globalMutex.unlock(); } +void ChaosMod::ActivateSubEffect(int num_subs) +{ + if (config.bSubs) + { + ChaosMod::LogToFile(("Activating " + std::to_string(num_subs) + " sub effects").c_str()); + bool double_subs_active = IsEffectActive("double_subs"); + ChaosMod::LogToFile(("Double subs active: " + std::to_string(double_subs_active)).c_str()); + int multiplier = double_subs_active ? 2 : 1; + int num_effects = (config.bSingleShotSub ? 1 : num_subs) * multiplier; + ChaosMod::LogToFile(("Generating " + std::to_string(num_effects) + " random effects").c_str()); + auto effects = GenerateEffectsWithChances(num_effects); + + ChaosMod::globalMutex.lock(); + + for (auto* effect : effects) + { + subEffects.push_back(effect); + } + + ChaosMod::globalMutex.unlock(); + } +} + +bool ChaosMod::IsEffectActive(std::string effect_id) +{ + for (auto check_effect : activeEffects) + { + if (check_effect->ID == effect_id) + { + return true; + } + } + return false; +} + void ChaosMod::ActivateEffect(Effect* effect) { if (!effect) { return; } - + if (effect->bTimed) { effect->ActivationTime = GetTickCount(); effect->DeactivationTime = effect->ActivationTime + (effect->EffectDuration * 1000); } - + + effect->DisplayTime = effect->ActivationTime + (config.effectDisplayTime * 1000); + prevActivatedEffect = effect; - + effect->OnActivate(); - + if (effect->bIsMeta) { this->activeEffects.insert(activeEffects.begin(), effect); @@ -221,29 +264,30 @@ void ChaosMod::ActivateEffect(Effect* effect) void ChaosMod::StartNodeProcess() { LogToFile("Starting node process.."); - + ZeroMemory(&this->NodeStartupInfo, sizeof(this->NodeStartupInfo)); NodeStartupInfo.cb = sizeof(this->NodeStartupInfo); ZeroMemory(&this->NodeProcessInformation, sizeof(this->NodeProcessInformation)); - + WCHAR gameDir[MAX_PATH]; GetCurrentDirectoryW(MAX_PATH, gameDir); - + std::wstring chaosDir = gameDir; - + chaosDir += L"\\ChaosMod"; - + std::wstring exePath = chaosDir; - + exePath += L"\\ChaosModRDRTwitch.exe"; - + LPWSTR exePath_c = const_cast(exePath.c_str()); LPWSTR chaosDir_c = const_cast(chaosDir.c_str()); - - auto processCreationResult = CreateProcessW(NULL, exePath_c, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, chaosDir_c, &NodeStartupInfo, &NodeProcessInformation); - + + auto processCreationResult = CreateProcessW(NULL, exePath_c, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, chaosDir_c, + &NodeStartupInfo, &NodeProcessInformation); + std::string logStr = "Node process started: " + std::to_string(processCreationResult); - + LogToFile(logStr.c_str()); } @@ -251,9 +295,9 @@ void ChaosMod::TerminateNodeProcess() { PROCESSENTRY32W processEntry; processEntry.dwSize = sizeof(PROCESSENTRY32W); - + HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); - + if (Process32FirstW(snapshot, &processEntry) == TRUE) { while (Process32NextW(snapshot, &processEntry) == TRUE) @@ -261,45 +305,45 @@ void ChaosMod::TerminateNodeProcess() if (_wcsicmp(processEntry.szExeFile, L"ChaosModRDRTwitch.exe") == 0) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processEntry.th32ProcessID); - + TerminateProcess(hProcess, 0); - + CloseHandle(hProcess); } } } - + CloseHandle(snapshot); } void ChaosMod::StopServer() { auto* mod = ChaosMod::Get(); - + if (mod) { ChaosMod::LogToFile("Stopping WebSockets server (F11)"); - + ChaosMod::globalMutex.lock(); - + if (mod->wsServer) { MessageBeep(MB_OK); mod->wsServer->Stop(); delete mod->wsServer; mod->wsServer = nullptr; - + } - + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, mod->NodeProcessInformation.dwProcessId); - + if (hProcess != NULL) { TerminateProcess(hProcess, 0); - + CloseHandle(hProcess); } - + ChaosMod::globalMutex.unlock(); } } @@ -309,36 +353,36 @@ void ChaosMod::Main() InitWeaponHashes(); InitWeatherHashes(); InitEffects(); - + ChaosMod::globalMutex.lock(); - + ChaosMod::LastTick = GetTickCount(); - + ChaosMod::globalMutex.unlock(); - + ChaosMod::ThreadID = GetCurrentThreadId(); - + ChaosMod::Singleton->SavePlayerAttributes(); ChaosMod::UpdatePlayerSkinHash(); - + config.Read(); - + std::string logStr = "Chaos Mod Loaded. Twitch: " + std::to_string(config.bTwitch); - + LogToFile(logStr.c_str()); - + if (config.bTwitch) { StartWSServer(); } - + while (true) { Update(); InputTick(); WAIT(0); } - + } void ChaosMod::Update() @@ -347,28 +391,28 @@ void ChaosMod::Update() { RenderNotification2(); } - + ChaosMod::globalMutex.lock(); - + uint32_t thisTick = GetTickCount(); - + ChaosMod::_DeltaTime = thisTick - ChaosMod::LastTick; ChaosMod::_DeltaTimeSeconds = float(float(ChaosMod::_DeltaTime) / 1000.0f); - + ChaosMod::LastTick = thisTick; ChaosMod::PLAYER_PED = PLAYER::PLAYER_PED_ID(); - + ChaosMod::globalMutex.unlock(); - + if (!bEnabled) { return; } - + for (int32_t i = 0; i < activeEffects.size(); i++) { auto* effect = activeEffects[i]; - + if (effect && effect->bTimed) { if (GetTickCount() >= effect->DeactivationTime) @@ -376,7 +420,7 @@ void ChaosMod::Update() effect->OnDeactivate(); activeEffects.erase(activeEffects.begin() + i); i--; - + if (effect->bIsMeta) { ResetMetaTimer(); @@ -388,41 +432,41 @@ void ChaosMod::Update() } } } - + if (timeoutVotingStartTime && !bVotingEnabled && GetTickCount() >= timeoutVotingStartTime) { if (config.bTwitch && wsServer) { ChaosMod::globalMutex.lock(); - + if (oldEffects.size() >= 12) { oldEffects.erase(oldEffects.begin(), oldEffects.begin() + 4); } - + pollEffects = GenerateEffectsWithChances(4); - - std::vector effectNames; - + + std::vector effectNames; + for (auto effect : pollEffects) { effectNames.push_back(effect->name); oldEffects.push_back(effect); } - + effectNames[effectNames.size() - 1] = "Random Effect"; - + wsServer->SendEffectNamesToClient(effectNames); - + ChaosMod::globalMutex.unlock(); } - + bVotingEnabled = true; - + for (int32_t i = 0; i < activeEffects.size(); i++) { auto* effect = activeEffects[i]; - + if (effect && !effect->bTimed) { effect->OnDeactivate(); @@ -431,19 +475,19 @@ void ChaosMod::Update() } } } - + if (timeoutEndTime && GetTickCount() >= timeoutEndTime) { ResetEffectsTimeout(); - + if (bEffectsActivatesAfterTimer) { if (config.bTwitch && wsServer) { ChaosMod::globalMutex.lock(); - + wsServer->SendMessageToClient("vote_ended"); - + ChaosMod::globalMutex.unlock(); } else @@ -453,13 +497,13 @@ void ChaosMod::Update() { maxEffects = 3; } - + auto effects = GenerateEffectsWithChances(maxEffects); for (auto* effect : effects) { ActivateEffect(effect); } - + if (effects[0]) { prevActivatedEffect = effects[0]; @@ -467,13 +511,13 @@ void ChaosMod::Update() } } } - + if (MetaActivationTime != 0 && GetTickCount() >= MetaActivationTime) { MetaActivationTime = 0; - - std::vector enabledMetaEffects; - + + std::vector < MetaEffect * > enabledMetaEffects; + for (auto* effect : AllMetaEffects) { if (effect->bEnabled) @@ -481,25 +525,25 @@ void ChaosMod::Update() enabledMetaEffects.push_back(effect); } } - + if (enabledMetaEffects.size() != 0) { MetaEffect* effect = enabledMetaEffects[rand() % enabledMetaEffects.size()]; - + ActivateEffect(effect); activeMeta = effect; - + if (effect->ID == "total_chaos" && !bVotingEnabled) { ResetEffectsTimeout(); } } } - + std::string twitchViewerName = ""; - + ChaosMod::globalMutex.lock(); - + if (twitchWinnerID != -1) { if (twitchWinnerID < pollEffects.size()) @@ -507,9 +551,9 @@ void ChaosMod::Update() auto* effect = pollEffects[twitchWinnerID]; ActivateEffect(effect); prevActivatedEffect = effect; - + pollEffects.clear(); - + if (activeMeta && activeMeta->ID == "combo_time") { auto comboEffects = GenerateEffectsWithChances(2); @@ -519,31 +563,44 @@ void ChaosMod::Update() } } } - + twitchWinnerID = -1; } - - + + if (!twitchViewerNameToSpawn.empty()) { twitchViewerName = twitchViewerNameToSpawn; twitchViewerNameToSpawn = ""; } - + ChaosMod::globalMutex.unlock(); - + if (!twitchViewerName.empty()) { for (auto effect : activeEffects) { if (effect->ID == "spawn_twitch_viewer") { - ((EffectSpawnTwitchViewer*)effect)->Spawn(twitchViewerName); + ((EffectSpawnTwitchViewer*) effect)->Spawn(twitchViewerName); break; } } } - + + if (subEffects.size() > 0) + { + for (auto* effect : subEffects) + { + if (effect) + { + ChaosMod::LogToFile(("Activating sub effect: " + effect->ID).c_str()); + ActivateEffect(effect); + } + } + subEffects.clear(); + } + DrawUI(); } @@ -553,39 +610,39 @@ void ChaosMod::InputTick() { ToggleModStatus(); } - + if (IsModEnabled()) { if (isKeyPressed(config.controls.toggleEffects)) { ToggleDefaultEffectActivation(); } - + if (isKeyPressed(config.controls.testEffect)) { ToggleEffectSelection(); } - + if (isKeyPressed(VK_LEFT)) { ChangeSelectedEffect(-1); - + if (modMenu.IsVisible()) { modMenu.OnKeyPressed(VK_LEFT); } } - + if (isKeyPressed(VK_RIGHT)) { ChangeSelectedEffect(1); - + if (modMenu.IsVisible()) { modMenu.OnKeyPressed(VK_RIGHT); } } - + if (isKeyPressed(VK_DOWN)) { if (modMenu.IsVisible()) @@ -593,7 +650,7 @@ void ChaosMod::InputTick() modMenu.OnKeyPressed(VK_DOWN); } } - + if (isKeyPressed(VK_UP)) { if (modMenu.IsVisible()) @@ -601,7 +658,7 @@ void ChaosMod::InputTick() modMenu.OnKeyPressed(VK_UP); } } - + if (isKeyPressed(VK_RETURN)) { ActivateSelectedEffect(); @@ -611,16 +668,16 @@ void ChaosMod::InputTick() modMenu.OnKeyPressed(VK_RETURN); } } - + //if (isKeyPressed(VK_F12)) //{ - //modMenu.ToggleVisibility(); + //modMenu.ToggleVisibility(); //} - + if (isKeyPressed(config.controls.instaKill)) { Ped playerPed = PLAYER::PLAYER_PED_ID(); - + if (ENTITY::DOES_ENTITY_EXIST(playerPed)) { ENTITY::SET_ENTITY_INVINCIBLE(playerPed, false); @@ -628,7 +685,7 @@ void ChaosMod::InputTick() } } } - + /** * For unknown reason, in debug mode mod breaks when trying to disable it with Ctrl+R if websocketpp loop is active * So you need to press F11 first to stop the websocket server and terminate its thread @@ -643,56 +700,78 @@ void ChaosMod::DrawUI() { /** 18px on 1080p */ static const float ProgressBarHeight = 18.0f / 1080.f; - + /** Draw progress bar background */ GRAPHICS::DRAW_RECT(0.5f, ProgressBarHeight / 2.0f, 1.0f, ProgressBarHeight, 0, 0, 0, 168, 0, 0); - - float effectTimeoutValue = float(float(GetTickCount() - timeoutStartTime) / float(timeoutEndTime - timeoutStartTime)); - - if (effectTimeoutValue < 0.0f) effectTimeoutValue = 0.0f; - else if (effectTimeoutValue > 1.0f) effectTimeoutValue = 1.0f; - + + float effectTimeoutValue = float( + float(GetTickCount() - timeoutStartTime) / float(timeoutEndTime - timeoutStartTime)); + + if (effectTimeoutValue < 0.0f) + { + effectTimeoutValue = 0.0f; + } + else if (effectTimeoutValue > 1.0f) + { + effectTimeoutValue = 1.0f; + } + LinearColor color(143, 6, 6, 255); - + if (activeMeta && activeMeta->ID == "total_chaos") { LinearColor startColor(143, 6, 6, 240); LinearColor endColor(249, 200, 4, 240); - + float alpha = ((sin(metaEffectColorSinX) + 1.0f) / 2.0f); - + color.R = Lerp(startColor.R, endColor.R, alpha); color.G = Lerp(startColor.G, endColor.G, alpha); color.B = Lerp(startColor.B, endColor.B, alpha); } - + /** Draw progress bar foreground */ - GRAPHICS::DRAW_RECT(effectTimeoutValue / 2.0f, ProgressBarHeight / 2.0f, effectTimeoutValue, ProgressBarHeight, color.R, color.G, color.B, color.A, 0, 0); - - for (int32_t i = 0; i < activeEffects.size(); i++) + GRAPHICS::DRAW_RECT(effectTimeoutValue / 2.0f, ProgressBarHeight / 2.0f, effectTimeoutValue, ProgressBarHeight, + color.R, color.G, color.B, color.A, 0, 0); + + + for (int32_t i = 0; i < displayedEffects.size(); i++) { - DrawEffectInUI(activeEffects[i], i); + auto* effect = displayedEffects[i]; + if (effect) + { + if (GetTickCount() >= max(effect->DisplayTime, effect->DeactivationTime)) + { + displayedEffects.erase(displayedEffects.begin() + i); + i--; + } + else + { + DrawEffectInUI(activeEffects[i], i); + } + } } - + if (bEffectSelectionVisible) { auto* Effect = AllEffects[debugSelectedEffectIndex]; - + std::string debugText = ""; - debugText += "[DEBUG] Effect to activate: \n[" + std::to_string(debugSelectedEffectIndex+1) + "] " + Effect->name; + debugText += + "[DEBUG] Effect to activate: \n[" + std::to_string(debugSelectedEffectIndex + 1) + "] " + Effect->name; debugText += ""; - + UI::SET_TEXT_SCALE(0.0f, 0.5f); UI::SET_TEXT_COLOR_RGBA(255, 255, 255, 240); UI::SET_TEXT_CENTRE(1); UI::SET_TEXT_DROPSHADOW(1, 0, 0, 0, 255); - - char* varString = GAMEPLAY::CREATE_STRING(10, (char*)"LITERAL_STRING", (char*)debugText.c_str()); - varString = invoke(0xFA925AC00EB830B9, 42, (char*)"COLOR_STRING", 0, varString); - + + char* varString = GAMEPLAY::CREATE_STRING(10, (char*) "LITERAL_STRING", (char*) debugText.c_str()); + varString = invoke(0xFA925AC00EB830B9, 42, (char*) "COLOR_STRING", 0, varString); + UI::DRAW_TEXT(varString, 0.5f, 0.5f); } - + if (modMenu.IsVisible()) { modMenu.Draw(); @@ -702,7 +781,7 @@ void ChaosMod::DrawUI() bool ChaosMod::isKeyPressed(uint8_t key) { bool bPressed = keyStates[key].bPressed && GetTickCount() < keyStates[key].time + 100; - + if (bPressed) { keyStates[key].bPressed = false; @@ -715,22 +794,22 @@ bool ChaosMod::isKeyPressed(uint8_t key) void ChaosMod::ResetEffectsTimeout() { bVotingEnabled = false; - + timeoutStartTime = GetTickCount(); - + int _effectsInterval = effectsInterval; - + bool bTotalChaos = activeMeta && activeMeta->ID == "total_chaos"; - + if (bTotalChaos) { _effectsInterval = 15; } - + timeoutEndTime = timeoutStartTime + (_effectsInterval * 1000); - + int _effectsVoteTime = 0; - + if (config.bTwitch) { _effectsVoteTime = effectsVoteTime; @@ -739,12 +818,12 @@ void ChaosMod::ResetEffectsTimeout() { _effectsVoteTime = _effectsInterval / 2; } - + if (bTotalChaos) { _effectsVoteTime = _effectsInterval - 2; } - + timeoutVotingStartTime = timeoutEndTime - (_effectsVoteTime * 1000); } @@ -754,32 +833,34 @@ void ChaosMod::DrawEffectInUI(Effect* effect, int32_t index) { return; } - + float X = 1690.0f / 1920.0f; float minY = 378.0f; float margin = 52.0f; float Y = (minY + (index * margin)) / 1080.0f; - + if (effect->bTimed && !effect->bIsFake) { - float progressBarValue = 1.0f - (((float)GetTickCount() - (float)effect->ActivationTime) / ((float)effect->DeactivationTime - (float)effect->ActivationTime)); + float progressBarValue = 1.0f - (((float) GetTickCount() - (float) effect->ActivationTime) / + ((float) effect->DeactivationTime - (float) effect->ActivationTime)); float progressBarWidth = (400.0f / 1920.0f); float progressBarX = X - (((1.0f - (progressBarValue)) / 2.0f) * progressBarWidth); - GRAPHICS::DRAW_RECT(progressBarX, Y, (progressBarWidth) * progressBarValue, 40.0f / 1080.0f, 0, 0, 0, 185, 0, 0); + GRAPHICS::DRAW_RECT(progressBarX, Y, (progressBarWidth) * progressBarValue, 40.0f / 1080.0f, 0, 0, 0, 185, 0, + 0); } - + UI::SET_TEXT_SCALE(0.0f, 0.35f); - + if (effect->bIsMeta) { LinearColor startColor(239, 86, 86, 240); - + LinearColor endColor(249, 200, 4, 240); - + metaEffectColorSinX += ChaosMod::GetDeltaTimeSeconds() * 5.0f; - + float alpha = ((sin(metaEffectColorSinX) + 1.0f) / 2.0f); - + LinearColor color; color.R = Lerp(startColor.R, endColor.R, alpha); @@ -792,10 +873,10 @@ void ChaosMod::DrawEffectInUI(Effect* effect, int32_t index) { UI::SET_TEXT_COLOR_RGBA(255, 255, 255, 240); } - + UI::SET_TEXT_CENTRE(1); UI::SET_TEXT_DROPSHADOW(1, 0, 0, 0, 255); - + std::string effectName = ""; if (effect->bIsMeta) @@ -804,218 +885,86 @@ void ChaosMod::DrawEffectInUI(Effect* effect, int32_t index) } effectName += effect->name + ""; - - char* varString = GAMEPLAY::CREATE_STRING(10, (char*)"LITERAL_STRING", (char*)effectName.c_str()); - - varString = invoke(0xFA925AC00EB830B9, 42, (char*)"COLOR_STRING", 0, varString); - + + char* varString = GAMEPLAY::CREATE_STRING(10, (char*) "LITERAL_STRING", (char*) effectName.c_str()); + + varString = invoke(0xFA925AC00EB830B9, 42, (char*) "COLOR_STRING", 0, varString); + UI::DRAW_TEXT(varString, X, Y - 0.0125f); } void ChaosMod::InitEffects() { - AllEffects = { - new EffectSpawnSoldier(), - new EffectSpawnLenny(), - new EffectSpawnDrunkardJon(), - new EffectSpawnChicken(), - new EffectLaunchPlayerUp(), - new EffectSpawnHotchkissCannon(), - new EffectKidnapping(), - new EffectSpawnHorse(), - new EffectTeleportEverything(), - new EffectSpawnWagon(), - new EffectSpawnMule(), - new EffectSpawnDonkey(), - new EffectSpawnSerialKiller(), - new EffectToTheStars(), - new EffectSnowstorm(), - new EffectThunderstorm(), - new EffectGivePlayerMoney(), - new EffectBankruptcy(), - new EffectSpawnVampire(), - new EffectGiveRifle(), - new EffectGiveRevolver(), - new EffectRemoveAllWeapons(), - new EffectNoAmmo(), - new EffectDropWeapon(), - new EffectHealPlayer(), - new EffectAlmostDead(), - new EffectRestoreStamina(), - new EffectFlipAllVehs(), - new EffectGiantPeds(), - new EffectAllPedsWannaKillPlayer(), - new EffectSpawnMiniDonkey(), - new EffectSpawnGiantDonkey(), - new EffectRagdoll(), - new EffectRagdollEveryone(), - new EffectSpawnGiantCop(), - new EffectLaunchPedsUp(), - new EffectInvertedGravity(), - new EffectDoomsday(), - new EffectGiveRandomWeapon(), - new EffectSetDrunk(), - new EffectSpawnAngryDwarf(), - new EffectSpawnAngrySkeleton(), - new EffectSpawnCompanionBertram(), - new EffectPlayIntro(), - new EffectSetRandomWeather(), - new EffectSetSunnyWeather(), - new EffectSetRainyWeather(), - new EffectSetRapidWeather(), - new EffectSetTimeMorning(), - new EffectSetTimeNight(), - new EffectSetRandomTime(), - new EffectClearPursuit(), - new EffectIncreaseBounty(), - new EffectSpawnFrozenCouple(), - new EffectEarthquake(), - new EffectRemoveCurrentVehicle(), - new EffectMinecartRain(), - new EffectGiveLasso(), - new EffectFullAcceleration(), - new EffectEveryoneIsInvincible(), - new EffectEveryoneExitsVehs(), - new EffectSetPlayerIntoRandomVeh(), - new Effect120FOV(), - new EffectSpawnRobot(), - new EffectSpawnHotAirBalloon(), - new EffectSpawnLassoGuy(), - new EffectIgnitePlayersWagon(), - new EffectIgniteNearbyWagons(), - new EffectIgnitePlayer(), - new EffectIgniteNearbyPeds(), - new EffectLightningOnce(), - new EffectKickflip(), - new EffectSpawnCanoe(), - new EffectHorsesRain(), - new EffectLightningEnemy(), - new EffectLightningWeapons(), - new EffectSkyrimIntro(), - new EffectCowSkin(), - new EffectDwarfSkin(), - new EffectPigSkin(), - new EffectRatSkin(), - new EffectTurtleSkin(), - new EffectSpawnParrotCompanion(), - new EffectHonorGood(), - new EffectHonorBad(), - new EffectHonorReset(), - new EffectSpawnShireHorse(), - new EffectAltTab(), - new EffectPlayerSleep(), - new EffectPlayerIsMinion(), - new EffectTeleportToWaypoint(), - new EffectRemoveWeaponFromEveryone(), - new EffectUndeadNightmare(), - new EffectBloodTrails(), - new EffectDetachWheels(), - new EffectExplosiveWeapons(), - new EffectSetFoggyWeather(), - new EffectGhostTown(), - new EffectSpawnDogCompanion(), - new EffectSpawnCatCompanion(), - new EffectSetPedsIntoPlayerVehicle(), - new EffectSetRandomWalkStyle(), - new EffectTeleportWeapons(), - new EffectGiveSniperRifle(), - new EffectGiveDynamite(), - new EffectThrowingKnives(), - new EffectSpawnBearCompanion(), - new EffectTeleportFewMeters(), - new EffectBlackingOut(), - new EffectRandomClothes(), - new EffectSpawnAngryCorpse(), - new EffectFastPlayersWagon(), - new EffectSpawnAngryCaveman(), - new EffectSpawnAngryTwin(), - new EffectMostWanted(), - new EffectSpawnUFO(), - new EffectGravityField(), - new EffectPigWeapons(), - new EffectSpawnAngryCowboy(), - new EffectSpawnUndeadBoss(), - new EffectSpawnGrieferMicah(), - new EffectSetWinterOutfit(), - new EffectGamespeedx02(), - new EffectGamespeedx05(), - new EffectSuperJump(), - new EffectDisableLeftRight(), - new EffectDisableForwardBackward(), - new EffectDisableAllMovements(), - new EffectDisableSprintJump(), - new EffectDisableAttackButton(), - new EffectDisableAiming(), - new EffectRandomWheelsDetaching(), - new EffectRainingPigs(), - new EffectRandomHonor(), - new EffectDutchStealsPlayersVeh(), - new EffectSpawnPredator(), - new EffectInvertVelocity(), - new EffectIncreaseVelocity(), - new EffectBunnyhop(), - new EffectEyeDisorder(), - new EffectPedsBhop(), - new EffectPedsSpin(), - new EffectBirdSkin(), - new EffectBodySwap(), - new EffectCloneEnemy(), - new EffectPedsFollowPlayer(), - new EffectPedsFleeing(), - new EffectPlayerSpin(), - new EffectRainbow(), - new EffectPlayerLosesWeight(), - new EffectPlayerGainsWeight(), - new EffectSetRandomHat(), - new EffectHealNearbyPeds(), - new EffectReviveDeadPeds(), - new EffectGravityGun(), - new EffectSpawnAngryTommy(), - new EffectDisableDeadEye(), - new EffectPartyTime(), - new EffectSetRandomVelocity(), - new EffectExplodeNearbyPeds(), - new EffectNearbyPedIsCompanion(), - new EffectEveryoneRagdollsWhenShot(), - new EffectNearbyPedIsEnemy(), - new EffectExplosiveCombat(), - new EffectGiveEveryoneRifle(), - new EffectTimelapse(), - new EffectNoHUD(), - new EffectFirstPerson(), - new EffectTopDownCamera(), - new EffectAgitateHorse(), - new EffectODriscolls(), - new EffectInsaneGravity(), - new EffectUpsideDownCamera(), - new EffectOneHitKO(), - new EffectBanditoKidnapsPlayer(), - new EffectTpRandomLocation(), - new EffectFakeTeleport(), - new EffectSpawnRandomVeh(), - new EffectHorsesAreDonkeys(), - new EffectSpawnTwitchViewer(), - new EffectEveryoneIsLenny(), - new EffectShadesOfGray(), - new EffectPotatoMode(), - new EffectSpawnExtremeEvilMicah(), - new EffectOilWagonsRain() - }; - + AllEffects = {new EffectSpawnSoldier(), new EffectSpawnLenny(), new EffectSpawnDrunkardJon(), + new EffectSpawnChicken(), new EffectSpawnWolfPack(), new EffectLaunchPlayerUp(), + new EffectSpawnHotchkissCannon(), new EffectKidnapping(), new EffectSpawnHorse(), + new EffectTeleportEverything(), new EffectSpawnWagon(), new EffectSpawnMule(), + new EffectSpawnDonkey(), new EffectSpawnSerialKiller(), new EffectToTheStars(), new EffectSnowstorm(), + new EffectThunderstorm(), new EffectGivePlayerMoney(), new EffectBankruptcy(), + new EffectSpawnVampire(), new EffectGiveRifle(), new EffectGiveRevolver(), + new EffectRemoveAllWeapons(), new EffectNoAmmo(), new EffectDropWeapon(), new EffectHealPlayer(), + new EffectAlmostDead(), new EffectRestoreStamina(), new EffectFlipAllVehs(), new EffectGiantPeds(), + new EffectAllPedsWannaKillPlayer(), new EffectSpawnMiniDonkey(), new EffectSpawnGiantDonkey(), + new EffectRagdoll(), new EffectRagdollEveryone(), new EffectSpawnGiantCop(), new EffectLaunchPedsUp(), + new EffectInvertedGravity(), new EffectDoomsday(), new EffectGiveRandomWeapon(), new EffectSetDrunk(), + new EffectSpawnAngryDwarf(), new EffectSpawnAngrySkeleton(), new EffectSpawnCompanionBertram(), + new EffectPlayIntro(), new EffectSetRandomWeather(), new EffectSetSunnyWeather(), + new EffectSetRainyWeather(), new EffectSetRapidWeather(), new EffectSetTimeMorning(), + new EffectSetTimeNight(), new EffectSetRandomTime(), new EffectClearPursuit(), + new EffectIncreaseBounty(), new EffectSpawnFrozenCouple(), new EffectEarthquake(), + new EffectRemoveCurrentVehicle(), new EffectTrainsawLaser(), new EffectMinecartRain(), + new EffectGiveLasso(), new EffectFullAcceleration(), new EffectEveryoneIsInvincible(), + new EffectEveryoneExitsVehs(), new EffectSetPlayerIntoRandomVeh(), new Effect120FOV(), + new EffectSpawnRobot(), new EffectSpawnHotAirBalloon(), new EffectSpawnLassoGuy(), + new EffectIgnitePlayersWagon(), new EffectIgniteNearbyWagons(), new EffectIgnitePlayer(), + new EffectIgniteNearbyPeds(), new EffectLightningOnce(), new EffectKickflip(), new EffectSpawnCanoe(), + new EffectHorsesRain(), new EffectLightningEnemy(), new EffectLightningWeapons(), + new EffectSkyrimIntro(), new EffectCowSkin(), new EffectDwarfSkin(), new EffectPigSkin(), + new EffectRatSkin(), new EffectTurtleSkin(), new EffectSpawnParrotCompanion(), new EffectHonorGood(), + new EffectHonorBad(), new EffectHonorReset(), new EffectSpawnShireHorse(), new EffectAltTab(), + new EffectPlayerSleep(), new EffectPlayerIsMinion(), new EffectTeleportToWaypoint(), + new EffectRemoveWeaponFromEveryone(), new EffectUndeadNightmare(), new EffectBloodTrails(), + new EffectDetachWheels(), new EffectExplosiveWeapons(), new EffectSetFoggyWeather(), + new EffectGhostTown(), new EffectSpawnDogCompanion(), new EffectSpawnCatCompanion(), + new EffectSetPedsIntoPlayerVehicle(), new EffectSetRandomWalkStyle(), new EffectTeleportWeapons(), + new EffectGiveSniperRifle(), new EffectGiveDynamite(), new EffectThrowingKnives(), + new EffectSpawnBearCompanion(), new EffectTeleportFewMeters(), new EffectBlackingOut(), + new EffectRandomClothes(), new EffectSpawnAngryCorpse(), new EffectFastPlayersWagon(), + new EffectSpawnAngryCaveman(), new EffectSpawnAngryTwin(), new EffectMostWanted(), + new EffectSpawnUFO(), new EffectGravityField(), new EffectPigWeapons(), new EffectSpawnAngryCowboy(), + new EffectSpawnUndeadBoss(), new EffectSpawnGrieferMicah(), new EffectSetWinterOutfit(), + new EffectGamespeedx02(), new EffectGamespeedx05(), new EffectSuperJump(), + new EffectDisableLeftRight(), new EffectDisableForwardBackward(), new EffectDisableAllMovements(), + new EffectDisableSprintJump(), new EffectDisableAttackButton(), new EffectDisableAiming(), + new EffectRandomWheelsDetaching(), new EffectRainingPigs(), new EffectRandomHonor(), + new EffectDutchStealsPlayersVeh(), new EffectSpawnPredator(), new EffectInvertVelocity(), + new EffectIncreaseVelocity(), new EffectBunnyhop(), new EffectEyeDisorder(), new EffectPedsBhop(), + new EffectPedsSpin(), new EffectBirdSkin(), new EffectBodySwap(), new EffectCloneEnemy(), + new EffectPedsFollowPlayer(), new EffectPedsFleeing(), new EffectPlayerSpin(), new EffectRainbow(), + new EffectPlayerLosesWeight(), new EffectPlayerGainsWeight(), new EffectSetRandomHat(), + new EffectHealNearbyPeds(), new EffectReviveDeadPeds(), new EffectGravityGun(), + new EffectSpawnAngryTommy(), new EffectDisableDeadEye(), new EffectPartyTime(), + new EffectSetRandomVelocity(), new EffectExplodeNearbyPeds(), new EffectNearbyPedIsCompanion(), + new EffectEveryoneRagdollsWhenShot(), new EffectNearbyPedIsEnemy(), new EffectExplosiveCombat(), + new EffectGiveEveryoneRifle(), new EffectTimelapse(), new EffectNoHUD(), new EffectFirstPerson(), + new EffectTopDownCamera(), new EffectAgitateHorse(), new EffectODriscolls(), + new EffectInsaneGravity(), new EffectUpsideDownCamera(), new EffectOneHitKO(), + new EffectBanditoKidnapsPlayer(), new EffectTpRandomLocation(), new EffectFakeTeleport(), + new EffectSpawnRandomVeh(), new EffectHorsesAreDonkeys(), new EffectSpawnTwitchViewer(), + new EffectEveryoneIsLenny(), new EffectShadesOfGray(), new EffectPotatoMode(), + new EffectSpawnExtremeEvilMicah(), new EffectOilWagonsRain()}; + EffectsMap.clear(); - + for (auto* effect : AllEffects) { EffectsMap.emplace(effect->ID, effect); } - - AllMetaEffects = { - new MetaEffectTotalChaos(), - new MetaEffectComboTime() - }; - + + AllMetaEffects = {new MetaEffectTotalChaos(), new MetaEffectComboTime(), new MetaEffectDoubleSubs()}; + MetaEffectsMap.clear(); - + for (auto* effect : AllMetaEffects) { MetaEffectsMap.emplace(effect->ID, effect); @@ -1025,7 +974,7 @@ void ChaosMod::InitEffects() void ChaosMod::ToggleDefaultEffectActivation() { MessageBeep(MB_OK); - + bEffectsActivatesAfterTimer = !bEffectsActivatesAfterTimer; } @@ -1039,19 +988,19 @@ void ChaosMod::ChangeSelectedEffect(int value) if (debugSelectedEffectIndex == 0 && value == -1) { debugSelectedEffectIndex = AllEffects.size() - 1; - AUDIO::PLAY_SOUND_FRONTEND((char*)"NAV_LEFT", (char*)"Ledger_Sounds", true, 0); + AUDIO::PLAY_SOUND_FRONTEND((char*) "NAV_LEFT", (char*) "Ledger_Sounds", true, 0); } else { debugSelectedEffectIndex += value; - + if (debugSelectedEffectIndex >= AllEffects.size()) { debugSelectedEffectIndex = 0; } - - AUDIO::PLAY_SOUND_FRONTEND((char*)"NAV_RIGHT", (char*)"Ledger_Sounds", true, 0); - + + AUDIO::PLAY_SOUND_FRONTEND((char*) "NAV_RIGHT", (char*) "Ledger_Sounds", true, 0); + } } @@ -1060,107 +1009,110 @@ void ChaosMod::ActivateSelectedEffect() if (bEffectSelectionVisible) { auto* effect = AllEffects[debugSelectedEffectIndex]; - + if (effect) { ActivateEffect(effect); } - + bEffectSelectionVisible = false; - - AUDIO::PLAY_SOUND_FRONTEND((char*)"INFO", (char*)"HUD_SHOP_SOUNDSET", true, 0); + + AUDIO::PLAY_SOUND_FRONTEND((char*) "INFO", (char*) "HUD_SHOP_SOUNDSET", true, 0); } } -void ChaosMod::ShowNotification(const char* title, const char* subtitle, const char* iconDict, const char* iconName, int32_t durationMs, const char* iconColor) +void ChaosMod::ShowNotification(const char* title, const char* subtitle, const char* iconDict, const char* iconName, + int32_t durationMs, const char* iconColor) { if (!notificationDuration) { notificationDuration = new NotificationDuration(); } - + if (!notificationData) { notificationData = new NotificationData(); } - + notificationDuration->ms = durationMs; - + if (strlen(iconColor) == 0) { iconColor = "COLOR_PURE_WHITE"; } - - notificationData->title = GAMEPLAY::CREATE_STRING(10, (char*)"LITERAL_STRING", (char*)title); - notificationData->subtitle = GAMEPLAY::CREATE_STRING(10, (char*)"LITERAL_STRING", (char*)subtitle); - - notificationData->iconDict = GAMEPLAY::GET_HASH_KEY((char*)iconDict); - notificationData->icon = GAMEPLAY::GET_HASH_KEY((char*)iconName); - notificationData->iconColor = GAMEPLAY::GET_HASH_KEY((char*)iconColor); - - if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*)iconDict)) + + notificationData->title = GAMEPLAY::CREATE_STRING(10, (char*) "LITERAL_STRING", (char*) title); + notificationData->subtitle = GAMEPLAY::CREATE_STRING(10, (char*) "LITERAL_STRING", (char*) subtitle); + + notificationData->iconDict = GAMEPLAY::GET_HASH_KEY((char*) iconDict); + notificationData->icon = GAMEPLAY::GET_HASH_KEY((char*) iconName); + notificationData->iconColor = GAMEPLAY::GET_HASH_KEY((char*) iconColor); + + if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*) iconDict)) { - TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*)iconDict, 0); + TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*) iconDict, 0); WAIT(1000); } - + /** _UI_FEED_POST_SAMPLE_TOAST */ - UIUNK::_0x26E87218390E6729((Any*)notificationDuration, (Any*)notificationData, 1, 1); - - TEXTURE::SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED((char*)iconDict); + UIUNK::_0x26E87218390E6729((Any*) notificationDuration, (Any*) notificationData, 1, 1); + + TEXTURE::SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED((char*) iconDict); } -void ChaosMod::ShowNotification2(const char* title, const char* subtitle, uint32_t durationMs, const char* iconDict, const char* iconName, LinearColor iconColor) +void ChaosMod::ShowNotification2(const char* title, const char* subtitle, uint32_t durationMs, const char* iconDict, + const char* iconName, LinearColor iconColor) { notification2Data.bSubtitleExists = strlen(subtitle) != 0; notification2Data.title = ""; notification2Data.title += title; notification2Data.title += ""; - + notification2Data.subtitle = ""; notification2Data.subtitle += subtitle; notification2Data.subtitle += ""; - + notification2Data.hideTime = GetTickCount() + durationMs; notification2Data.showTime = GetTickCount(); - - if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*)iconDict)) + + if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*) iconDict)) { - TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*)iconDict, 0); + TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*) iconDict, 0); WAIT(100); } - - if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*)"feeds")) + + if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*) "feeds")) { - TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*)"feeds", 0); + TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*) "feeds", 0); WAIT(100); } - + notification2Data.icon.dict = iconDict; notification2Data.icon.name = iconName; notification2Data.iconColor = iconColor; - + } void ChaosMod::RenderNotification2() { float yOffset = 0.35f; - + float opacity = 1.0f; uint32_t timeNow = GetTickCount(); - + const uint32_t fadeTime = 300; - + if (timeNow < notification2Data.showTime + fadeTime) { - opacity = float(timeNow - notification2Data.showTime) / float(notification2Data.showTime + fadeTime - notification2Data.showTime); + opacity = float(timeNow - notification2Data.showTime) / + float(notification2Data.showTime + fadeTime - notification2Data.showTime); } else if (timeNow > notification2Data.hideTime - fadeTime) { uint32_t start = notification2Data.hideTime - fadeTime; - opacity = 1.0f-(float(timeNow - start) / float(notification2Data.hideTime - start)); + opacity = 1.0f - (float(timeNow - start) / float(notification2Data.hideTime - start)); } - + if (opacity < 0.0f) { opacity = 0.0f; @@ -1169,36 +1121,38 @@ void ChaosMod::RenderNotification2() { opacity = 1.0f; } - + uint8_t alpha = uint8_t(255.0f * opacity); - - if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*)notification2Data.icon.dict)) + + if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*) notification2Data.icon.dict)) { - TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*)notification2Data.icon.dict, 0); + TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*) notification2Data.icon.dict, 0); WAIT(100); } - - if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*)"feeds")) + + if (!TEXTURE::HAS_STREAMED_TEXTURE_DICT_LOADED((char*) "feeds")) { - TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*)"feeds", 0); + TEXTURE::REQUEST_STREAMED_TEXTURE_DICT((char*) "feeds", 0); WAIT(100); } - - GRAPHICS::DRAW_SPRITE((char*)"feeds", (char*)"help_text_bg", 0.5f, 0.5f + yOffset, 512.0f / 1920.0f, 128.0f / 1080.0f, 0.0f, 0, 0, 0, alpha, false); - + + GRAPHICS::DRAW_SPRITE((char*) "feeds", (char*) "help_text_bg", 0.5f, 0.5f + yOffset, 512.0f / 1920.0f, + 128.0f / 1080.0f, 0.0f, 0, 0, 0, alpha, false); + /** Icon color */ LinearColor iconC = notification2Data.iconColor; iconC.A = uint8_t(float(iconC.A) * opacity); - - GRAPHICS::DRAW_SPRITE((char*)notification2Data.icon.dict, (char*)notification2Data.icon.name, 0.41f, 0.5f + yOffset, 0.05f, 96.0f / 1080.0f, 0.0f, iconC.R, iconC.G, iconC.B, iconC.A, false); - + + GRAPHICS::DRAW_SPRITE((char*) notification2Data.icon.dict, (char*) notification2Data.icon.name, 0.41f, + 0.5f + yOffset, 0.05f, 96.0f / 1080.0f, 0.0f, iconC.R, iconC.G, iconC.B, iconC.A, false); + UI::SET_TEXT_SCALE(0.0f, 0.5f); UI::SET_TEXT_COLOR_RGBA(255, 255, 255, alpha); UI::SET_TEXT_CENTRE(false); UI::SET_TEXT_DROPSHADOW(0, 0, 0, 0, 0); float textY = 0.5f; - + if (notification2Data.bSubtitleExists) { textY = 0.46f; @@ -1207,34 +1161,37 @@ void ChaosMod::RenderNotification2() { textY = 0.48f; } - - notification2Data.__titleVarStr = GAMEPLAY::CREATE_STRING(10, (char*)"LITERAL_STRING", (char*)notification2Data.title.c_str()); - notification2Data.__titleVarStr = invoke(0xFA925AC00EB830B9, 42, (char*)"COLOR_STRING", 0, notification2Data.__titleVarStr); - - UI::DRAW_TEXT((char*)notification2Data.__titleVarStr, 0.44f, textY + yOffset); - + + notification2Data.__titleVarStr = GAMEPLAY::CREATE_STRING(10, (char*) "LITERAL_STRING", + (char*) notification2Data.title.c_str()); + notification2Data.__titleVarStr = invoke(0xFA925AC00EB830B9, 42, (char*) "COLOR_STRING", 0, + notification2Data.__titleVarStr); + + UI::DRAW_TEXT((char*) notification2Data.__titleVarStr, 0.44f, textY + yOffset); + if (notification2Data.bSubtitleExists) { UI::SET_TEXT_SCALE(0.0f, 0.4f); UI::SET_TEXT_COLOR_RGBA(255, 255, 255, alpha); UI::SET_TEXT_CENTRE(false); UI::SET_TEXT_DROPSHADOW(0, 0, 0, 0, 0); - - auto subtitle = GAMEPLAY::CREATE_STRING(10, (char*)"LITERAL_STRING", (char*)notification2Data.subtitle.c_str()); - subtitle = invoke(0xFA925AC00EB830B9, 42, (char*)"COLOR_STRING", 0, subtitle); - - UI::DRAW_TEXT((char*)subtitle, 0.44f, 0.5f + yOffset); + + auto subtitle = GAMEPLAY::CREATE_STRING(10, (char*) "LITERAL_STRING", + (char*) notification2Data.subtitle.c_str()); + subtitle = invoke(0xFA925AC00EB830B9, 42, (char*) "COLOR_STRING", 0, subtitle); + + UI::DRAW_TEXT((char*) subtitle, 0.44f, 0.5f + yOffset); } } void ChaosMod::UpdatePlayerSkinHash() { - static Hash playerSkinArthur = GAMEPLAY::GET_HASH_KEY((char*)"Player_Zero"); - static Hash playerSkinJohn = GAMEPLAY::GET_HASH_KEY((char*)"Player_Three"); - + static Hash playerSkinArthur = GAMEPLAY::GET_HASH_KEY((char*) "Player_Zero"); + static Hash playerSkinJohn = GAMEPLAY::GET_HASH_KEY((char*) "Player_Three"); + uint64_t* ptr1 = getGlobalPtr(0x28) + 0x27; uint64_t* ptr2 = getGlobalPtr(0x1D890E) + 2; - + if (*ptr1 == playerSkinArthur || *ptr1 == playerSkinJohn) { ChaosMod::PlayerSkin1 = *ptr1; @@ -1245,31 +1202,31 @@ void ChaosMod::UpdatePlayerSkinHash() void ChaosMod::ResetPlayerSkin() { Hash currentSkin = ENTITY::GET_ENTITY_MODEL(PLAYER::PLAYER_PED_ID()); - - static Hash playerSkinArthur = GAMEPLAY::GET_HASH_KEY((char*)"Player_Zero"); - static Hash playerSkinJohn = GAMEPLAY::GET_HASH_KEY((char*)"Player_Three"); - + + static Hash playerSkinArthur = GAMEPLAY::GET_HASH_KEY((char*) "Player_Zero"); + static Hash playerSkinJohn = GAMEPLAY::GET_HASH_KEY((char*) "Player_Three"); + if (currentSkin == playerSkinArthur || currentSkin == playerSkinJohn) { return; } - + LoadModel(ChaosMod::PlayerSkin1); - + PLAYER::SET_PLAYER_MODEL(PLAYER::PLAYER_ID(), ChaosMod::PlayerSkin1, 1); *getGlobalPtr(0x23) = PLAYER::PLAYER_PED_ID(); - + uint64_t* ptr1 = getGlobalPtr(0x28) + 0x27; uint64_t* ptr2 = getGlobalPtr(0x1D890E) + 2; - + *ptr1 = ChaosMod::PlayerSkin1; *ptr2 = ChaosMod::PlayerSkin2; Ped playerPed = PLAYER::PLAYER_PED_ID(); *getGlobalPtr(0x23) = playerPed; - + ENTITY::SET_ENTITY_COLLISION(playerPed, true, true); ENTITY::SET_ENTITY_DYNAMIC(playerPed, true); - + Singleton->RestorePlayerAttributes(); } @@ -1277,71 +1234,75 @@ void ChaosMod::StartWSServer() { wsServer = new WebSocketServer(); wsServer->Init(9149); - + LogToFile("Creating WebSockets thread.."); - - wsThread = std::thread([this] { this->wsServer->Run(); }); - + + wsThread = std::thread([this] + { + this->wsServer->Run(); + }); + wsThread.detach(); - + TerminateNodeProcess(); - + StartNodeProcess(); } std::vector ChaosMod::GenerateEffectsWithChances(uint32_t maxEffects) { - std::vector effects; - std::vector effectsIndices = {}; - std::set oldEffectIDs; - + std::vector < Effect * > effects; + std::vector effectsIndices = {}; + std::set oldEffectIDs; + for (auto oldEffect : oldEffects) { oldEffectIDs.insert(oldEffect->ID); } - + for (uint32_t i = 0; i < config.effects.size(); i++) { ConfigEffect& configEffect = config.effects[i]; - + /** * Skip this effect if it was disabled by user or activated in the previous time */ - if (!configEffect.bEnabled || oldEffectIDs.contains(configEffect.id) || (prevActivatedEffect && prevActivatedEffect->ID == configEffect.id)) + if (!configEffect.bEnabled || oldEffectIDs.contains(configEffect.id) || + (prevActivatedEffect && prevActivatedEffect->ID == configEffect.id)) { continue; } - + configEffect.chance = configEffect.chance < 1 ? 1 : (configEffect.chance > 10 ? 10 : configEffect.chance); - + effectsIndices.insert(effectsIndices.end(), configEffect.chance, i); } - + for (uint32_t i = 0; i < maxEffects; i++) { uint32_t randomIndex = rand() % effectsIndices.size(); uint16_t effectIndex = effectsIndices[randomIndex]; - + ConfigEffect configEffect = config.effects[effectIndex]; - + auto* effect = EffectsMap[configEffect.id]; - + if (effect) { effects.push_back(effect); } - + if (maxEffects == 1) { break; } - + /** * Find a first index of the effect in effectsIndices list, then delete all of this effect's indices * Effects will not be repeated in the output array if we do this */ uint32_t effectIndexStart = randomIndex; - + for (int i = randomIndex; i >= 0; i--) { if (effectsIndices[i] == effectIndex) @@ -1349,9 +1310,10 @@ std::vector ChaosMod::GenerateEffectsWithChances(uint32_t maxEffects) effectIndexStart = i; } } - effectsIndices.erase(effectsIndices.begin() + effectIndexStart, effectsIndices.begin() + (effectIndexStart + configEffect.chance) ); + effectsIndices.erase(effectsIndices.begin() + effectIndexStart, + effectsIndices.begin() + (effectIndexStart + configEffect.chance)); } - + return effects; } @@ -1361,18 +1323,18 @@ void ChaosMod::LogToFile(const char* str) { return; } - + ChaosMod::globalMutex.lock(); - + static auto logFilePath = std::filesystem::current_path() / L"ChaosMod" / L"chaos.log"; - + ChaosMod::logString += str; ChaosMod::logString += "\n"; - + std::ofstream outFile(logFilePath); outFile << logString; outFile.close(); - + ChaosMod::globalMutex.unlock(); } @@ -1386,7 +1348,7 @@ void ChaosMod::ResetMetaTimer() { MetaActivationTime = GetTickCount() + (config.metaInterval * 1000); } - + activeMeta = nullptr; metaEffectColorSinX = 0.0f; } @@ -1396,12 +1358,12 @@ bool ChaosMod::RequestTwitchViewerNameToSpawn() if (!config.bTwitch || !wsServer) { this->twitchViewerNameToSpawn = "Viewer_Name"; - + return false; } - + wsServer->SendMessageToClient("request-twitch-viewer-name"); - + return true; } @@ -1409,40 +1371,40 @@ void ChaosMod::SavePlayerAttributes() { Ped playerPed = PLAYER::PLAYER_PED_ID(); Player player = PLAYER::PLAYER_ID(); - - static Hash playerSkinArthur = GAMEPLAY::GET_HASH_KEY((char*)"Player_Zero"); - static Hash playerSkinJohn = GAMEPLAY::GET_HASH_KEY((char*)"Player_Three"); + + static Hash playerSkinArthur = GAMEPLAY::GET_HASH_KEY((char*) "Player_Zero"); + static Hash playerSkinJohn = GAMEPLAY::GET_HASH_KEY((char*) "Player_Three"); Hash skin = ENTITY::GET_ENTITY_MODEL(playerPed); - + if (skin != playerSkinArthur && skin != playerSkinJohn) { return; } - + for (int i = 0; i < 3; i++) { playerAttributesRanks[i] = ATTRIBUTE::_0x147149F2E909323C(playerPed, i); } - + playerDeadEyeLevel = PLAYER::_0xCCE7C695C164C35F(player); - - + + playerOldClothes.clear(); - + int32_t maxCategories = PED::_0xA622E66EEE92A08D(PLAYER::PLAYER_PED_ID()); - + struct ComponentsStruct { alignas(32) uint8_t param1 = 0; }; - + for (int32_t i = 0; i < maxCategories; i++) { ComponentsStruct st1; ComponentsStruct st2; - Hash componentHash = PED::_0x77BA37622E22023B(PLAYER::PLAYER_PED_ID(), i, true, (Any*)&st1, (Any*)&st2); - + Hash componentHash = PED::_0x77BA37622E22023B(PLAYER::PLAYER_PED_ID(), i, true, (Any * ) & st1, (Any * ) & st2); + if (componentHash != 0) { playerOldClothes.insert(componentHash); @@ -1454,38 +1416,38 @@ void ChaosMod::RestorePlayerAttributes() { Ped playerPed = PLAYER::PLAYER_PED_ID(); Player player = PLAYER::PLAYER_ID(); - + for (int i = 0; i < 3; i++) { /** Reset attribute rank */ ATTRIBUTE::_0x5DA12E025D47D4E5(playerPed, i, playerAttributesRanks[i]); - + /** Set core values */ ATTRIBUTE::_0xC6258F41D86676E0(playerPed, i, 100); } - + ENTITY::SET_ENTITY_HEALTH(playerPed, ENTITY::GET_ENTITY_MAX_HEALTH(playerPed, 0), 0); - + PLAYER::RESTORE_PLAYER_STAMINA(player, 1.0f); PLAYER::RESTORE_SPECIAL_ABILITY(player, -1, 1); - + /** Special abilites */ PLAYER::_0xAE637BB8EF017875(player, 0); PLAYER::_0x95EE1DEE1DCD9070(player, 1); PLAYER::_0x64FF4BF9AF59E139(player, 0); PLAYER::_0xA63FCAD3A6FEC6D2(player, 1); - + /** _SET_DEADEYE_ABILITY_LEVEL */ PLAYER::_0xF0FE8E790BFEB5BB(player, playerDeadEyeLevel); - + while (!PED::_0xA0BC8FAED8CFEB3C(playerPed)) { WAIT(100); } - + for (auto hash : playerOldClothes) { PED::_0xD3A7B003ED343FD9(playerPed, hash, 1, 0, 1); } - + } \ No newline at end of file diff --git a/src/script.h b/src/script.h index 74a4115..ba18af5 100644 --- a/src/script.h +++ b/src/script.h @@ -18,12 +18,16 @@ struct Vector2 { - Vector2() {}; + Vector2() + { + }; + Vector2(float _X, float _Y) { X = _X; Y = _Y; } + float X = 0.0f; float Y = 0.0f; }; @@ -34,11 +38,13 @@ struct KeyState bool bPressed = false; }; -struct NotificationDuration { +struct NotificationDuration +{ alignas(32) int32_t ms = 2000; }; -struct NotificationData { +struct NotificationData +{ alignas(8) int32_t __unknown = 0; alignas(8) const char* title; alignas(8) const char* subtitle; @@ -51,12 +57,16 @@ struct NotificationData { struct GameAssetData { - GameAssetData() {}; + GameAssetData() + { + }; + GameAssetData(const char* _dict, const char* _name) { dict = _dict; name = _name; } + const char* dict; const char* name; }; @@ -65,19 +75,19 @@ struct Notification2Data { std::string title; std::string subtitle; - + uint32_t hideTime = 0; uint32_t showTime = 0; - + GameAssetData icon; - + LinearColor iconColor; - + const char* __titleVarStr; const char* __subtitleVarStr; - + bool bSubtitleExists = false; - + }; @@ -85,79 +95,97 @@ class ChaosMod { public: ChaosMod(); + ~ChaosMod(); - + static void ScriptMain(); - + static ChaosMod* Singleton; - + /** Returns singleton */ static ChaosMod* Get(); - + bool IsModEnabled(); - static void DrawText(char* text, Vector2 position, Vector2 scale, LinearColor color, bool bCenter = true, int shadowSize = 0, LinearColor shadowColor = LinearColor()); - - static void OnKeyboardMessage(DWORD key, WORD repeats, BYTE scanCode, BOOL isExtended, BOOL isWithAlt, BOOL wasDownBefore, BOOL isUpNow); - + static void + DrawText(char* text, Vector2 position, Vector2 scale, LinearColor color, bool bCenter = true, int shadowSize = 0, + LinearColor shadowColor = LinearColor()); + + static void + OnKeyboardMessage(DWORD key, WORD repeats, BYTE scanCode, BOOL isExtended, BOOL isWithAlt, BOOL wasDownBefore, + BOOL isUpNow); + /** Enabled and disbles the mod */ void ToggleModStatus(); - + void ActivateEffect(Effect* effect); - + + void ActivateSubEffect(int num_subs); + + void ActivateRandomEffect(int num_effects); + + bool IsEffectActive(std::string effect_id); + WebSocketServer* wsServer = nullptr; - + std::thread wsThread; static std::mutex globalMutex; - + static void StopServer(); - + void StartWSServer(); - + static uint32_t LastTick; static uint64_t ThreadID; static Ped PLAYER_PED; static HMODULE hInstance; - + /** Set of peds created by mod */ - static std::set pedsSet; + static std::set pedsSet; /** Set of vehs created by mod */ - static std::set vehsSet; + static std::set vehsSet; /** Set of objects created by mod */ - static std::set propsSet; - - + static std::set propsSet; + + static Hash PlayerSkin1; static Hash PlayerSkin2; - + static void UpdatePlayerSkinHash(); + static void ResetPlayerSkin(); + private: void Main(); + void Update(); + void InputTick(); + void DrawUI(); - + bool bEnabled = false; - + std::string ModUITextString; uint32_t ModUITextEndTime = 0; - + KeyState keyStates[0xFF] = {}; - + bool isKeyPressed(uint8_t key); - + NotificationDuration* notificationDuration = nullptr; NotificationData* notificationData = nullptr; + + void ShowNotification(const char* title, const char* subtitle, const char* iconDict, const char* iconName, + int32_t durationMs = 2000, const char* iconColor = ""); - void ShowNotification(const char* title, const char* subtitle, const char* iconDict, const char* iconName, int32_t durationMs = 2000, const char* iconColor = ""); public: /** Timers and effects */ - + /** In seconds */ int effectsInterval = 90; int effectsVoteTime = 45; - + std::vector AllEffects; std::map EffectsMap; @@ -165,49 +193,55 @@ class ChaosMod uint32_t timeoutStartTime = 0; uint32_t timeoutEndTime = 0; uint32_t timeoutVotingStartTime = 0; - + bool bVotingEnabled = false; void ResetEffectsTimeout(); - + std::vector activeEffects; - + std::vector subEffects; + std::vector displayedEffects; + void DrawEffectInUI(Effect* effect, int32_t index); - + void InitEffects(); private: /** Debug */ - + bool bEffectsActivatesAfterTimer = true; - + /** For debug only, disables effect activation after timer */ void ToggleDefaultEffectActivation(); - + int32_t debugSelectedEffectIndex = 0; - + bool bEffectSelectionVisible = false; - + void ToggleEffectSelection(); - + void ChangeSelectedEffect(int value); - + void ActivateSelectedEffect(); + public: void StartNodeProcess(); + static void TerminateNodeProcess(); - + STARTUPINFOW NodeStartupInfo; PROCESS_INFORMATION NodeProcessInformation; private: - + /** Notifications 2 */ Notification2Data notification2Data; - - void ShowNotification2(const char* title, const char* subtitle, uint32_t durationMs, const char* iconDict, const char* iconName, LinearColor iconColor); - + + void ShowNotification2(const char* title, const char* subtitle, uint32_t durationMs, const char* iconDict, + const char* iconName, LinearColor iconColor); + void RenderNotification2(); + private: ModMenu modMenu; private: @@ -215,9 +249,9 @@ class ChaosMod public: /** This effect was activated in the previous time and will not be activated now */ Effect* prevActivatedEffect = nullptr; - + std::vector GenerateEffectsWithChances(uint32_t maxEffects); - + /** Effects available for vote on Twitch chat now */ std::vector pollEffects; @@ -231,46 +265,49 @@ class ChaosMod static uint32_t _DeltaTime; /** Difference between last and this tick in seconds */ static float _DeltaTimeSeconds; + /** Get difference between last and this tick in ms */ static inline uint32_t GetDeltaTime() { return ChaosMod::_DeltaTime; } + /** Get difference between last and this tick in seconds */ static inline float GetDeltaTimeSeconds() { return ChaosMod::_DeltaTimeSeconds; } - + static void LogToFile(const char* str); - + static std::string logString; public: MetaEffect* activeMeta = nullptr; uint32_t MetaActivationTime = 0; std::vector AllMetaEffects; - + std::map MetaEffectsMap; - + void ResetMetaTimer(); - + float metaEffectColorSinX = 0.0f; public: std::vector oldEffects; - + std::string twitchViewerNameToSpawn = ""; - + bool RequestTwitchViewerNameToSpawn(); + public: void SavePlayerAttributes(); - + void RestorePlayerAttributes(); - + /** Health, stamina and dead eye ranks */ int playerAttributesRanks[3]; - + int playerDeadEyeLevel = 1; - - std::set playerOldClothes; + + std::set playerOldClothes; }; \ No newline at end of file diff --git a/src/server.cpp b/src/server.cpp index d5652a6..cadc597 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -12,10 +12,10 @@ void WebSocketServer::Init(int32_t port) instance.set_open_handler(bind(&WebSocketServer::OnConnect, this, std::placeholders::_1)); instance.set_close_handler(bind(&WebSocketServer::OnDisconnect, this, std::placeholders::_1)); instance.set_message_handler(bind(&WebSocketServer::OnMessage, this, std::placeholders::_1, std::placeholders::_2)); - + instance.set_access_channels(websocketpp::log::alevel::none); instance.set_error_channels(websocketpp::log::elevel::none); - + instance.init_asio(); instance.listen("127.0.0.1", std::to_string(port)); instance.start_accept(); @@ -24,23 +24,23 @@ void WebSocketServer::Init(int32_t port) void WebSocketServer::Run() { ChaosMod::LogToFile("Started WebSockets thread & server"); - + bStarted = true; bool bJoinThread = false; while (true) { ChaosMod::globalMutex.lock(); - + uint32_t lastTick = ChaosMod::LastTick; - + if (GetTickCount() > lastTick + 5000) { bool bGamePaused = UI::IS_PAUSE_MENU_ACTIVE(); Ped ped = PLAYER::PLAYER_PED_ID(); - + /** If game thread is sleeping, but game is not paused by player */ bool bReloading = !bGamePaused; - + if (bReloading) { if (ChaosMod::PLAYER_PED) @@ -52,28 +52,31 @@ void WebSocketServer::Run() bReloading = false; } } - + if (bReloading) { Stop(); bJoinThread = true; bStarted = false; } - + ChaosMod::LastTick = GetTickCount(); } - + ChaosMod::globalMutex.unlock(); - + instance.poll_one(); - - if (!bStarted) break; + + if (!bStarted) + { + break; + } } - + if (bJoinThread && ChaosMod::Singleton) { ChaosMod::LogToFile("Stopping WebSockets server (game loading)"); - + ChaosMod::globalMutex.lock(); delete ChaosMod::Singleton->wsServer; ChaosMod::globalMutex.unlock(); @@ -85,23 +88,23 @@ void WebSocketServer::OnMessage(websocketpp::connection_hdl hdl, _server::messag std::string logStr = "Got message from websocket client: \n\""; logStr += msg->get_payload() + "\""; ChaosMod::LogToFile(logStr.c_str()); - + rapidjson::Document document; - + document.Parse(msg->get_payload().data()); - + if (document.HasParseError()) { return; } - + if (!document.HasMember("type")) { return; } - + std::string eventType = document["type"].GetString(); - + if (eventType == "activate-effect") { OnNewEffectActivated(document); @@ -110,24 +113,28 @@ void WebSocketServer::OnMessage(websocketpp::connection_hdl hdl, _server::messag { OnTwitchViewerSpawned(document); } + else if (eventType == "subscribe-event") + { + OnSubscribeEvent(document); + } } void WebSocketServer::OnConnect(websocketpp::connection_hdl hdl) { ChaosMod::LogToFile("Websockets client connected"); - + if (this->client) { delete this->client; } - + this->client = new websocketpp::connection_hdl(hdl); } void WebSocketServer::OnDisconnect(websocketpp::connection_hdl hdl) { ChaosMod::LogToFile("Websockets client disconnected"); - + if (this->client) { delete this->client; @@ -152,45 +159,45 @@ void WebSocketServer::SendMessageToClient(const char* msg) } } -void WebSocketServer::SendEffectNamesToClient(std::vector names) +void WebSocketServer::SendEffectNamesToClient(std::vector names) { rapidjson::Document document; - + document.SetObject(); - + document.AddMember("type", "vote_activate", document.GetAllocator()); - + rapidjson::Value namesArray; namesArray.SetArray(); - - for (auto str : names) + + for (auto str: names) { rapidjson::Value str_; str_.SetString(str.c_str(), document.GetAllocator()); namesArray.PushBack(str_, document.GetAllocator()); } - + document.AddMember("data", namesArray, document.GetAllocator()); - + rapidjson::StringBuffer buffer; - rapidjson::Writer writer(buffer); + rapidjson::Writer writer(buffer); document.Accept(writer); - + auto str = buffer.GetString(); - + //MessageBox(NULL, str, "Data", MB_OK); - + SendMessageToClient(buffer.GetString()); } void WebSocketServer::Stop() { bStarted = false; - + instance.stop(); instance.stop_listening(); instance.stop_perpetual(); - + if (this->client) { delete this->client; @@ -198,28 +205,28 @@ void WebSocketServer::Stop() } } -void WebSocketServer::OnNewEffectActivated(rapidjson::Document &document) +void WebSocketServer::OnNewEffectActivated(rapidjson::Document& document) { int32_t winnerID = -1; - + try { if (!document.HasMember("index")) { return; } - + winnerID = document["index"].GetInt(); } catch (int err) { // } - + ChaosMod::globalMutex.lock(); - + ChaosMod::Singleton->twitchWinnerID = winnerID; - + ChaosMod::globalMutex.unlock(); } @@ -229,12 +236,23 @@ void WebSocketServer::OnTwitchViewerSpawned(rapidjson::Document& document) { return; } - + std::string name = document["name"].GetString(); - + ChaosMod::globalMutex.lock(); - + ChaosMod::Singleton->twitchViewerNameToSpawn = name; - + ChaosMod::globalMutex.unlock(); } + +void WebSocketServer::OnSubscribeEvent(rapidjson::Document& document) +{ + if (!document.HasMember("num_subs")) + { + return; + } + + int num_subs = document["num_subs"].GetInt(); + ChaosMod::Singleton->ActivateSubEffect(num_subs); +} diff --git a/src/server.h b/src/server.h index f983020..3ab97b5 100644 --- a/src/server.h +++ b/src/server.h @@ -6,28 +6,36 @@ class WebSocketServer { public: typedef websocketpp::server _server; - + WebSocketServer(); - + void Init(int32_t port = 9149); + void Run(); - + void OnMessage(websocketpp::connection_hdl hdl, _server::message_ptr msg); + void OnConnect(websocketpp::connection_hdl hdl); + void OnDisconnect(websocketpp::connection_hdl hdl); - + void SendMessageToClient(std::string msg); + void SendMessageToClient(const char* msg); - - void SendEffectNamesToClient(std::vector names); + + void SendEffectNamesToClient(std::vector names); + void Stop(); private: _server instance; websocketpp::connection_hdl* client = nullptr; - + void OnNewEffectActivated(rapidjson::Document& document); - void OnTwitchViewerSpawned(rapidjson::Document &document); - + + void OnTwitchViewerSpawned(rapidjson::Document& document); + + void OnSubscribeEvent(rapidjson::Document& document); + std::atomic bStarted = std::atomic(false); }; \ No newline at end of file