class BotGroupMissionTroick: MissionBase { void BotGroupMissionTroick() { StartMissionAI(); } AIWorld world = GetGame().GetWorld().GetAIWorld(); // Конфиги ботов vector BotSpawnPoint = "7928.453613 337.658356 14597.561523"; // задаем точку спавна бота int m_botAcuracy = 10; // Настройка меткости бота (чем выше число, тем чаще бот промазывает) int BotSolderCountMin = 2; // назначаем минимальное количесство ботов int BotSolderCountMax = 4; // назначаем максимальное количесство ботов int botLootCountMin = 5; // назначаем минимальное количество лута у бота int botLootCountMax = 15; // назначаем максимальное количество лута у бота float Zone_Radius = 700; // Радиус триггера на игрока для появления ботов bool isUseCheckPoints = true; // задаем используются ли чекпонинты true - используются, fslse - не используются bool isBotKaratist = false; // Задаем будут ли боты с оружием или будут дратся кулаками, по умолчанию они с оружием, если нужны без огнестрела пропиши true bool onRespawnBot = true; // Включение или отключение респавна бота (true - включено, fslse - выключено) bool canUseTrigger = true; // Использовать триггер (true - включено, fslse - выключено), если не используется триггер боты спавнятся сразу после запуска сервера bool useKilFeed = true; // Включение или отключение оповещения при убийстве бота bool m_Frendly = false; // Дружелюбие :) включение или отключение. Если включено то боты вас не будут атаковать пока вы на него не нападете, если атакуете бота то станете для всех ботов врагом. bool onVoice = true; // Включение или отключение голоса бота (включение этого параметра вызывает больше нагрузки на сервер) int m_spawnBotRadius = 50; // Радиус спавна ботов на територие, центром територии является координата указанная в BotSpawnPoint int m_SpeedPatrol = 3; // Установка скорости передвижения при патрулировании (min = 1 max = 3) int m_TargetDist = 100; // Задаем растояние в метрах на котором бот видит цель. bool canBotSpawned = true; // Не изменять!!!!!!! // ------------------------------- конец конфига ------------------------------------------ // // Массивы с лутом и одеждой // Если какойто тип не нужен просто оставляем пустые ковычки пример ---> TStringArray OtherEquip = {""}; ref TStringArray Shirt = {"GorkaEJacket_Autumn", "GorkaEJacket_Flat", "GorkaEJacket_PautRev", "GorkaEJacket_Summer"}; //Добавляем верх одежды ref TStringArray Jeans = {"GorkaPants_Autumn", "GorkaPants_Flat", "GorkaPants_PautRev", "GorkaPants_Summer"}; //Добавляем штаны ref TStringArray Shoes = {"TTSKOBoots", "WorkingBoots_Beige", "CombatBoots_Beige", "CombatBoots_Black", "CombatBoots_Brown"}; //Добавляем ботинки ref TStringArray BackPack = {"CoyoteBag_Brown", "CoyoteBag_Green", "HuntingBag", "TortillaBag", "WaterproofBag_Green"}; //Добавляем Рюкзак ref TStringArray Vest = {"HighCapacityVest_Black", "HighCapacityVest_Olive", "HuntingVest", "PlateCarrierVest", "UKAssVest_Camo"}; //Добавляем разгрузку ref TStringArray Helm = {"GorkaHelmet", "Mich2001Helmet", "MotoHelmet_Black", "PumpkinHelmet", "SkateHelmet_Black"}; //Добавляем шлем или головной убор ref TStringArray Gloves = {"WorkingGloves_Beige", "WorkingGloves_Black", "NBCGlovesGray", "OMNOGloves_Brown", "SurgicalGloves_Blue"}; //Добавляем перчатки ref TStringArray OtherEquip = {"CivilianBelt", "MilitaryBelt"}; //Добавляем дополнительный элемент одежды, это может быть всё что угодно :) ref TStringArray RandomLoot = {"SardinesCan", "SodaCan_Cola", "SodaCan_Kvass", "Rice", "Rope", "Screwdriver", "AmmoBox_545x39_20Rnd"}; //Добавляем в масив любой лут, количество не ограничено ref TStringArray MeleeWeap = {"WoodAxe", "FirefighterAxe", "Shovel", "Pickaxe"}; //Добавляем холодное оружие // -------------------------------- конец массивов лута -------------------------------------------------------// EntityAI itemEnt; // Не изменять!!!! // Функция создания чекпоинтов (прописываем чекпоинты тут) void AddCeckPoint(SurvivorBotBase m_BotSolder) { m_BotSolder.SetUseCheckpoint(); // Эту строку не трогаем! m_BotSolder.AddCheckpoint("7908.396484 337.337708 14612.336914"); m_BotSolder.AddCheckpoint("7906.007324 338.781555 14654.738281"); m_BotSolder.AddCheckpoint("7927.181152 339.171600 14657.208008"); m_BotSolder.AddCheckpoint("7926.386230 338.485382 14639.730469"); m_BotSolder.AddCheckpoint("7937.773926 338.512451 14638.373047"); m_BotSolder.AddCheckpoint("7943.151855 338.512451 14626.012695"); } // ---------------------------------- Конец функции создания чекпоинтов -------------------------------------- / ref array m_BotMass = new array; ref array m_PlaersZoneArray = new array; // Функция создания оружия для бота (тут можно добавить 7 вмдов оружия, вписываем по своему усмотрению) void createWeapFromBot(SurvivorBotBase m_BotSolder) { int randomWeapon = Math.RandomInt(1, 7); switch( randomWeapon ) { case 1: { m_BotSolder.AddWeapon("M4A1"); //оружие m_BotSolder.AddWeaponAtt("M4_RISHndgrd"); //Обвес1 m_BotSolder.AddWeaponAtt("M4_MPBttstck"); //Обвес2 m_BotSolder.AddWeaponAtt("ACOGOptic"); //Обвес3 m_BotSolder.AddMagazine("Mag_STANAG_30Rnd"); //Обойма break; //Обвесы добовляем по необходимости, магазины для оружия выдаются автоматически если они не назначены в ручную } case 2: { m_BotSolder.AddWeapon("AKM"); m_BotSolder.AddWeaponAtt("AK_WoodBttstck"); m_BotSolder.AddWeaponAtt("AK_WoodHndgrd"); m_BotSolder.AddMagazine("Mag_AKM_Drum75Rnd"); break; } case 3: { m_BotSolder.AddWeapon("AKM"); m_BotSolder.AddWeaponAtt("AK_WoodBttstck"); m_BotSolder.AddWeaponAtt("AK_WoodHndgrd"); m_BotSolder.AddMagazine("Mag_AKM_Drum75Rnd"); break; } case 4: { m_BotSolder.AddWeapon("SVD"); m_BotSolder.AddMagazine("Mag_SVD_10Rnd"); break; } case 5: { m_BotSolder.AddWeapon("M4A1"); m_BotSolder.AddWeaponAtt("M4_RISHndgrd"); m_BotSolder.AddWeaponAtt("M4_MPBttstck"); m_BotSolder.AddWeaponAtt("ACOGOptic"); m_BotSolder.AddMagazine("Mag_STANAG_30Rnd"); break; } case 6: { m_BotSolder.AddWeapon("AKM"); m_BotSolder.AddWeaponAtt("AK_WoodBttstck"); m_BotSolder.AddWeaponAtt("AK_WoodHndgrd"); m_BotSolder.AddMagazine("Mag_AKM_Drum75Rnd"); break; } case 7: { m_BotSolder.AddWeapon("AKM"); m_BotSolder.AddWeaponAtt("AK_WoodBttstck"); m_BotSolder.AddWeaponAtt("AK_WoodHndgrd"); m_BotSolder.AddMagazine("Mag_AKM_Drum75Rnd"); break; } } } // ----------------------------- Конец функции создания оружия ------------------------------------- // // Функция спавна бота (тут ничего не меняем!!!) void createBotUnit() { vector Navmesh; vector botSpPos; private SurvivorBotBase m_BotSolder; ref TStringArray m_BotBody = { "BotM_Mirek", "BotM_Rolf", "BotM_Quinn", "BotM_Peter", "BotM_Oliver" }; PGFilter m_pgFilterNav = new PGFilter(); m_pgFilterNav.SetFlags(PGPolyFlags.WALK, PGPolyFlags.INSIDE, 0); float bspX = BotSpawnPoint[0]; float bspY = BotSpawnPoint[2]; if (isUseCheckPoints) botSpPos = Vector(bspX + Math.RandomInt(-7, 7), BotSpawnPoint[1], bspY + Math.RandomInt(-7, 7)); else botSpPos = Vector(bspX + Math.RandomInt(-m_spawnBotRadius, m_spawnBotRadius), BotSpawnPoint[1], bspY + Math.RandomInt(-m_spawnBotRadius, m_spawnBotRadius)); bool IsNavmesh = world.SampleNavmeshPosition( botSpPos, 2, m_pgFilterNav, Navmesh ); if (IsNavmesh) m_BotSolder = SurvivorBotBase.Cast(GetGame().CreatePlayer(null, m_BotBody.GetRandomElement(), Navmesh, 0, "NONE")); else m_BotSolder = SurvivorBotBase.Cast(GetGame().CreatePlayer(null, m_BotBody.GetRandomElement(), botSpPos, 0, "NONE")); m_BotSolder.GetInventory().CreateInInventory(Shirt.GetRandomElement()); m_BotSolder.GetInventory().CreateInInventory(Jeans.GetRandomElement()); m_BotSolder.GetInventory().CreateInInventory(Shoes.GetRandomElement()); m_BotSolder.GetInventory().CreateInInventory(BackPack.GetRandomElement()); m_BotSolder.GetInventory().CreateInInventory(Vest.GetRandomElement()); m_BotSolder.GetInventory().CreateInInventory(Helm.GetRandomElement()); m_BotSolder.GetInventory().CreateInInventory(Gloves.GetRandomElement()); m_BotSolder.GetInventory().CreateInInventory(OtherEquip.GetRandomElement()); if (isBotKaratist) m_BotSolder.GetHumanInventory().CreateInHands(MeleeWeap.GetRandomElement()); else createWeapFromBot(m_BotSolder); int rndLootCnt = Math.RandomInt(botLootCountMin, botLootCountMax); for (int i = 0; i < rndLootCnt; i++) { itemEnt = m_BotSolder.GetInventory().CreateInInventory(RandomLoot.GetRandomElement()); if (itemEnt) { int rndHlt = Math.RandomInt(55,100); itemEnt.SetHealth("","",rndHlt); } } m_BotSolder.SetAcuracy(m_botAcuracy); m_BotSolder.SetDistance(m_TargetDist); m_BotSolder.SetUseVoice(onVoice); m_BotSolder.SetUseKillFeed(useKilFeed); m_BotSolder.SetFrendly(m_Frendly); m_BotSolder.SetSpeedPatrol(m_SpeedPatrol); if (isUseCheckPoints) AddCeckPoint(m_BotSolder); m_BotMass.Insert(m_BotSolder); } // ----------------------------- Конец функции спавна бота ------------------------------------- // // ----------------------------- Функция респавна ботов ----------------------------------------// private void respawnBotUnitTroick() { ref array players = new array; GetGame().GetPlayers( players ); SurvivorBotBase Bot_Ar; vector posB; bool m_botRemoved = false; float distB; int m_countBot = m_BotMass.Count(); int plaersZoneCount = -1; m_PlaersZoneArray.Clear(); if (canBotSpawned) { for ( int u = 0; u < players.Count(); u++ ) { PlayerBase player; Class.CastTo(player, players.Get(u)); vector pos = player.GetPosition(); float dist = vector.Distance( pos, BotSpawnPoint ); if ( dist < Zone_Radius && player.IsAlive() ) { m_PlaersZoneArray.Insert(player); // return; } } Print("Players count in zone bots Troick = " + m_PlaersZoneArray.Count()); if (m_PlaersZoneArray.Count() == 0) { for ( int a = 0; a < m_countBot; a++ ) { Bot_Ar = m_BotMass.Get(a); if (Bot_Ar) { if (!Bot_Ar.IsAlive()) { posB = Bot_Ar.GetPosition(); distB = vector.Distance( posB, BotSpawnPoint ); if (distB < Zone_Radius) { m_BotMass.Remove( a ); } if (m_BotMass.Count() == 0) m_botRemoved = true; } else { if (distB < Zone_Radius) { m_BotMass.Remove( a ); GetGame().ObjectDelete( Bot_Ar ); } if (m_BotMass.Count() == 0) m_botRemoved = true; } } } if (m_botRemoved && m_PlaersZoneArray.Count() == 0) { StartMissionAI(); GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(respawnBotUnitTroick); m_botRemoved = false; } } } } // ----------------------------- Конец функции ----------------------------------------// // Функция спавна группы ботов int delaySpawn = 0; void spawnBotGroup() { int rndBotGrpCnt = Math.RandomInt(BotSolderCountMin, BotSolderCountMax); Print("Bots spawned! Count " + rndBotGrpCnt); for (int a = 0; a < rndBotGrpCnt; a++) { GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(createBotUnit, 500 + delaySpawn); delaySpawn +=1000; } } // --------------------------------------- Конец функции спавна группы --------------------------------------- // // Функция триггера на игрока void TriggerPlayersTroick() { ref array players = new array; GetGame().GetPlayers( players ); delaySpawn = 0; if (canBotSpawned && IsGoodSrvFps()) { for ( int u = 0; u < players.Count(); u++ ) { PlayerBase player; Class.CastTo(player, players.Get(u)); vector pos = player.GetPosition(); float dist = vector.Distance( pos, BotSpawnPoint ); if ( dist < Zone_Radius && !player.IsBot() ) { spawnBotGroup(); GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).Remove(TriggerPlayersTroick); if (onRespawnBot) GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(respawnBotUnitTroick, 60000, true); } } } } // --------------------------------------- Конец функции триггера --------------------------------------- // // Эту функцию вызываем в initBotMissions.c void StartMissionAI() { Print("Start mission bot"); if (canUseTrigger) { GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(TriggerPlayersTroick, 5000, true); } else if (IsGoodSrvFps()) { spawnBotGroup(); } } bool IsGoodSrvFps() { float TestFpsSrv = GetGame().GetFps(); if (TestFpsSrv < 2) { return true; } else { Print("Server FPS low! FPS = " + TestFpsSrv + " Bots not respawned!"); return false; } } }