mirror of
https://github.com/sp-tarkov/modules.git
synced 2025-02-13 09:50:43 -05:00
Refactor LighthouseProgressionClass + adjust lightkeeper standing to -0.01 when player becomes hostile with Zryachiy/followers
This commit is contained in:
parent
8b4847714c
commit
aa9a1af8c4
@ -10,142 +10,189 @@ namespace Aki.SinglePlayer.Models.Progression
|
||||
{
|
||||
private bool _isScav;
|
||||
private GameWorld _gameWorld;
|
||||
private Player _player;
|
||||
private float _timer;
|
||||
private bool _addedToEnemy;
|
||||
private List<MineDirectionalColliders> _mines;
|
||||
private bool _playerFlaggedAsEnemyToBosses;
|
||||
private List<MineDirectionalColliders> _bridgeMines;
|
||||
private RecodableItemClass _transmitter;
|
||||
private List<IAIDetails> _bosses;
|
||||
private List<IAIDetails> _zryachiyAndFollowers = new List<IAIDetails>();
|
||||
private bool _aggressor;
|
||||
private bool _disabledDoor;
|
||||
private bool _isDoorDisabled;
|
||||
private readonly string _transmitterId = "62e910aaf957f2915e0a5e36";
|
||||
private readonly string _lightKeeperTid = "638f541a29ffd1183d187f57";
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_gameWorld = Singleton<GameWorld>.Instance;
|
||||
_bosses = new List<IAIDetails>();
|
||||
_mines = GameObject.FindObjectsOfType<MineDirectionalColliders>().ToList();
|
||||
_player = _gameWorld?.MainPlayer;
|
||||
|
||||
if (_gameWorld == null || !string.Equals(_gameWorld.MainPlayer.Location, "lighthouse", System.StringComparison.OrdinalIgnoreCase))
|
||||
// Exit if not on lighthouse
|
||||
if (_gameWorld == null || !string.Equals(_player.Location, "lighthouse", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if player is a scav, there is no need to continue this method.
|
||||
if (_gameWorld.MainPlayer.Side == EPlayerSide.Savage)
|
||||
// Expensive, run after gameworld / lighthouse checks above
|
||||
_bridgeMines = FindObjectsOfType<MineDirectionalColliders>().ToList();
|
||||
|
||||
// Player is a scav, exit
|
||||
if (_player.Side == EPlayerSide.Savage)
|
||||
{
|
||||
_isScav = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the players Transmitter.
|
||||
_transmitter = (RecodableItemClass) _gameWorld.MainPlayer.Profile.Inventory.AllRealPlayerItems.FirstOrDefault(x => x.TemplateId == _transmitterId);
|
||||
|
||||
if (_transmitter != null)
|
||||
_transmitter = GetTransmitterFromInventory();
|
||||
if (PlayerHasTransmitterInInventory())
|
||||
{
|
||||
GameObject.Find("Attack").SetActive(false);
|
||||
|
||||
// this zone was added in a newer version and the gameObject actually has a \
|
||||
// Zone was added in a newer version and the gameObject actually has a \
|
||||
GameObject.Find("CloseZone\\").SetActive(false);
|
||||
|
||||
// Give access to the Lightkeepers door.
|
||||
_gameWorld.BufferZoneController.SetPlayerAccessStatus(_gameWorld.MainPlayer.ProfileId, true);
|
||||
// Give access to Lightkeepers door
|
||||
_gameWorld.BufferZoneController.SetPlayerAccessStatus(_player.ProfileId, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (_gameWorld == null || _addedToEnemy || _disabledDoor || _transmitter == null) return;
|
||||
|
||||
_timer += Time.deltaTime;
|
||||
IncrementLastUpdateTimer();
|
||||
|
||||
// Exit early if last update() run time was < 10 secs ago
|
||||
if (_timer < 10f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_bosses.Count == 0)
|
||||
// Skip if:
|
||||
// GameWorld missing
|
||||
// Player not an enemy to Zryachiy
|
||||
// Lk door not accessible
|
||||
// Player has no transmitter on thier person
|
||||
if (_gameWorld == null || _playerFlaggedAsEnemyToBosses || _isDoorDisabled || _transmitter == null)
|
||||
{
|
||||
SetupBosses();
|
||||
return;
|
||||
}
|
||||
|
||||
// Find Zryachiy and prep him
|
||||
if (_zryachiyAndFollowers.Count == 0)
|
||||
{
|
||||
SetupZryachiyAndFollowerHostility();
|
||||
}
|
||||
|
||||
if (_isScav)
|
||||
{
|
||||
PlayerIsScav();
|
||||
MakeZryachiyAndFollowersHostileToPlayer();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_gameWorld?.MainPlayer?.HandsController?.Item?.TemplateId == _transmitterId)
|
||||
// (active/green)
|
||||
if (PlayerHasActiveTransmitterInHands())
|
||||
{
|
||||
if (_transmitter?.RecodableComponent?.Status == RadioTransmitterStatus.Green)
|
||||
{
|
||||
foreach (var mine in _mines)
|
||||
{
|
||||
if (mine.gameObject.activeSelf)
|
||||
{
|
||||
mine.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
SetBridgeMinesStatus(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var mine in _mines)
|
||||
{
|
||||
if (!mine.gameObject.activeSelf)
|
||||
{
|
||||
mine.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
SetBridgeMinesStatus(true);
|
||||
}
|
||||
|
||||
if (_aggressor)
|
||||
{
|
||||
PlayerIsAggressor();
|
||||
DisableAccessToLightKeeper();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupBosses()
|
||||
private RecodableItemClass GetTransmitterFromInventory()
|
||||
{
|
||||
foreach (var aiBot in _gameWorld.AllAlivePlayersList)
|
||||
{
|
||||
if (!aiBot.IsYourPlayer)
|
||||
{
|
||||
// Edge case of bossZryachiy not being hostile to player
|
||||
if (aiBot.AIData.BotOwner.IsRole(WildSpawnType.bossZryachiy) || aiBot.AIData.BotOwner.IsRole(WildSpawnType.followerZryachiy))
|
||||
{
|
||||
// Subscribe to Bosses OnDeath event
|
||||
aiBot.OnPlayerDeadOrUnspawn += player1 =>
|
||||
{
|
||||
if (player1?.KillerId == _gameWorld.MainPlayer.ProfileId)
|
||||
{
|
||||
_aggressor = true;
|
||||
}
|
||||
};
|
||||
return (RecodableItemClass)_player.Profile.Inventory.AllRealPlayerItems.FirstOrDefault(x => x.TemplateId == _transmitterId);
|
||||
}
|
||||
|
||||
_bosses.Add(aiBot);
|
||||
}
|
||||
private bool PlayerHasTransmitterInInventory()
|
||||
{
|
||||
return _transmitter != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update _time to diff from last run of update()
|
||||
/// </summary>
|
||||
private void IncrementLastUpdateTimer()
|
||||
{
|
||||
_timer += Time.deltaTime;
|
||||
}
|
||||
|
||||
private bool PlayerHasActiveTransmitterInHands()
|
||||
{
|
||||
return _gameWorld?.MainPlayer?.HandsController?.Item?.TemplateId == _transmitterId
|
||||
&& _transmitter?.RecodableComponent?.Status == RadioTransmitterStatus.Green;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set all brdige mines to desire state
|
||||
/// </summary>
|
||||
/// <param name="active">What state mines should be</param>
|
||||
private void SetBridgeMinesStatus(bool active)
|
||||
{
|
||||
// Find mines with opposite state of what we want
|
||||
foreach (var mine in _bridgeMines.Where(mine => mine.gameObject.activeSelf == !active))
|
||||
{
|
||||
mine.gameObject.SetActive(active);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupZryachiyAndFollowerHostility()
|
||||
{
|
||||
// only process non-players (ai)
|
||||
foreach (var aiBot in _gameWorld.AllAlivePlayersList.Where(x => !x.IsYourPlayer))
|
||||
{
|
||||
// Edge case of bossZryachiy not being hostile to player
|
||||
if (aiBot.AIData.BotOwner.IsRole(WildSpawnType.bossZryachiy) || aiBot.AIData.BotOwner.IsRole(WildSpawnType.followerZryachiy))
|
||||
{
|
||||
// Subscribe to bots OnDeath event
|
||||
aiBot.OnPlayerDeadOrUnspawn += player1 =>
|
||||
{
|
||||
// If player kills zryachiy or follower, force aggressor state
|
||||
// Also set players Lk standing to negative (allows access to quest chain (Making Amends))
|
||||
if (player1?.KillerId == _player.ProfileId)
|
||||
{
|
||||
_aggressor = true;
|
||||
_player.Profile.TradersInfo[_lightKeeperTid].SetStanding(-0.01);
|
||||
}
|
||||
};
|
||||
|
||||
// Save bot to list for later access
|
||||
_zryachiyAndFollowers.Add(aiBot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayerIsScav()
|
||||
/// <summary>
|
||||
/// Iterate over bots gathered from SetupZryachiyHostility()
|
||||
/// </summary>
|
||||
private void MakeZryachiyAndFollowersHostileToPlayer()
|
||||
{
|
||||
// If player is a scav, they must be added to the bosses enemy list otherwise they wont kill them
|
||||
foreach (var boss in _bosses)
|
||||
foreach (var bot in _zryachiyAndFollowers)
|
||||
{
|
||||
boss.AIData.BotOwner.BotsGroup.AddEnemy(_gameWorld.MainPlayer);
|
||||
bot.AIData.BotOwner.BotsGroup.AddEnemy(_player);
|
||||
}
|
||||
|
||||
_addedToEnemy = true;
|
||||
// Flag player was added to enemy list
|
||||
_playerFlaggedAsEnemyToBosses = true;
|
||||
}
|
||||
|
||||
private void PlayerIsAggressor()
|
||||
/// <summary>
|
||||
/// Disable door + set transmitter to 'red'
|
||||
/// </summary>
|
||||
private void DisableAccessToLightKeeper()
|
||||
{
|
||||
// Disable access to Lightkeepers door for the player
|
||||
_gameWorld.BufferZoneController.SetPlayerAccessStatus(_gameWorld.MainPlayer.ProfileId, false);
|
||||
_transmitter?.RecodableComponent?.SetStatus(RadioTransmitterStatus.Yellow);
|
||||
_transmitter?.RecodableComponent?.SetEncoded(false);
|
||||
_disabledDoor = true;
|
||||
_isDoorDisabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,10 @@ namespace Aki.SinglePlayer.Patches.Progression
|
||||
private static void PatchPostfix()
|
||||
{
|
||||
var gameWorld = Singleton<GameWorld>.Instance;
|
||||
|
||||
if (gameWorld == null || gameWorld.MainPlayer.Location.ToLower() != "lighthouse") return;
|
||||
if (gameWorld == null || gameWorld.MainPlayer.Location.ToLower() != "lighthouse")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gameWorld.GetOrAddComponent<LighthouseProgressionClass>();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user