Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace ZombifiedInitiative;
- using Il2CppInterop.Runtime.InteropTypes.Arrays;
- using UnityEngine;
- using BepInEx;
- using BepInEx.Logging;
- using BepInEx.Unity.IL2CPP;
- using GTFO.API;
- using LevelGeneration;
- using Agents;
- using Player;
- using Enemies;
- [BepInDependency("dev.gtfomodding.gtfo-api")]
- [BepInPlugin("org.bepinex.plugins.zombified-initiative", "Zombified Initiative", "0.0.3.0")]
- public class ZombifiedInitiative : BasePlugin
- {
- public override void Load()
- {
- var initiative = AddComponent<Initiative>();
- EventAPI.OnExpeditionStarted += initiative.FindBots;
- EventAPI.OnExpeditionStarted += initiative.FindMenu;
- initiative.Log = Log;
- AddComponent<CustomMenu>();
- }
- private class Initiative : MonoBehaviour
- {
- private enum Bot
- {
- DAUDA,
- HACKETT,
- BISHOP
- }
- private Dictionary<Bot, string> botNameMapping = new Dictionary<Bot, string>
- {
- { Bot.DAUDA, "Dauda" },
- { Bot.HACKETT, "Hackett" },
- { Bot.BISHOP, "Bishop" }
- };
- public ManualLogSource Log;
- private Il2CppArrayBase<PlayerAIBot> _bots;
- private CustomMenu _customMenu;
- private PUI_CommunicationMenu _menu;
- private PUI_CommunicationButton _newMenuButton;
- private int _highlightedMenuButtonIndex = 0;
- private float _manualActionsPriority = 5f;
- private float _manualActionsHaste = 1f;
- private bool _preventAutoPickups = true;
- private bool _preventAutoUses = true;
- private bool _debug;
- private void Awake()
- {
- _bots = new Il2CppReferenceArray<PlayerAIBot>(0);
- }
- private void Start()
- {
- Print("Zombified Initiative has been added as component", true);
- _customMenu = GetComponent<CustomMenu>();
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.L))
- SwitchDebug();
- if (Input.GetKeyDown(KeyCode.P))
- PreventManualActions();
- if (Input.GetKeyDown(KeyCode.J))
- {
- _preventAutoPickups = !_preventAutoPickups;
- Print("Automatic resource pickups " + (_preventAutoPickups ? "disabled" : "enabled"));
- }
- if (Input.GetKeyDown(KeyCode.K))
- {
- _preventAutoUses = !_preventAutoUses;
- Print("Automatic resource uses " + (_preventAutoUses ? "disabled" : "enabled"));
- }
- if (_preventAutoPickups)
- PreventAutoResourcePickups();
- if (_preventAutoUses)
- PreventAutoResourceUses();
- if (Input.GetKey(KeyCode.Alpha8))
- SendBot(Bot.DAUDA);
- if (Input.GetKey(KeyCode.Alpha9))
- SendBot(Bot.HACKETT);
- if (Input.GetKey(KeyCode.Alpha0))
- SendBot(Bot.BISHOP);
- void SendBot(Bot bot)
- {
- if (Input.GetMouseButtonDown(2))
- {
- var monster = GetMonsterUnderPlayerAim();
- if (monster != null)
- {
- SendBotToKillEnemy(bot, monster,
- PlayerBotActionAttack.StanceEnum.All,
- PlayerBotActionAttack.AttackMeansEnum.All,
- PlayerBotActionWalk.Descriptor.PostureEnum.Stand);
- }
- }
- if (Input.GetKeyDown(KeyCode.U))
- {
- var item = GetItemUnderPlayerAim();
- if (item != null)
- SendBotToPickupItem(bot, item /*, true*/);
- }
- if (Input.GetKeyDown(KeyCode.I))
- SendBotToShareResourcePack(bot, GetHumanUnderPlayerAim());
- // if (Input.GetKeyDown(KeyCode.J))
- // MakeBotThrowResourcePack(bot, RaycastHits().First().point);
- }
- if (_menu != null && _menu.m_root.activeInHierarchy)
- _highlightedMenuButtonIndex = _menu.m_highlightedButtonIndex;
- }
- private void LateUpdate()
- {
- if (_menu == null || !_menu.m_root.activeInHierarchy)
- return;
- if (Input.GetKeyDown(KeyCode.Q))
- AddNewMenuButton();
- HandleMenuScroll();
- // Show custom menu when user selected the new "Zombified Initiative" menu button
- if (_highlightedMenuButtonIndex == 6 && (Input.GetMouseButtonDown(2) || Input.GetKeyDown(KeyCode.Alpha7)))
- _customMenu.Show(
- _bots.FirstOrDefault(bot => bot.Agent.PlayerName == "Dauda") != null,
- _bots.FirstOrDefault(bot => bot.Agent.PlayerName == "Haskett") != null,
- _bots.FirstOrDefault(bot => bot.Agent.PlayerName == "Bishop") != null);
- if (Input.GetKeyUp(KeyCode.Q))
- RemoveNewSubMenuButton();
- }
- public void FindBots()
- {
- _bots = FindObjectsOfType<PlayerAIBot>();
- Print("Found bots");
- }
- public void FindMenu()
- {
- _menu = FindObjectOfType<PUI_CommunicationMenu>();
- Print("Found menu");
- }
- private void AddNewMenuButton()
- {
- _newMenuButton = Instantiate(_menu.m_buttonPrefab, _menu.m_root.transform)
- .GetComponent<PUI_CommunicationButton>();
- _newMenuButton.transform.localPosition = new Vector3(-50f, -360f);
- _newMenuButton.transform.SetSiblingIndex(6);
- _menu.SetupButton(
- 6,
- _newMenuButton,
- new CommunicationNode(0, CommunicationNode.ScriptType.None),
- "Zombified Initiative",
- 0,
- 0,
- FindObjectOfType<LocalPlayerAgent>(),
- null,
- null
- );
- _menu.m_buttons.Insert(6, _newMenuButton);
- }
- private void HandleMenuScroll()
- {
- var scrollWheelDelta = Input.mouseScrollDelta.y;
- if (_highlightedMenuButtonIndex == 5 && scrollWheelDelta < 0)
- {
- _menu.SetHighlight(6);
- }
- else if (_highlightedMenuButtonIndex == 6 && scrollWheelDelta < 0)
- {
- _menu.SetHighlight(0);
- }
- else if (_highlightedMenuButtonIndex == 0 && scrollWheelDelta > 0)
- {
- _menu.SetHighlight(6);
- }
- else if (_highlightedMenuButtonIndex == 6 && scrollWheelDelta > 0)
- {
- _menu.SetHighlight(5);
- }
- }
- private void RemoveNewSubMenuButton()
- {
- _menu.m_buttons.Remove(_newMenuButton);
- Destroy(_newMenuButton.gameObject);
- }
- #region Preventions
- private void PreventManualActions()
- {
- var actionsToRemove = new List<PlayerBotActionBase>();
- var haste = _manualActionsHaste - 0.01f;
- foreach (var bot in _bots)
- {
- foreach (var action in bot.Actions)
- {
- if (action.GetIl2CppType().Name == "PlayerBotActionAttack")
- {
- var descriptor = action.DescBase.Cast<PlayerBotActionAttack.Descriptor>();
- if (descriptor.Haste > haste)
- {
- actionsToRemove.Add(action);
- continue;
- }
- }
- if (action.GetIl2CppType().Name == "PlayerBotActionCollectItem")
- {
- var descriptor = action.DescBase.Cast<PlayerBotActionCollectItem.Descriptor>();
- if (descriptor.Haste > haste)
- {
- actionsToRemove.Add(action);
- continue;
- }
- }
- if (action.GetIl2CppType().Name == "PlayerBotActionShareResourcePack")
- {
- var descriptor = action.DescBase.Cast<PlayerBotActionShareResourcePack.Descriptor>();
- if (descriptor.Haste > haste)
- {
- actionsToRemove.Add(action);
- continue;
- }
- }
- }
- foreach (var action in actionsToRemove)
- {
- // bot.Actions.Remove(action); // Queued stop
- bot.StopAction(action.DescBase); // Instant stop
- Print(bot.Agent.PlayerName + "'s manual actions were cancelled");
- }
- actionsToRemove.Clear();
- }
- }
- private void PreventAutoResourcePickups()
- {
- var actionsToRemove = new List<PlayerBotActionBase>();
- foreach (var bot in _bots)
- {
- foreach (var action in bot.Actions)
- {
- if (action.GetIl2CppType().Name != "PlayerBotActionCollectItem")
- continue;
- var descriptor = action.DescBase.Cast<PlayerBotActionCollectItem.Descriptor>();
- // TODO Find out what desinfection resource pack is really called, the name below is a guess
- var itemIsDesinfectionPack = descriptor.TargetItem.PublicName == "Desinfection Pack";
- var itemIsMediPack = descriptor.TargetItem.PublicName == "MediPack";
- var itemIsAmmoPack = descriptor.TargetItem.PublicName == "Ammo Pack";
- var itemIsToolRefillPack = descriptor.TargetItem.PublicName == "Tool Refill Pack";
- var itemIsPack = itemIsToolRefillPack || itemIsAmmoPack || itemIsMediPack || itemIsDesinfectionPack;
- if (descriptor.Haste < _manualActionsHaste && itemIsPack)
- actionsToRemove.Add(action);
- }
- foreach (var action in actionsToRemove)
- {
- bot.Actions.Remove(action); // Queued stop
- // bot.StopAction(action.DescBase); // Instant stop
- Print("Prevented " + bot.Agent.PlayerName + " from resource pickup");
- }
- actionsToRemove.Clear();
- }
- }
- private void PreventAutoResourceUses()
- {
- var actionsToRemove = new List<PlayerBotActionBase>();
- foreach (var bot in _bots)
- {
- foreach (var action in bot.Actions)
- {
- if (action.GetIl2CppType().Name != "PlayerBotActionShareResourcePack")
- continue;
- var descriptor = action.DescBase.Cast<PlayerBotActionShareResourcePack.Descriptor>();
- if (descriptor.Haste < _manualActionsHaste)
- {
- actionsToRemove.Add(action);
- }
- }
- foreach (var action in actionsToRemove)
- {
- bot.Actions.Remove(action); // Queued stop
- // bot.StopAction(action.DescBase); // Instant stop
- Print("Prevented " + bot.Agent.PlayerName + " from sharing resource pack");
- }
- actionsToRemove.Clear();
- }
- }
- #endregion
- #region Attack monster
- private EnemyAgent GetMonsterUnderPlayerAim()
- {
- return GetComponentUnderPlayerAim<EnemyAgent>
- (enemy => "Found monster: " + enemy.EnemyData.name, false);
- }
- private void SendBotToKillEnemy(Bot chosenBot, Agent enemy,
- PlayerBotActionAttack.StanceEnum stance,
- PlayerBotActionAttack.AttackMeansEnum means,
- PlayerBotActionWalk.Descriptor.PostureEnum posture)
- {
- var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
- if (bot == null)
- return;
- ExecuteBotAction(bot, new PlayerBotActionAttack.Descriptor(bot)
- {
- // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
- // Bot = bot,
- Stance = stance,
- Means = means,
- Posture = posture,
- TargetAgent = enemy,
- Prio = _manualActionsPriority,
- Haste = _manualActionsHaste,
- },
- "Added kill enemy action to " + bot.Agent.PlayerName);
- }
- #endregion
- #region Item pickup
- private ItemInLevel GetItemUnderPlayerAim()
- {
- return GetComponentUnderPlayerAim<ItemInLevel>
- (item => "Found item: " + item.PublicName);
- }
- private void SendBotToPickupItem(Bot chosenBot, ItemInLevel item /*, bool resourcePack = false*/)
- {
- var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
- if (bot == null)
- return;
- // if (resourcePack)
- // if (item.GetIl2CppType().Name != "Interact_Pickup_PickupItem")
- // return;
- ExecuteBotAction(bot, new PlayerBotActionCollectItem.Descriptor(bot)
- {
- // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
- // Bot = bot,
- TargetItem = item,
- TargetContainer = item.container,
- TargetPosition = item.transform.position,
- Prio = _manualActionsPriority,
- Haste = _manualActionsHaste,
- },
- "Added collect item action to " + bot.Agent.PlayerName);
- }
- #endregion
- #region Resource pack sharing
- private PlayerAgent GetHumanUnderPlayerAim()
- {
- var playerAIBot = GetComponentUnderPlayerAim<PlayerAIBot>
- (bot => "Found bot: " + bot.Agent.PlayerName);
- if (playerAIBot != null)
- return playerAIBot.Agent;
- var otherPlayerAgent = GetComponentUnderPlayerAim<PlayerAgent>
- (player => "Found other player: " + player.PlayerName);
- if (otherPlayerAgent != null)
- return otherPlayerAgent;
- var localPlayerAgent = FindObjectOfType<LocalPlayerAgent>().Cast<PlayerAgent>();
- Print("Found local player: " + localPlayerAgent.PlayerName);
- return localPlayerAgent;
- }
- private void SendBotToShareResourcePack(Bot chosenBot, PlayerAgent human)
- {
- var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
- if (bot == null)
- return;
- BackpackItem backpackItem = null;
- var gotBackpackItem = bot.Backpack.HasBackpackItem(InventorySlot.ResourcePack) &&
- bot.Backpack.TryGetBackpackItem(InventorySlot.ResourcePack, out backpackItem);
- if (!gotBackpackItem)
- return;
- var resourcePack = backpackItem.Instance.Cast<ItemEquippable>();
- bot.Inventory.DoEquipItem(resourcePack);
- ExecuteBotAction(bot, new PlayerBotActionShareResourcePack.Descriptor(bot)
- {
- // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
- // Bot = bot,
- Receiver = human,
- Item = resourcePack,
- Prio = _manualActionsPriority,
- Haste = _manualActionsHaste,
- },
- "Added share resource action to " + bot.Agent.PlayerName);
- }
- #endregion
- /*private void MakeBotThrowResourcePack(Bot chosenBot, Vector3 targetPosition)
- {
- var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
- if (bot == null)
- return;
- BackpackItem backpackItem = null;
- var gotBackpackItem = bot.Backpack.HasBackpackItem(InventorySlot.ResourcePack) &&
- bot.Backpack.TryGetBackpackItem(InventorySlot.ResourcePack, out backpackItem);
- if (!gotBackpackItem)
- return;
- var resourcePack = backpackItem.Instance.Cast<ItemEquippable>();
- bot.Inventory.DoEquipItem(resourcePack);
- ExecuteBotAction(bot, new PlayerBotActionThrowItem.Descriptor(bot)
- {
- // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
- // Bot = bot,
- TargetPosition = targetPosition,
- Item = resourcePack,
- Prio = _manualActionsPriority,
- Haste = _manualActionsHaste,
- },
- "Added throw resource pack to " + bot.Agent.PlayerName);
- }*/
- /*private SentryGunInstance GetSentryUnderPlayerAim()
- {
- var sentryGun = GetObjectUnderPlayerAim<SentryGunInstance>
- (sentryGun => "Found sentry gun: " + sentryGun.PublicName);
- if (sentryGun != null)
- return sentryGun;
- return null;
- }*/
- private void ExecuteBotAction(PlayerAIBot bot, PlayerBotActionBase.Descriptor descriptor, string message)
- {
- // bot.Actions.Add(new PlayerBotActionBase(descriptor));
- // bot.StartQueuedActions();
- // bot.UpdateActions();
- bot.StartAction(descriptor);
- Print(message);
- }
- private T GetComponentUnderPlayerAim<T>(System.Func<T, string> message, bool raycastAll = true) where T : class
- {
- if (raycastAll)
- {
- foreach (var raycastHit in RaycastHits())
- {
- var component = raycastHit.collider.GetComponentInParent<T>();
- if (component == null)
- continue;
- Print(message(component));
- return component;
- }
- }
- else
- {
- var raycastHit = RaycastHit();
- if (raycastHit.HasValue)
- {
- var component = raycastHit.Value.collider.GetComponentInParent<T>();
- if (component == null)
- return null;
- Print(message(component));
- return component;
- }
- }
- return null;
- }
- private RaycastHit? RaycastHit()
- {
- if (Physics.Raycast(Camera.current.ScreenPointToRay(Input.mousePosition), out var hitInfo))
- return hitInfo;
- return null;
- }
- private Il2CppStructArray<RaycastHit> RaycastHits()
- {
- return Physics.RaycastAll(Camera.current.ScreenPointToRay(Input.mousePosition));
- }
- private void SwitchDebug()
- {
- _debug = !_debug;
- Print("Debug log " + (_debug ? "enabled" : "disabled"), true);
- }
- private void Print(string text, bool forced = false)
- {
- if (_debug || forced)
- Log.LogInfo(text);
- }
- }
- private class CustomMenu : MonoBehaviour
- {
- private Initiative _initiative;
- private bool _isDaudaAround;
- private bool _isHaskettAround;
- private bool _isBishopAround;
- private bool _show;
- private void Start()
- {
- _initiative = GetComponent<Initiative>();
- }
- private void OnGUI()
- {
- if (!_show)
- return;
- Cursor.visible = true;
- Cursor.lockState = CursorLockMode.None;
- if (_isDaudaAround && GUILayout.Button("Dauda"))
- {
- Cursor.visible = false;
- Cursor.lockState = CursorLockMode.Locked;
- _initiative.Log.LogDebug("Selected Dauda");
- _show = false;
- }
- if (_isHaskettAround && GUILayout.Button("Haskett"))
- {
- Cursor.visible = false;
- Cursor.lockState = CursorLockMode.Locked;
- _initiative.Log.LogDebug("Selected Haskett");
- _show = false;
- }
- if (_isBishopAround && GUILayout.Button("Bishop"))
- {
- Cursor.visible = false;
- Cursor.lockState = CursorLockMode.Locked;
- _initiative.Log.LogDebug("Selected Bishop");
- _show = false;
- }
- }
- public void Show(bool isDaudaAround, bool isHaskettAround, bool isBishopAround)
- {
- _isDaudaAround = isDaudaAround;
- _isHaskettAround = isHaskettAround;
- _isBishopAround = isBishopAround;
- _show = true;
- }
- }
- }
Add Comment
Please, Sign In to add comment