Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "script.h"
- #include <string>
- #include <vector>
- #include <iostream>
- #include <fstream>
- #include "keyboard.h"
- using namespace std;
- //#define DEBUG_CONSOLE
- void allocateConsole()
- {
- AllocConsole();
- SetConsoleTitleA("RDR2DebugConsole");
- FILE* pCout;
- freopen_s(&pCout, "CONOUT$", "w", stdout);
- freopen_s(&pCout, "CONOUT$", "w", stderr);
- std::cout.clear();
- std::clog.clear();
- std::cerr.clear();
- }
- void notifycomplex(const char* fmt, ...)
- {
- #ifdef DEBUG_CONSOLE
- char buf[2048] = { 0 };
- va_list va_alist;
- va_start(va_alist, fmt);
- vsprintf_s(buf, fmt, va_alist);
- va_end(va_alist);
- char buff2[2048] = { 0 };
- sprintf_s(buff2, "%s", buf);
- const char* literalString = MISC::VAR_STRING(10, "LITERAL_STRING", buff2);
- std::cout << literalString << std::endl;
- #endif
- }
- struct GunInfo
- {
- Vehicle Gun;
- Ped Gunner;
- bool Available;
- bool WaitingForPedToReach;
- bool Occupied;
- bool PedRecentlyKilled;
- bool AssignedTarget;
- Ped Target;
- int CooldownTimer;
- };
- Hash MaximHash;
- const int maxguns = 4;
- const int defaultcooldown = 400;
- const float ConsiderRange = 20.0;
- const float MaxShootingRange = 60.0;
- int GunAccuracy = 10;
- GunInfo DefaultGunInfo = { NULL, NULL, false, false, false, false, false, NULL, 0 };
- GunInfo KnownGuns[maxguns];
- void refreshConsole()
- {
- #ifdef DEBUG_CONSOLE
- cout << string(100, '\n');
- cout << "----- TRACKING GUNS -----" << endl;
- for (int i = 0; i < maxguns; i++)
- {
- notifycomplex("GUN %i", i);
- notifycomplex(" VEHICLE: %s", (KnownGuns[i].Gun == NULL) ? " " : "YES");
- notifycomplex(" FREE: %s", KnownGuns[i].Available ? "TRUE" : "FALSE");
- notifycomplex(" PED: %s", (KnownGuns[i].Gunner == NULL) ? " " : "YES");
- notifycomplex("COMING: %s", KnownGuns[i].WaitingForPedToReach ? "TRUE" : "FALSE");
- notifycomplex("MANNED: %s", KnownGuns[i].Occupied ? "TRUE" : "FALSE");
- notifycomplex("KILLED: %s", KnownGuns[i].PedRecentlyKilled ? "TRUE" : "FALSE");
- notifycomplex("TARGET: %s", KnownGuns[i].AssignedTarget ? "TRUE" : "FALSE");
- notifycomplex("TARGET: %s", (KnownGuns[i].Target == NULL) ? " " : "YES");
- notifycomplex(" TIMER: %i", KnownGuns[i].CooldownTimer);
- cout << endl;
- }
- #endif
- }
- void AddGunToKnown(Vehicle g)
- {
- bool GunExists = false;
- for (int i = 0; i < maxguns; i++)
- {
- if (KnownGuns[i].Gun == g)
- {
- GunExists = true;
- }
- }
- if (!GunExists)
- {
- for (int i = 0; i < maxguns; i++)
- {
- if (KnownGuns[i].Gun == NULL)
- {
- KnownGuns[i].Gun = g;
- KnownGuns[i].Available = true;
- break;
- }
- }
- }
- }
- void RemoveGunFromKnown(Vehicle g)
- {
- for (int i = 0; i < maxguns; i++)
- {
- if (KnownGuns[i].Gun == g)
- {
- KnownGuns[i] = DefaultGunInfo;
- }
- }
- }
- bool WorldGunValid(Vehicle v)
- {
- if (v == NULL)
- {
- return false;
- }
- if (!VEHICLE::IS_VEHICLE_MODEL(v, MaximHash))
- {
- return false;
- }
- if (!ENTITY::IS_ENTITY_UPRIGHT(v, 40.0))
- {
- return false;
- }
- if (VEHICLE::IS_VEHICLE_WRECKED(v))
- {
- return false;
- }
- return true;
- }
- bool GunOccupiedByPlayer(Vehicle gun)
- {
- return (PED::GET_VEHICLE_PED_IS_IN(PLAYER::PLAYER_PED_ID(), false) == gun);
- }
- bool PedIsUsingKnownGun(Ped p)
- {
- bool usingOurGuns = false;
- for (int i = 0; i < maxguns; i++)
- {
- if (PED::GET_VEHICLE_PED_IS_IN(p, false) == KnownGuns[i].Gun)
- {
- usingOurGuns = true;
- }
- }
- return usingOurGuns;
- }
- bool PedIsGunCapable(Ped p)
- {
- if (!PED::IS_PED_HUMAN(p))
- {
- return false;
- }
- if (p == PLAYER::PLAYER_PED_ID() || p == PLAYER::GET_PLAYER_PED(PLAYER::PLAYER_ID()) || PED::IS_PED_A_PLAYER(p))
- {
- return false;
- }
- if (PED::IS_PED_FATALLY_INJURED(p) || PED::IS_PED_DEAD_OR_DYING(p, false))
- {
- return false;
- }
- if (PED::IS_PED_LASSOED(p) || PED::IS_PED_BEING_DRAGGED(p) || PED::IS_PED_HOGTIED(p) || PED::IS_PED_INCAPACITATED(p) || PED::IS_PED_RAGDOLL(p))
- {
- return false;
- }
- //if (!PED::IS_PED_ON_FOOT(p) && !PedIsUsingKnownGun(p))
- //{
- // return false;
- //}
- bool combat = false;
- Ped potentialpeds[1024];
- int pcount = worldGetAllPeds(potentialpeds, 1024);
- for (int i = 0; i < pcount; i++)
- {
- Ped other = potentialpeds[i];
- if (PED::IS_PED_IN_COMBAT(p, other))
- {
- combat = true;
- }
- }
- if (!combat)
- {
- return false;
- }
- return true;
- }
- bool PedInGunConsiderRange(Ped ped, Vehicle gun)
- {
- Vector3 p = ENTITY::GET_ENTITY_COORDS(ped, true, true);
- Vector3 g = ENTITY::GET_ENTITY_COORDS(gun, true, true);
- return MISC::GET_DISTANCE_BETWEEN_COORDS(p.x, p.y, p.z, g.x, g.y, g.z, true) <= ConsiderRange;
- }
- bool PedAlreadyAssignedToGun(Ped p)
- {
- for (int i = 0; i < maxguns; i++)
- {
- if (KnownGuns[i].Gunner == p)
- {
- return true;
- }
- }
- return false;
- }
- void TellPedToManGun(Ped p, Vehicle gun)
- {
- TASK::TASK_ENTER_VEHICLE(p, gun, 20000, -1, 2.0f, 1, 0);
- }
- bool PedIsValidGunTarget(Ped target, Ped gunner)
- {
- if (target == gunner)
- {
- return false;
- }
- Vector3 tloc = ENTITY::GET_ENTITY_COORDS(target, true, true);
- Vector3 gloc = ENTITY::GET_ENTITY_COORDS(gunner, true, true);
- if (MISC::GET_DISTANCE_BETWEEN_COORDS(tloc.x, tloc.y, tloc.z, gloc.x, gloc.y, gloc.z, true) > MaxShootingRange)
- {
- return false;
- }
- // Figure out shooting at hostile animals later
- if (!PED::IS_PED_HUMAN(target))
- {
- return false;
- }
- if (!ENTITY::HAS_ENTITY_CLEAR_LOS_TO_ENTITY(gunner, target, 17))
- {
- return false;
- }
- if (PED::IS_PED_DEAD_OR_DYING(target, false))
- {
- return false;
- }
- if (PED::IS_PED_LASSOED(target) || PED::IS_PED_BEING_DRAGGED(target) || PED::IS_PED_HOGTIED(target) || PED::IS_PED_INCAPACITATED(target) || PED::IS_PED_RAGDOLL(target))
- {
- return false;
- }
- //if (!PED::IS_PED_IN_COMBAT(gunner, target))
- //{
- // return false;
- //}
- enum RelationshipType
- {
- ACQUAINTANCE_TYPE_NONE = 0,
- ACQUAINTANCE_TYPE_PED_RESPECT = 1,
- ACQUAINTANCE_TYPE_PED_LIKE = 2,
- ACQUAINTANCE_TYPE_PED_IGNORE = 3,
- ACQUAINTANCE_TYPE_PED_DISLIKE = 4,
- ACQUAINTANCE_TYPE_PED_HATE = 6
- };
- int RelationToTarget = PED::GET_RELATIONSHIP_BETWEEN_PEDS(gunner, target);
- if (RelationToTarget == ACQUAINTANCE_TYPE_PED_LIKE ||
- RelationToTarget == ACQUAINTANCE_TYPE_PED_RESPECT ||
- RelationToTarget == ACQUAINTANCE_TYPE_PED_IGNORE)
- {
- return false;
- }
- return true;
- }
- Ped ChooseGunTarget(Ped gunner, Vehicle gun)
- {
- Ped target = NULL;
- Ped potentialpeds[1024];
- int pcount = worldGetAllPeds(potentialpeds, 1024);
- for (int i = 0; i < pcount; i++)
- {
- Ped ped = potentialpeds[i];
- if (PedIsValidGunTarget(ped, gunner))
- {
- target = ped;
- }
- }
- return target;
- }
- void TriggerGunCooldown(int i)
- {
- KnownGuns[i].Available = false;
- KnownGuns[i].Gunner = NULL;
- KnownGuns[i].WaitingForPedToReach = false;
- KnownGuns[i].Occupied = false;
- KnownGuns[i].AssignedTarget = false;
- KnownGuns[i].Target = NULL;
- KnownGuns[i].PedRecentlyKilled = true;
- KnownGuns[i].CooldownTimer = defaultcooldown;
- }
- void ProcessGunsInWorld()
- {
- Vehicle potentialguns[50];
- int vcount = worldGetAllVehicles(potentialguns, 50);
- for (int i = 0; i < vcount; i++)
- {
- Vehicle gun = potentialguns[i];
- if (WorldGunValid(gun))
- {
- AddGunToKnown(gun);
- }
- else
- {
- RemoveGunFromKnown(gun);
- }
- }
- }
- void ProcessKnownGuns()
- {
- Ped potentialpeds[1024];
- int pcount = worldGetAllPeds(potentialpeds, 1024);
- for (int i = 0; i < maxguns; i++)
- {
- if (KnownGuns[i].Gun == NULL)
- {
- KnownGuns[i] = DefaultGunInfo;
- break;
- }
- // If the player is on the gun then just set a cooldown, it'll start counting down as soon as they leave
- if (GunOccupiedByPlayer(KnownGuns[i].Gun) && !KnownGuns[i].WaitingForPedToReach)
- {
- TriggerGunCooldown(i);
- }
- // If the gun is available and has nobody assigned to it, assign a valid ped and tell them to enter it
- else if (KnownGuns[i].Available && KnownGuns[i].Gunner == NULL)
- {
- for (int j = 0; j < pcount; j++)
- {
- Ped ped = potentialpeds[j];
- if (PedIsGunCapable(ped) && PedInGunConsiderRange(ped, KnownGuns[i].Gun) && !PedAlreadyAssignedToGun(ped) && !KnownGuns[i].WaitingForPedToReach)
- {
- KnownGuns[i].Available = false;
- KnownGuns[i].Gunner = ped;
- KnownGuns[i].WaitingForPedToReach = true;
- TellPedToManGun(KnownGuns[i].Gunner, KnownGuns[i].Gun);
- }
- }
- }
- // If we have a ped, but they died or something, clear everything and start the cooldown
- else if (KnownGuns[i].Gunner != NULL && !PedIsGunCapable(KnownGuns[i].Gunner))
- {
- TriggerGunCooldown(i);
- }
- // If we have a cooldown, decrement it
- else if (KnownGuns[i].PedRecentlyKilled && KnownGuns[i].CooldownTimer > 0)
- {
- KnownGuns[i].CooldownTimer--;
- }
- // If the cooldown expired, reset
- else if (KnownGuns[i].PedRecentlyKilled && KnownGuns[i].CooldownTimer <= 0)
- {
- KnownGuns[i].PedRecentlyKilled = false;
- KnownGuns[i].Available = true;
- }
- // If we have a ped but they're still running to the gun, check if they've reached it and prepare to fire if they have
- else if (KnownGuns[i].Gunner != NULL && KnownGuns[i].WaitingForPedToReach)
- {
- if (PED::GET_VEHICLE_PED_IS_IN(KnownGuns[i].Gunner, false) == KnownGuns[i].Gun)
- {
- KnownGuns[i].WaitingForPedToReach = false;
- KnownGuns[i].Occupied = true;
- // From ambush_exc_wagon_turret.c (Lemoyne Raiders Maxim Ambush)
- PED::SET_PED_COMBAT_MOVEMENT(KnownGuns[i].Gunner, 0);
- PED::SET_PED_COMBAT_ATTRIBUTES(KnownGuns[i].Gunner, 27, false);
- PED::SET_PED_COMBAT_ATTRIBUTES(KnownGuns[i].Gunner, 30, true);
- WEAPON::_0xA769D753922B031B(KnownGuns[i].Gunner, 0.5f, 0.5f);
- PED::SET_PED_FIRING_PATTERN(KnownGuns[i].Gunner, 1575766855);
- PED::SET_PED_CONFIG_FLAG(KnownGuns[i].Gunner, 22, true);
- PED::SET_PED_ACCURACY(KnownGuns[i].Gunner, GunAccuracy);
- }
- }
- // If we have a ped, and they are manning the gun, then give them a target and start shooting at it
- else if (KnownGuns[i].Gunner != NULL && KnownGuns[i].Occupied && !KnownGuns[i].AssignedTarget)
- {
- Ped potentialTarget = ChooseGunTarget(KnownGuns[i].Gunner, KnownGuns[i].Gun);
- if (potentialTarget != NULL)
- {
- KnownGuns[i].AssignedTarget = true;
- KnownGuns[i].Target = potentialTarget;
- TASK::TASK_VEHICLE_SHOOT_AT_PED(KnownGuns[i].Gunner, potentialTarget, 360.0f);
- }
- else
- {
- TASK::CLEAR_PED_TASKS(KnownGuns[i].Gunner, false, false);
- }
- }
- // If the target is down, clear the target so we can get a new one next time
- else if (KnownGuns[i].AssignedTarget && !PedIsValidGunTarget(KnownGuns[i].Target, KnownGuns[i].Gunner))
- {
- KnownGuns[i].AssignedTarget = false;
- KnownGuns[i].Target = NULL;
- }
- // If we have a target then shoot at it
- else if (KnownGuns[i].AssignedTarget)
- {
- // The game handles the actual shooting
- }
- // If something strange happened, just reset
- else if (KnownGuns[i].Gun != NULL && KnownGuns[i].Gunner != NULL)
- {
- TASK::TASK_EVERYONE_LEAVE_VEHICLE(KnownGuns[i].Gun, true);
- TriggerGunCooldown(i);
- }
- }
- }
- void ProcessOtherHeavyWeapons()
- {
- Vehicle mountedguns[10];
- int count = worldGetAllVehicles(mountedguns, 10);
- for (int i = 0; i < count; i++)
- {
- Vehicle gun = mountedguns[i];
- Hash gunHash = ENTITY::GET_ENTITY_MODEL(gun);
- // These vehicles are hardcoded
- //if (gunHash == MISC::GET_HASH_KEY("GATCHUCK_2") || gunHash == MISC::GET_HASH_KEY("policewagongatling01x"))
- //{
- // WEAPON::_SET_VEHICLE_WEAPON_HEADING_LIMITS(gun, -1, -180.0, 180.0);
- //}
- if (gun == PED::GET_VEHICLE_PED_IS_USING(PLAYER::PLAYER_PED_ID()))
- {
- if (gunHash == MISC::GET_HASH_KEY("hotchkiss_cannon") ||
- gunHash == MISC::GET_HASH_KEY("BREACH_CANNON") ||
- gunHash == MISC::GET_HASH_KEY("GATLING_GUN"))
- {
- int ro = 0;
- float step = 0.1;
- Vector3 rot = ENTITY::GET_ENTITY_ROTATION(gun, ro);
- if (IsKeyDown(0x41 /*A*/))
- {
- ENTITY::SET_ENTITY_ROTATION(gun, rot.x, rot.y, rot.z + step, ro, true);
- }
- else if (IsKeyDown(0x44 /*D*/))
- {
- ENTITY::SET_ENTITY_ROTATION(gun, rot.x, rot.y, rot.z - step, ro, true);
- }
- }
- }
- }
- }
- void update()
- {
- ProcessGunsInWorld();
- ProcessKnownGuns();
- ProcessOtherHeavyWeapons();
- }
- void main()
- {
- #ifdef DEBUG_CONSOLE
- allocateConsole();
- #endif
- MaximHash = MISC::GET_HASH_KEY("GATLINGMAXIM02");
- for (int i = 0; i < maxguns; i++)
- {
- KnownGuns[i] = DefaultGunInfo;
- }
- int refreshrate = 25;
- while (true)
- {
- #ifdef DEBUG_CONSOLE
- if (refreshrate <= 0)
- {
- refreshrate = 25;
- refreshConsole();
- }
- else
- {
- refreshrate--;
- }
- #endif
- update();
- WAIT(0);
- }
- }
- void ScriptMain()
- {
- srand(GetTickCount());
- main();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement