r2mods/ilspy_dump/ror2_csproj/RoR2/HalcyoniteShrineInteractabl...

631 lines
16 KiB
C#
Raw Permalink Normal View History

2024-10-04 07:26:37 +00:00
using System.Runtime.InteropServices;
using EntityStates;
using EntityStates.ShrineHalcyonite;
using UnityEngine;
using UnityEngine.Networking;
namespace RoR2;
public class HalcyoniteShrineInteractable : NetworkBehaviour
{
[Header("Shrine Core Variables")]
public bool HalcyoniteShrineActive = true;
[Tooltip("Flat max gold cost for accessing top quality. *Note, without difficulty cost scaling.")]
public int maxGoldCost = 300;
[Tooltip("Flat mid gold cost for accessing top quality. *Note, without difficulty cost scaling.")]
public int midGoldCost = 150;
[Tooltip("Minimum amount of gold required to activate boss fight and end drain. *Note, without difficulty cost scaling.")]
public int lowGoldCost = 75;
[Tooltip("True if shrine gold mechanic should increase with difficulty. False if it should not.")]
[SerializeField]
private bool automaticallyScaleCostWithDifficulty = true;
[SerializeField]
private GameObject shrineCollisionObject;
[Tooltip("Detection radius for picking up the players within range of the Halcyonite Shrine.")]
[Header("Draining Gold Variables")]
public float radius = 30f;
[Tooltip("Amount drained per tick.")]
public int goldDrainValue = 1;
[Tooltip("Total amount of gold stored in Shrine.")]
public int goldDrained;
[Min(float.Epsilon)]
[Tooltip("How many ticks per second.")]
public float tickRate = 5f;
[SyncVar]
[Tooltip("Maximum amount of player targets allowed.")]
public int maxTargets = 4;
[Tooltip("Game Object for the network game object responsible for draining the player's gold.")]
public GameObject siphonObject;
[SyncVar]
[HideInInspector]
public int interactions;
[SerializeField]
[Tooltip("Renderer reference for when changing target renderers for the highlight script.")]
private Renderer shrineRenderer;
[SyncVar]
public bool isDraining;
[SerializeField]
[Tooltip("Reference to the crystal object for changing its materials.")]
[Header("Gauge Mechanic")]
public GameObject crystalObject;
[SerializeField]
[SyncVar]
public GameObject shrineGoldBottom;
[SyncVar]
[SerializeField]
public GameObject shrineGoldMid;
[SerializeField]
[SyncVar]
public GameObject shrineGoldTop;
[SerializeField]
public Material goldMaterialController;
[Tooltip("Color of VFX and Crystal once the encounter is finished and reward has been dispersed.")]
[SerializeField]
public GameObject shrineBaseObject;
[Tooltip("Halcyonite Shrine bubble Game Object reference.")]
[SerializeField]
public GameObject shrineHalcyoniteBubble;
[Tooltip("Entity State Machine reference for handling changes to gauge mechanics for the network.")]
[SerializeField]
public EntityStateMachine stateMachine;
public SerializableEntityStateType noQualityState = new SerializableEntityStateType(typeof(ShrineHalcyoniteNoQuality));
public SerializableEntityStateType finishedState = new SerializableEntityStateType(typeof(ShrineHalcyoniteFinished));
public SfxLocator sfxLocator;
[SerializeField]
private PurchaseInteraction purchaseInteraction;
[SerializeField]
[Header("Shrine Encounter and Rewards")]
private DirectorCard chosenDirectCard;
[SerializeField]
[Tooltip("Drop table dictating what rewards are available at minimum gold value.")]
private BasicPickupDropTable halcyoniteDropTableTier1;
[SerializeField]
[Tooltip("Drop table dictating what rewards are available at middling gold value.")]
private BasicPickupDropTable halcyoniteDropTableTier2;
[SerializeField]
[Tooltip("Drop table dictating what rewards are available at maximum gold value.")]
private BasicPickupDropTable halcyoniteDropTableTier3;
[Tooltip("Use this tier to get a pickup index for the reward. The droplet's visuals will correspond to this.")]
[SerializeField]
private ItemTier rewardDisplayTier;
[SerializeField]
[Tooltip("The number of options to display when the player interacts with the reward pickup.")]
private int rewardOptionCount;
[SerializeField]
[Tooltip("The prefab to use for the reward pickup.")]
private GameObject rewardPickupPrefab;
[SerializeField]
[Tooltip("Where to spawn the reward droplets relative to the spawn target (the center of the safe ward).")]
private Vector3 rewardOffset;
[SerializeField]
[Header("Colossus Portal")]
public ChildLocator modelChildLocator;
public PortalSpawner[] portalSpawners;
[Tooltip("Combat Director managing the monster wave that spawns on Halcyon Shrine's gold drain behavior activation.")]
public CombatDirector activationDirector;
[Tooltip("Monster credits given to combat director to determine how many monsters to spawn.")]
public float monsterCredit;
[SerializeField]
private bool scaleMonsterCreditWithDifficultyCoefficient = true;
[SerializeField]
private CombatDirector combatDirector;
private int quantityIncreaseFromBuyIn = 1;
private BasicPickupDropTable rewardDropTable;
private Xoroshiro128Plus rng;
[SyncVar]
public float goldMaterialModifier = -2.2f;
[SyncVar]
private bool visualsDone;
private NetworkInstanceId ___shrineGoldBottomNetId;
private NetworkInstanceId ___shrineGoldMidNetId;
private NetworkInstanceId ___shrineGoldTopNetId;
public static bool isCommandEnabled => RunArtifactManager.instance.IsArtifactEnabled(RoR2Content.Artifacts.Command);
public int NetworkmaxTargets
{
get
{
return maxTargets;
}
[param: In]
set
{
SetSyncVar(value, ref maxTargets, 1u);
}
}
public int Networkinteractions
{
get
{
return interactions;
}
[param: In]
set
{
SetSyncVar(value, ref interactions, 2u);
}
}
public bool NetworkisDraining
{
get
{
return isDraining;
}
[param: In]
set
{
SetSyncVar(value, ref isDraining, 4u);
}
}
public GameObject NetworkshrineGoldBottom
{
get
{
return shrineGoldBottom;
}
[param: In]
set
{
SetSyncVarGameObject(value, ref shrineGoldBottom, 8u, ref ___shrineGoldBottomNetId);
}
}
public GameObject NetworkshrineGoldMid
{
get
{
return shrineGoldMid;
}
[param: In]
set
{
SetSyncVarGameObject(value, ref shrineGoldMid, 16u, ref ___shrineGoldMidNetId);
}
}
public GameObject NetworkshrineGoldTop
{
get
{
return shrineGoldTop;
}
[param: In]
set
{
SetSyncVarGameObject(value, ref shrineGoldTop, 32u, ref ___shrineGoldTopNetId);
}
}
public float NetworkgoldMaterialModifier
{
get
{
return goldMaterialModifier;
}
[param: In]
set
{
SetSyncVar(value, ref goldMaterialModifier, 64u);
}
}
public bool NetworkvisualsDone
{
get
{
return visualsDone;
}
[param: In]
set
{
SetSyncVar(value, ref visualsDone, 128u);
}
}
protected void Awake()
{
if (NetworkServer.active)
{
if (automaticallyScaleCostWithDifficulty)
{
lowGoldCost = Run.instance.GetDifficultyScaledCost(lowGoldCost);
midGoldCost = Run.instance.GetDifficultyScaledCost(midGoldCost);
maxGoldCost = Run.instance.GetDifficultyScaledCost(maxGoldCost);
goldDrainValue = Run.instance.GetDifficultyScaledCost(goldDrainValue);
}
CalculateCredits();
HalcyoniteShrineActive = true;
goldMaterialController.EnableKeyword("_SLICEHEIGHT");
combatDirector = GetComponent<CombatDirector>();
}
}
private void Start()
{
HalcyoniteShrineActive = true;
shrineCollisionObject.layer = LayerIndex.world.intVal;
}
private void CalculateCredits()
{
if (scaleMonsterCreditWithDifficultyCoefficient)
{
monsterCredit = Mathf.CeilToInt(monsterCredit * Run.instance.difficultyCoefficient);
}
}
[Server]
public void TrackInteractions()
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.HalcyoniteShrineInteractable::TrackInteractions()' called on client");
return;
}
if (interactions == 0)
{
GetComponent<Highlight>().targetRenderer = shrineRenderer;
stateMachine.SetNextStateToMain();
}
Networkinteractions = interactions + 1;
if (interactions >= 3)
{
stateMachine.SetNextState(new ShrineHalcyoniteMaxQuality());
}
}
[Server]
public void IsDraining(bool drainingActive)
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.HalcyoniteShrineInteractable::IsDraining(System.Boolean)' called on client");
}
else
{
NetworkisDraining = drainingActive;
}
}
public void DestroyDrainVFX()
{
if ((bool)siphonObject)
{
NetworkServer.Destroy(siphonObject);
}
if ((bool)shrineHalcyoniteBubble && shrineHalcyoniteBubble.activeInHierarchy)
{
shrineHalcyoniteBubble.SetActive(value: false);
}
IsDraining(drainingActive: false);
}
public void DrainConditionMet()
{
DestroyDrainVFX();
if ((bool)purchaseInteraction && purchaseInteraction.available)
{
purchaseInteraction.SetAvailable(newAvailable: false);
}
if (goldDrained > lowGoldCost && goldDrained < midGoldCost)
{
quantityIncreaseFromBuyIn = 1;
rewardDropTable = halcyoniteDropTableTier1;
rewardOptionCount = 3;
rng = new Xoroshiro128Plus(Run.instance.treasureRng.nextUlong);
}
if (goldDrained > midGoldCost && goldDrained < maxGoldCost)
{
quantityIncreaseFromBuyIn = 1;
rewardDropTable = halcyoniteDropTableTier2;
rewardOptionCount = 4;
rng = new Xoroshiro128Plus(Run.instance.treasureRng.nextUlong);
}
if (goldDrained >= maxGoldCost)
{
quantityIncreaseFromBuyIn = 1;
rewardDropTable = halcyoniteDropTableTier3;
rewardOptionCount = 5;
rng = new Xoroshiro128Plus(Run.instance.treasureRng.nextUlong);
}
Transform transform = modelChildLocator.FindChild("ModelBase");
if (transform != null)
{
Vector3 origin = transform.position + new Vector3(0f, 16f, 0f);
EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/HalcyonShrineTierReachVFX"), new EffectData
{
origin = origin
}, transmit: false);
}
int difficultyLevel = (int)((float)goldDrained / 100f);
combatDirector.HalcyoniteShrineActivation(chosenDirectCard.cost, chosenDirectCard, difficultyLevel, base.gameObject.transform);
}
public void StoreDrainValue(int value)
{
goldDrained += value;
}
[Server]
public void AttemptSpawnPortal()
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.HalcyoniteShrineInteractable::AttemptSpawnPortal()' called on client");
return;
}
PortalSpawner[] array = portalSpawners;
for (int i = 0; i < array.Length; i++)
{
array[i].AttemptSpawnPortalServer();
}
}
[Server]
public void DropRewards()
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.HalcyoniteShrineInteractable::DropRewards()' called on client");
return;
}
stateMachine.SetNextState(EntityStateCatalog.InstantiateState(ref finishedState));
int participatingPlayerCount = Run.instance.participatingPlayerCount;
if (participatingPlayerCount <= 0 || !base.gameObject || !rewardDropTable)
{
return;
}
int num = participatingPlayerCount * quantityIncreaseFromBuyIn;
float angle = 360f / (float)num;
Vector3 vector = Quaternion.AngleAxis(Random.Range(0, 360), Vector3.up) * (Vector3.up * 40f + Vector3.forward * 5f);
Quaternion quaternion = Quaternion.AngleAxis(angle, Vector3.up);
Vector3 position = base.gameObject.transform.position + rewardOffset;
int num2 = 0;
while (num2 < num)
{
if (isCommandEnabled)
{
int num3 = rewardOptionCount - 2;
for (int i = 0; i < num3; i++)
{
PickupIndex pickupIndex = rewardDropTable.GenerateDrop(rng);
GenericPickupController.CreatePickupInfo createPickupInfo = default(GenericPickupController.CreatePickupInfo);
createPickupInfo.pickupIndex = pickupIndex;
createPickupInfo.rotation = Quaternion.identity;
createPickupInfo.position = position;
GenericPickupController.CreatePickupInfo pickupInfo = createPickupInfo;
PickupDropletController.CreatePickupDroplet(pickupInfo, pickupInfo.position, vector);
}
}
else
{
GenericPickupController.CreatePickupInfo createPickupInfo = default(GenericPickupController.CreatePickupInfo);
createPickupInfo.pickupIndex = PickupCatalog.FindPickupIndex(rewardDisplayTier);
createPickupInfo.pickerOptions = PickupPickerController.GenerateOptionsFromDropTablePlusForcedStorm(rewardOptionCount, halcyoniteDropTableTier3, halcyoniteDropTableTier2, rng);
createPickupInfo.rotation = Quaternion.identity;
createPickupInfo.prefabOverride = rewardPickupPrefab;
GenericPickupController.CreatePickupInfo pickupInfo2 = createPickupInfo;
pickupInfo2.position = position;
PickupDropletController.CreatePickupDroplet(pickupInfo2, position, vector);
}
num2++;
vector = quaternion * vector;
}
}
private void UNetVersion()
{
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (forceAll)
{
writer.WritePackedUInt32((uint)maxTargets);
writer.WritePackedUInt32((uint)interactions);
writer.Write(isDraining);
writer.Write(shrineGoldBottom);
writer.Write(shrineGoldMid);
writer.Write(shrineGoldTop);
writer.Write(goldMaterialModifier);
writer.Write(visualsDone);
return true;
}
bool flag = false;
if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.WritePackedUInt32((uint)maxTargets);
}
if ((base.syncVarDirtyBits & 2u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.WritePackedUInt32((uint)interactions);
}
if ((base.syncVarDirtyBits & 4u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(isDraining);
}
if ((base.syncVarDirtyBits & 8u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(shrineGoldBottom);
}
if ((base.syncVarDirtyBits & 0x10u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(shrineGoldMid);
}
if ((base.syncVarDirtyBits & 0x20u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(shrineGoldTop);
}
if ((base.syncVarDirtyBits & 0x40u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(goldMaterialModifier);
}
if ((base.syncVarDirtyBits & 0x80u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(visualsDone);
}
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
}
return flag;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (initialState)
{
maxTargets = (int)reader.ReadPackedUInt32();
interactions = (int)reader.ReadPackedUInt32();
isDraining = reader.ReadBoolean();
___shrineGoldBottomNetId = reader.ReadNetworkId();
___shrineGoldMidNetId = reader.ReadNetworkId();
___shrineGoldTopNetId = reader.ReadNetworkId();
goldMaterialModifier = reader.ReadSingle();
visualsDone = reader.ReadBoolean();
return;
}
int num = (int)reader.ReadPackedUInt32();
if (((uint)num & (true ? 1u : 0u)) != 0)
{
maxTargets = (int)reader.ReadPackedUInt32();
}
if (((uint)num & 2u) != 0)
{
interactions = (int)reader.ReadPackedUInt32();
}
if (((uint)num & 4u) != 0)
{
isDraining = reader.ReadBoolean();
}
if (((uint)num & 8u) != 0)
{
shrineGoldBottom = reader.ReadGameObject();
}
if (((uint)num & 0x10u) != 0)
{
shrineGoldMid = reader.ReadGameObject();
}
if (((uint)num & 0x20u) != 0)
{
shrineGoldTop = reader.ReadGameObject();
}
if (((uint)num & 0x40u) != 0)
{
goldMaterialModifier = reader.ReadSingle();
}
if (((uint)num & 0x80u) != 0)
{
visualsDone = reader.ReadBoolean();
}
}
public override void PreStartClient()
{
if (!___shrineGoldBottomNetId.IsEmpty())
{
NetworkshrineGoldBottom = ClientScene.FindLocalObject(___shrineGoldBottomNetId);
}
if (!___shrineGoldMidNetId.IsEmpty())
{
NetworkshrineGoldMid = ClientScene.FindLocalObject(___shrineGoldMidNetId);
}
if (!___shrineGoldTopNetId.IsEmpty())
{
NetworkshrineGoldTop = ClientScene.FindLocalObject(___shrineGoldTopNetId);
}
}
}