Guest User

Zombified Initiative

a guest
Aug 16th, 2023
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 21.49 KB | Gaming | 0 0
  1. namespace ZombifiedInitiative;
  2.  
  3. using Il2CppInterop.Runtime.InteropTypes.Arrays;
  4. using UnityEngine;
  5. using BepInEx;
  6. using BepInEx.Logging;
  7. using BepInEx.Unity.IL2CPP;
  8. using GTFO.API;
  9. using LevelGeneration;
  10. using Agents;
  11. using Player;
  12. using Enemies;
  13.  
  14. [BepInDependency("dev.gtfomodding.gtfo-api")]
  15. [BepInPlugin("org.bepinex.plugins.zombified-initiative", "Zombified Initiative", "0.0.3.0")]
  16. public class ZombifiedInitiative : BasePlugin
  17. {
  18.     public override void Load()
  19.     {
  20.         var initiative = AddComponent<Initiative>();
  21.         EventAPI.OnExpeditionStarted += initiative.FindBots;
  22.         EventAPI.OnExpeditionStarted += initiative.FindMenu;
  23.         initiative.Log = Log;
  24.  
  25.         AddComponent<CustomMenu>();
  26.     }
  27.  
  28.  
  29.     private class Initiative : MonoBehaviour
  30.     {
  31.         private enum Bot
  32.         {
  33.             DAUDA,
  34.             HACKETT,
  35.             BISHOP
  36.         }
  37.  
  38.         private Dictionary<Bot, string> botNameMapping = new Dictionary<Bot, string>
  39.         {
  40.             { Bot.DAUDA, "Dauda" },
  41.             { Bot.HACKETT, "Hackett" },
  42.             { Bot.BISHOP, "Bishop" }
  43.         };
  44.  
  45.         public ManualLogSource Log;
  46.         private Il2CppArrayBase<PlayerAIBot> _bots;
  47.         private CustomMenu _customMenu;
  48.         private PUI_CommunicationMenu _menu;
  49.         private PUI_CommunicationButton _newMenuButton;
  50.         private int _highlightedMenuButtonIndex = 0;
  51.         private float _manualActionsPriority = 5f;
  52.         private float _manualActionsHaste = 1f;
  53.         private bool _preventAutoPickups = true;
  54.         private bool _preventAutoUses = true;
  55.         private bool _debug;
  56.  
  57.  
  58.         private void Awake()
  59.         {
  60.             _bots = new Il2CppReferenceArray<PlayerAIBot>(0);
  61.         }
  62.  
  63.  
  64.         private void Start()
  65.         {
  66.             Print("Zombified Initiative has been added as component", true);
  67.             _customMenu = GetComponent<CustomMenu>();
  68.         }
  69.  
  70.  
  71.         private void Update()
  72.         {
  73.             if (Input.GetKeyDown(KeyCode.L))
  74.                 SwitchDebug();
  75.  
  76.             if (Input.GetKeyDown(KeyCode.P))
  77.                 PreventManualActions();
  78.  
  79.             if (Input.GetKeyDown(KeyCode.J))
  80.             {
  81.                 _preventAutoPickups = !_preventAutoPickups;
  82.                 Print("Automatic resource pickups " + (_preventAutoPickups ? "disabled" : "enabled"));
  83.             }
  84.  
  85.             if (Input.GetKeyDown(KeyCode.K))
  86.             {
  87.                 _preventAutoUses = !_preventAutoUses;
  88.                 Print("Automatic resource uses " + (_preventAutoUses ? "disabled" : "enabled"));
  89.             }
  90.  
  91.             if (_preventAutoPickups)
  92.                 PreventAutoResourcePickups();
  93.  
  94.             if (_preventAutoUses)
  95.                 PreventAutoResourceUses();
  96.  
  97.             if (Input.GetKey(KeyCode.Alpha8))
  98.                 SendBot(Bot.DAUDA);
  99.  
  100.             if (Input.GetKey(KeyCode.Alpha9))
  101.                 SendBot(Bot.HACKETT);
  102.  
  103.             if (Input.GetKey(KeyCode.Alpha0))
  104.                 SendBot(Bot.BISHOP);
  105.  
  106.             void SendBot(Bot bot)
  107.             {
  108.                 if (Input.GetMouseButtonDown(2))
  109.                 {
  110.                     var monster = GetMonsterUnderPlayerAim();
  111.                     if (monster != null)
  112.                     {
  113.                         SendBotToKillEnemy(bot, monster,
  114.                             PlayerBotActionAttack.StanceEnum.All,
  115.                             PlayerBotActionAttack.AttackMeansEnum.All,
  116.                             PlayerBotActionWalk.Descriptor.PostureEnum.Stand);
  117.                     }
  118.                 }
  119.  
  120.                 if (Input.GetKeyDown(KeyCode.U))
  121.                 {
  122.                     var item = GetItemUnderPlayerAim();
  123.                     if (item != null)
  124.                         SendBotToPickupItem(bot, item /*, true*/);
  125.                 }
  126.  
  127.                 if (Input.GetKeyDown(KeyCode.I))
  128.                     SendBotToShareResourcePack(bot, GetHumanUnderPlayerAim());
  129.  
  130.                 // if (Input.GetKeyDown(KeyCode.J))
  131.                 //     MakeBotThrowResourcePack(bot, RaycastHits().First().point);
  132.             }
  133.  
  134.             if (_menu != null && _menu.m_root.activeInHierarchy)
  135.                 _highlightedMenuButtonIndex = _menu.m_highlightedButtonIndex;
  136.         }
  137.  
  138.  
  139.         private void LateUpdate()
  140.         {
  141.             if (_menu == null || !_menu.m_root.activeInHierarchy)
  142.                 return;
  143.  
  144.             if (Input.GetKeyDown(KeyCode.Q))
  145.                 AddNewMenuButton();
  146.  
  147.             HandleMenuScroll();
  148.  
  149.             // Show custom menu when user selected the new "Zombified Initiative" menu button
  150.             if (_highlightedMenuButtonIndex == 6 && (Input.GetMouseButtonDown(2) || Input.GetKeyDown(KeyCode.Alpha7)))
  151.                 _customMenu.Show(
  152.                     _bots.FirstOrDefault(bot => bot.Agent.PlayerName == "Dauda") != null,
  153.                     _bots.FirstOrDefault(bot => bot.Agent.PlayerName == "Haskett") != null,
  154.                     _bots.FirstOrDefault(bot => bot.Agent.PlayerName == "Bishop") != null);
  155.  
  156.             if (Input.GetKeyUp(KeyCode.Q))
  157.                 RemoveNewSubMenuButton();
  158.         }
  159.  
  160.  
  161.         public void FindBots()
  162.         {
  163.             _bots = FindObjectsOfType<PlayerAIBot>();
  164.             Print("Found bots");
  165.         }
  166.  
  167.  
  168.         public void FindMenu()
  169.         {
  170.             _menu = FindObjectOfType<PUI_CommunicationMenu>();
  171.             Print("Found menu");
  172.         }
  173.  
  174.  
  175.         private void AddNewMenuButton()
  176.         {
  177.             _newMenuButton = Instantiate(_menu.m_buttonPrefab, _menu.m_root.transform)
  178.                 .GetComponent<PUI_CommunicationButton>();
  179.             _newMenuButton.transform.localPosition = new Vector3(-50f, -360f);
  180.             _newMenuButton.transform.SetSiblingIndex(6);
  181.  
  182.             _menu.SetupButton(
  183.                 6,
  184.                 _newMenuButton,
  185.                 new CommunicationNode(0, CommunicationNode.ScriptType.None),
  186.                 "Zombified Initiative",
  187.                 0,
  188.                 0,
  189.                 FindObjectOfType<LocalPlayerAgent>(),
  190.                 null,
  191.                 null
  192.             );
  193.  
  194.             _menu.m_buttons.Insert(6, _newMenuButton);
  195.         }
  196.  
  197.  
  198.         private void HandleMenuScroll()
  199.         {
  200.             var scrollWheelDelta = Input.mouseScrollDelta.y;
  201.             if (_highlightedMenuButtonIndex == 5 && scrollWheelDelta < 0)
  202.             {
  203.                 _menu.SetHighlight(6);
  204.             }
  205.             else if (_highlightedMenuButtonIndex == 6 && scrollWheelDelta < 0)
  206.             {
  207.                 _menu.SetHighlight(0);
  208.             }
  209.             else if (_highlightedMenuButtonIndex == 0 && scrollWheelDelta > 0)
  210.             {
  211.                 _menu.SetHighlight(6);
  212.             }
  213.             else if (_highlightedMenuButtonIndex == 6 && scrollWheelDelta > 0)
  214.             {
  215.                 _menu.SetHighlight(5);
  216.             }
  217.         }
  218.  
  219.  
  220.         private void RemoveNewSubMenuButton()
  221.         {
  222.             _menu.m_buttons.Remove(_newMenuButton);
  223.             Destroy(_newMenuButton.gameObject);
  224.         }
  225.  
  226.  
  227.         #region Preventions
  228.         private void PreventManualActions()
  229.         {
  230.             var actionsToRemove = new List<PlayerBotActionBase>();
  231.             var haste = _manualActionsHaste - 0.01f;
  232.  
  233.             foreach (var bot in _bots)
  234.             {
  235.                 foreach (var action in bot.Actions)
  236.                 {
  237.                     if (action.GetIl2CppType().Name == "PlayerBotActionAttack")
  238.                     {
  239.                         var descriptor = action.DescBase.Cast<PlayerBotActionAttack.Descriptor>();
  240.                         if (descriptor.Haste > haste)
  241.                         {
  242.                             actionsToRemove.Add(action);
  243.                             continue;
  244.                         }
  245.                     }
  246.  
  247.                     if (action.GetIl2CppType().Name == "PlayerBotActionCollectItem")
  248.                     {
  249.                         var descriptor = action.DescBase.Cast<PlayerBotActionCollectItem.Descriptor>();
  250.                         if (descriptor.Haste > haste)
  251.                         {
  252.                             actionsToRemove.Add(action);
  253.                             continue;
  254.                         }
  255.                     }
  256.  
  257.                     if (action.GetIl2CppType().Name == "PlayerBotActionShareResourcePack")
  258.                     {
  259.                         var descriptor = action.DescBase.Cast<PlayerBotActionShareResourcePack.Descriptor>();
  260.                         if (descriptor.Haste > haste)
  261.                         {
  262.                             actionsToRemove.Add(action);
  263.                             continue;
  264.                         }
  265.                     }
  266.                 }
  267.  
  268.                 foreach (var action in actionsToRemove)
  269.                 {
  270.                     // bot.Actions.Remove(action); // Queued stop
  271.                     bot.StopAction(action.DescBase); // Instant stop
  272.                     Print(bot.Agent.PlayerName + "'s manual actions were cancelled");
  273.                 }
  274.  
  275.                 actionsToRemove.Clear();
  276.             }
  277.         }
  278.  
  279.  
  280.         private void PreventAutoResourcePickups()
  281.         {
  282.             var actionsToRemove = new List<PlayerBotActionBase>();
  283.  
  284.             foreach (var bot in _bots)
  285.             {
  286.                 foreach (var action in bot.Actions)
  287.                 {
  288.                     if (action.GetIl2CppType().Name != "PlayerBotActionCollectItem")
  289.                         continue;
  290.  
  291.                     var descriptor = action.DescBase.Cast<PlayerBotActionCollectItem.Descriptor>();
  292.  
  293.                     // TODO Find out what desinfection resource pack is really called, the name below is a guess
  294.                     var itemIsDesinfectionPack = descriptor.TargetItem.PublicName == "Desinfection Pack";
  295.                     var itemIsMediPack = descriptor.TargetItem.PublicName == "MediPack";
  296.                     var itemIsAmmoPack = descriptor.TargetItem.PublicName == "Ammo Pack";
  297.                     var itemIsToolRefillPack = descriptor.TargetItem.PublicName == "Tool Refill Pack";
  298.  
  299.                     var itemIsPack = itemIsToolRefillPack || itemIsAmmoPack || itemIsMediPack || itemIsDesinfectionPack;
  300.                     if (descriptor.Haste < _manualActionsHaste && itemIsPack)
  301.                         actionsToRemove.Add(action);
  302.                 }
  303.  
  304.                 foreach (var action in actionsToRemove)
  305.                 {
  306.                     bot.Actions.Remove(action); // Queued stop
  307.                     // bot.StopAction(action.DescBase); // Instant stop
  308.                     Print("Prevented " + bot.Agent.PlayerName + " from resource pickup");
  309.                 }
  310.  
  311.                 actionsToRemove.Clear();
  312.             }
  313.         }
  314.  
  315.  
  316.         private void PreventAutoResourceUses()
  317.         {
  318.             var actionsToRemove = new List<PlayerBotActionBase>();
  319.  
  320.             foreach (var bot in _bots)
  321.             {
  322.                 foreach (var action in bot.Actions)
  323.                 {
  324.                     if (action.GetIl2CppType().Name != "PlayerBotActionShareResourcePack")
  325.                         continue;
  326.  
  327.                     var descriptor = action.DescBase.Cast<PlayerBotActionShareResourcePack.Descriptor>();
  328.                     if (descriptor.Haste < _manualActionsHaste)
  329.                     {
  330.                         actionsToRemove.Add(action);
  331.                     }
  332.                 }
  333.  
  334.                 foreach (var action in actionsToRemove)
  335.                 {
  336.                     bot.Actions.Remove(action); // Queued stop
  337.                     // bot.StopAction(action.DescBase); // Instant stop
  338.                     Print("Prevented " + bot.Agent.PlayerName + " from sharing resource pack");
  339.                 }
  340.  
  341.                 actionsToRemove.Clear();
  342.             }
  343.         }
  344.         #endregion
  345.  
  346.  
  347.         #region Attack monster
  348.         private EnemyAgent GetMonsterUnderPlayerAim()
  349.         {
  350.             return GetComponentUnderPlayerAim<EnemyAgent>
  351.                 (enemy => "Found monster: " + enemy.EnemyData.name, false);
  352.         }
  353.  
  354.  
  355.         private void SendBotToKillEnemy(Bot chosenBot, Agent enemy,
  356.             PlayerBotActionAttack.StanceEnum stance,
  357.             PlayerBotActionAttack.AttackMeansEnum means,
  358.             PlayerBotActionWalk.Descriptor.PostureEnum posture)
  359.         {
  360.             var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
  361.             if (bot == null)
  362.                 return;
  363.  
  364.             ExecuteBotAction(bot, new PlayerBotActionAttack.Descriptor(bot)
  365.                 {
  366.                     // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
  367.                     // Bot = bot,
  368.                     Stance = stance,
  369.                     Means = means,
  370.                     Posture = posture,
  371.                     TargetAgent = enemy,
  372.                     Prio = _manualActionsPriority,
  373.                     Haste = _manualActionsHaste,
  374.                 },
  375.                 "Added kill enemy action to " + bot.Agent.PlayerName);
  376.         }
  377.         #endregion
  378.  
  379.  
  380.         #region Item pickup
  381.         private ItemInLevel GetItemUnderPlayerAim()
  382.         {
  383.             return GetComponentUnderPlayerAim<ItemInLevel>
  384.                 (item => "Found item: " + item.PublicName);
  385.         }
  386.  
  387.  
  388.         private void SendBotToPickupItem(Bot chosenBot, ItemInLevel item /*, bool resourcePack = false*/)
  389.         {
  390.             var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
  391.             if (bot == null)
  392.                 return;
  393.  
  394.             // if (resourcePack)
  395.             //     if (item.GetIl2CppType().Name != "Interact_Pickup_PickupItem")
  396.             //         return;
  397.  
  398.             ExecuteBotAction(bot, new PlayerBotActionCollectItem.Descriptor(bot)
  399.                 {
  400.                     // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
  401.                     // Bot = bot,
  402.                     TargetItem = item,
  403.                     TargetContainer = item.container,
  404.                     TargetPosition = item.transform.position,
  405.                     Prio = _manualActionsPriority,
  406.                     Haste = _manualActionsHaste,
  407.                 },
  408.                 "Added collect item action to " + bot.Agent.PlayerName);
  409.         }
  410.         #endregion
  411.  
  412.  
  413.         #region Resource pack sharing
  414.         private PlayerAgent GetHumanUnderPlayerAim()
  415.         {
  416.             var playerAIBot = GetComponentUnderPlayerAim<PlayerAIBot>
  417.                 (bot => "Found bot: " + bot.Agent.PlayerName);
  418.             if (playerAIBot != null)
  419.                 return playerAIBot.Agent;
  420.  
  421.             var otherPlayerAgent = GetComponentUnderPlayerAim<PlayerAgent>
  422.                 (player => "Found other player: " + player.PlayerName);
  423.             if (otherPlayerAgent != null)
  424.                 return otherPlayerAgent;
  425.  
  426.             var localPlayerAgent = FindObjectOfType<LocalPlayerAgent>().Cast<PlayerAgent>();
  427.             Print("Found local player: " + localPlayerAgent.PlayerName);
  428.             return localPlayerAgent;
  429.         }
  430.  
  431.  
  432.         private void SendBotToShareResourcePack(Bot chosenBot, PlayerAgent human)
  433.         {
  434.             var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
  435.             if (bot == null)
  436.                 return;
  437.  
  438.             BackpackItem backpackItem = null;
  439.             var gotBackpackItem = bot.Backpack.HasBackpackItem(InventorySlot.ResourcePack) &&
  440.                                   bot.Backpack.TryGetBackpackItem(InventorySlot.ResourcePack, out backpackItem);
  441.             if (!gotBackpackItem)
  442.                 return;
  443.  
  444.             var resourcePack = backpackItem.Instance.Cast<ItemEquippable>();
  445.             bot.Inventory.DoEquipItem(resourcePack);
  446.  
  447.             ExecuteBotAction(bot, new PlayerBotActionShareResourcePack.Descriptor(bot)
  448.                 {
  449.                     // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
  450.                     // Bot = bot,
  451.                     Receiver = human,
  452.                     Item = resourcePack,
  453.                     Prio = _manualActionsPriority,
  454.                     Haste = _manualActionsHaste,
  455.                 },
  456.                 "Added share resource action to " + bot.Agent.PlayerName);
  457.         }
  458.         #endregion
  459.  
  460.  
  461.         /*private void MakeBotThrowResourcePack(Bot chosenBot, Vector3 targetPosition)
  462.         {
  463.             var bot = _bots.First(bot => bot.Agent.PlayerName == botNameMapping[chosenBot]);
  464.             if (bot == null)
  465.                 return;
  466.  
  467.             BackpackItem backpackItem = null;
  468.             var gotBackpackItem = bot.Backpack.HasBackpackItem(InventorySlot.ResourcePack) &&
  469.                                   bot.Backpack.TryGetBackpackItem(InventorySlot.ResourcePack, out backpackItem);
  470.             if (!gotBackpackItem)
  471.                 return;
  472.  
  473.             var resourcePack = backpackItem.Instance.Cast<ItemEquippable>();
  474.             bot.Inventory.DoEquipItem(resourcePack);
  475.  
  476.             ExecuteBotAction(bot, new PlayerBotActionThrowItem.Descriptor(bot)
  477.                 {
  478.                     // Status = PlayerBotActionBase.Descriptor.StatusType.Active,
  479.                     // Bot = bot,
  480.                     TargetPosition = targetPosition,
  481.                     Item = resourcePack,
  482.                     Prio = _manualActionsPriority,
  483.                     Haste = _manualActionsHaste,
  484.                 },
  485.                 "Added throw resource pack to " + bot.Agent.PlayerName);
  486.         }*/
  487.  
  488.  
  489.         /*private SentryGunInstance GetSentryUnderPlayerAim()
  490.         {
  491.             var sentryGun = GetObjectUnderPlayerAim<SentryGunInstance>
  492.                 (sentryGun => "Found sentry gun: " + sentryGun.PublicName);
  493.             if (sentryGun != null)
  494.                 return sentryGun;
  495.             return null;
  496.         }*/
  497.  
  498.  
  499.         private void ExecuteBotAction(PlayerAIBot bot, PlayerBotActionBase.Descriptor descriptor, string message)
  500.         {
  501.             // bot.Actions.Add(new PlayerBotActionBase(descriptor));
  502.             // bot.StartQueuedActions();
  503.             // bot.UpdateActions();
  504.             bot.StartAction(descriptor);
  505.             Print(message);
  506.         }
  507.  
  508.  
  509.         private T GetComponentUnderPlayerAim<T>(System.Func<T, string> message, bool raycastAll = true) where T : class
  510.         {
  511.             if (raycastAll)
  512.             {
  513.                 foreach (var raycastHit in RaycastHits())
  514.                 {
  515.                     var component = raycastHit.collider.GetComponentInParent<T>();
  516.                     if (component == null)
  517.                         continue;
  518.  
  519.                     Print(message(component));
  520.                     return component;
  521.                 }
  522.             }
  523.             else
  524.             {
  525.                 var raycastHit = RaycastHit();
  526.                 if (raycastHit.HasValue)
  527.                 {
  528.                     var component = raycastHit.Value.collider.GetComponentInParent<T>();
  529.                     if (component == null)
  530.                         return null;
  531.  
  532.                     Print(message(component));
  533.                     return component;
  534.                 }
  535.             }
  536.  
  537.             return null;
  538.         }
  539.  
  540.  
  541.         private RaycastHit? RaycastHit()
  542.         {
  543.             if (Physics.Raycast(Camera.current.ScreenPointToRay(Input.mousePosition), out var hitInfo))
  544.                 return hitInfo;
  545.             return null;
  546.         }
  547.  
  548.  
  549.         private Il2CppStructArray<RaycastHit> RaycastHits()
  550.         {
  551.             return Physics.RaycastAll(Camera.current.ScreenPointToRay(Input.mousePosition));
  552.         }
  553.  
  554.  
  555.         private void SwitchDebug()
  556.         {
  557.             _debug = !_debug;
  558.             Print("Debug log " + (_debug ? "enabled" : "disabled"), true);
  559.         }
  560.  
  561.  
  562.         private void Print(string text, bool forced = false)
  563.         {
  564.             if (_debug || forced)
  565.                 Log.LogInfo(text);
  566.         }
  567.     }
  568.  
  569.  
  570.     private class CustomMenu : MonoBehaviour
  571.     {
  572.         private Initiative _initiative;
  573.         private bool _isDaudaAround;
  574.         private bool _isHaskettAround;
  575.         private bool _isBishopAround;
  576.         private bool _show;
  577.  
  578.  
  579.         private void Start()
  580.         {
  581.             _initiative = GetComponent<Initiative>();
  582.         }
  583.  
  584.  
  585.         private void OnGUI()
  586.         {
  587.             if (!_show)
  588.                 return;
  589.  
  590.             Cursor.visible = true;
  591.             Cursor.lockState = CursorLockMode.None;
  592.  
  593.             if (_isDaudaAround && GUILayout.Button("Dauda"))
  594.             {
  595.                 Cursor.visible = false;
  596.                 Cursor.lockState = CursorLockMode.Locked;
  597.                 _initiative.Log.LogDebug("Selected Dauda");
  598.                 _show = false;
  599.             }
  600.  
  601.             if (_isHaskettAround && GUILayout.Button("Haskett"))
  602.             {
  603.                 Cursor.visible = false;
  604.                 Cursor.lockState = CursorLockMode.Locked;
  605.                 _initiative.Log.LogDebug("Selected Haskett");
  606.                 _show = false;
  607.             }
  608.  
  609.             if (_isBishopAround && GUILayout.Button("Bishop"))
  610.             {
  611.                 Cursor.visible = false;
  612.                 Cursor.lockState = CursorLockMode.Locked;
  613.                 _initiative.Log.LogDebug("Selected Bishop");
  614.                 _show = false;
  615.             }
  616.         }
  617.  
  618.  
  619.         public void Show(bool isDaudaAround, bool isHaskettAround, bool isBishopAround)
  620.         {
  621.             _isDaudaAround = isDaudaAround;
  622.             _isHaskettAround = isHaskettAround;
  623.             _isBishopAround = isBishopAround;
  624.             _show = true;
  625.         }
  626.     }
  627. }
Add Comment
Please, Sign In to add comment