r2mods/ilspy_dump/ror2_csproj/RoR2/PurchaseInteraction.cs

657 lines
16 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using RoR2.EntitlementManagement;
using RoR2.ExpansionManagement;
using RoR2.Hologram;
using RoR2.Stats;
using UnityEngine;
using UnityEngine.Networking;
namespace RoR2;
[RequireComponent(typeof(Highlight))]
public sealed class PurchaseInteraction : NetworkBehaviour, IInteractable, IInspectable, ISupportsMultipleInspectZones, IHologramContentProvider, IDisplayNameProvider
{
[SyncVar]
public string displayNameToken;
[SyncVar]
public string contextToken;
public CostTypeIndex costType;
[SyncVar]
public bool available = true;
[SyncVar]
public int cost;
public int solitudeCost;
public bool automaticallyScaleCostWithDifficulty;
[Tooltip("The unlockable that a player must have to be able to interact with this terminal.")]
public string requiredUnlockable = "";
public bool ignoreSpherecastForInteractability;
public string[] purchaseStatNames;
public bool setUnavailableOnTeleporterActivated;
public bool isShrine;
public bool isGoldShrine;
public bool shouldProximityHighlight = true;
public bool saleStarCompatible;
[SerializeField]
public ExpansionDef requiredExpansion;
private IInspectInfoProvider[] cachedInspectInfoProviders;
[HideInInspector]
public Interactor lastActivator;
[SyncVar]
public GameObject lockGameObject;
private Xoroshiro128Plus rng;
private GameObjectUnlockableFilter gameObjectUnlockableFilter;
private static readonly StringBuilder sharedStringBuilder = new StringBuilder();
public PurchaseEvent onPurchase;
private Transform viewerTransform;
private CharacterBody viewerBody;
private int currentInspectIndex;
private NetworkInstanceId ___lockGameObjectNetId;
public string NetworkdisplayNameToken
{
get
{
return displayNameToken;
}
[param: In]
set
{
SetSyncVar(value, ref displayNameToken, 1u);
}
}
public string NetworkcontextToken
{
get
{
return contextToken;
}
[param: In]
set
{
SetSyncVar(value, ref contextToken, 2u);
}
}
public bool Networkavailable
{
get
{
return available;
}
[param: In]
set
{
SetSyncVar(value, ref available, 4u);
}
}
public int Networkcost
{
get
{
return cost;
}
[param: In]
set
{
SetSyncVar(value, ref cost, 8u);
}
}
public GameObject NetworklockGameObject
{
get
{
return lockGameObject;
}
[param: In]
set
{
SetSyncVarGameObject(value, ref lockGameObject, 16u, ref ___lockGameObjectNetId);
}
}
public static event Action<PurchaseInteraction, Interactor> onItemSpentOnPurchase;
public static event Action<PurchaseInteraction, Interactor, EquipmentIndex> onEquipmentSpentOnPurchase;
private void Awake()
{
if (NetworkServer.active)
{
if (automaticallyScaleCostWithDifficulty)
{
Networkcost = Run.instance.GetDifficultyScaledCost(cost);
solitudeCost = cost;
}
rng = new Xoroshiro128Plus(Run.instance.treasureRng.nextUlong);
}
cachedInspectInfoProviders = GetComponents<IInspectInfoProvider>();
}
private void Start()
{
gameObjectUnlockableFilter = base.gameObject.GetComponent<GameObjectUnlockableFilter>();
}
[Server]
public void SetAvailable(bool newAvailable)
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.PurchaseInteraction::SetAvailable(System.Boolean)' called on client");
}
else
{
Networkavailable = newAvailable;
}
}
[Server]
public void SetUnavailableTemporarily(float time)
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.PurchaseInteraction::SetUnavailableTemporarily(System.Single)' called on client");
return;
}
Networkavailable = false;
Invoke("SetAvailableTrue", time);
}
private void SetAvailableTrue()
{
Networkavailable = true;
}
public string GetDisplayName()
{
return Language.GetString(displayNameToken);
}
private static bool ActivatorHasUnlockable(Interactor activator, string unlockableName)
{
NetworkUser networkUser = Util.LookUpBodyNetworkUser(activator.gameObject);
if ((bool)networkUser)
{
LocalUser localUser = networkUser.localUser;
if (localUser != null)
{
return localUser.userProfile.HasUnlockable(unlockableName);
}
}
return true;
}
public string GetContextString(Interactor activator)
{
sharedStringBuilder.Clear();
sharedStringBuilder.Append(Language.GetString(contextToken));
if (costType != 0)
{
sharedStringBuilder.Append(" <nobr>(");
if (costType == CostTypeIndex.Money)
{
if (TeamManager.LongstandingSolitudesInParty() > 0)
{
CostTypeCatalog.GetCostTypeDef(costType).BuildCostStringStyled(cost * (TeamManager.LongstandingSolitudesInParty() + 1), sharedStringBuilder, forWorldDisplay: false);
}
else
{
CostTypeCatalog.GetCostTypeDef(costType).BuildCostStringStyled(cost, sharedStringBuilder, forWorldDisplay: false);
}
}
else
{
CostTypeCatalog.GetCostTypeDef(costType).BuildCostStringStyled(cost, sharedStringBuilder, forWorldDisplay: false);
}
sharedStringBuilder.Append(")</nobr>");
}
return sharedStringBuilder.ToString();
}
public Interactability GetInteractability(Interactor activator)
{
if (!string.IsNullOrEmpty(requiredUnlockable) && !ActivatorHasUnlockable(activator, requiredUnlockable))
{
return Interactability.Disabled;
}
if (!available || (bool)lockGameObject)
{
return Interactability.Disabled;
}
if (gameObjectUnlockableFilter != null)
{
NetworkUser networkUser = Util.LookUpBodyNetworkUser(activator.gameObject);
if ((bool)networkUser)
{
LocalUser localUser = networkUser.localUser;
if (localUser != null && localUser.userProfile.HasAchievement(gameObjectUnlockableFilter.AchievementToDisable))
{
return Interactability.Disabled;
}
}
}
Run instance = Run.instance;
if ((bool)instance && (bool)requiredExpansion)
{
if (!instance.IsExpansionEnabled(requiredExpansion))
{
return Interactability.Disabled;
}
EntitlementDef requiredEntitlement = requiredExpansion.requiredEntitlement;
CharacterBody component = activator.GetComponent<CharacterBody>();
if ((bool)component && (bool)requiredEntitlement)
{
PlayerCharacterMasterController playerCharacterMasterController = component.master.playerCharacterMasterController;
if (!playerCharacterMasterController)
{
return Interactability.Disabled;
}
PlayerCharacterMasterControllerEntitlementTracker component2 = playerCharacterMasterController.GetComponent<PlayerCharacterMasterControllerEntitlementTracker>();
if (!component2)
{
Debug.LogWarning("Rejecting interact because the playerCharacterMasterController doesn't have a sibling PlayerCharacterMasterControllerEntitlementTracker");
return Interactability.Disabled;
}
if (!component2.HasEntitlement(requiredEntitlement))
{
Debug.LogWarning("Rejecting interact because the player doesn't have entitlement " + requiredEntitlement.name);
return Interactability.Disabled;
}
}
}
if (!CanBeAffordedByInteractor(activator))
{
return Interactability.ConditionsNotMet;
}
return Interactability.Available;
}
public bool CanBeAffordedByInteractor(Interactor activator)
{
int num = cost;
if (costType == CostTypeIndex.Money)
{
num = ((activator.GetComponent<CharacterBody>().GetBuffCount(DLC2Content.Buffs.FreeUnlocks) <= 0) ? (cost * (TeamManager.LongstandingSolitudesInParty() + 1)) : 0);
}
return CostTypeCatalog.GetCostTypeDef(costType).IsAffordable(num, activator);
}
public void OnInteractionBegin(Interactor activator)
{
if (!CanBeAffordedByInteractor(activator))
{
return;
}
CharacterBody component = activator.GetComponent<CharacterBody>();
CostTypeDef costTypeDef = CostTypeCatalog.GetCostTypeDef(costType);
ItemIndex itemIndex = ItemIndex.None;
ShopTerminalBehavior component2 = GetComponent<ShopTerminalBehavior>();
if ((bool)component2)
{
itemIndex = PickupCatalog.GetPickupDef(component2.CurrentPickupIndex())?.itemIndex ?? ItemIndex.None;
}
int num = cost;
if (costType == CostTypeIndex.Money)
{
if (activator.GetComponent<CharacterBody>().GetBuffCount(DLC2Content.Buffs.FreeUnlocks) > 0 && !GetComponent<MultiShopController>())
{
num = 0;
activator.GetComponent<CharacterBody>().RemoveBuff(DLC2Content.Buffs.FreeUnlocks);
Util.PlaySound("Play_item_proc_onLevelUpFreeUnlock_activate", base.gameObject);
}
else
{
num = cost * (TeamManager.LongstandingSolitudesInParty() + 1);
}
}
if (component.inventory.GetItemCount(DLC2Content.Items.LowerPricedChests) > 0 && saleStarCompatible)
{
int itemCount = activator.GetComponent<CharacterBody>().inventory.GetItemCount(DLC2Content.Items.LowerPricedChests);
int num2 = 0;
float num3 = 1f;
if (itemCount == 1)
{
num2 = 0;
}
else
{
for (int i = 1; i < 4; i++)
{
switch (i)
{
case 1:
num3 = 30f;
break;
case 2:
num3 = 15f;
break;
case 3:
num3 = 1f;
break;
}
if (itemCount >= 3)
{
float num4 = 1f - 1f / ((float)itemCount * 0.05f + 1f);
if (!Util.CheckRoll(num3 + num4 * 100f, activator.GetComponent<CharacterBody>().master))
{
break;
}
num2 = i;
}
else
{
if (!Util.CheckRoll(num3, activator.GetComponent<CharacterBody>().master))
{
break;
}
num2 = i;
}
}
}
if ((bool)GetComponent<ChestBehavior>())
{
GetComponent<ChestBehavior>().dropCount = 2 + num2;
}
else if ((bool)GetComponent<RouletteChestController>())
{
GetComponent<RouletteChestController>().dropCount = 2 + num2;
}
component.inventory.RemoveItem(DLC2Content.Items.LowerPricedChests, activator.GetComponent<CharacterBody>().inventory.GetItemCount(DLC2Content.Items.LowerPricedChests));
component.inventory.GiveItem(DLC2Content.Items.LowerPricedChestsConsumed, itemCount);
CharacterMasterNotificationQueue.SendTransformNotification(component.master, DLC2Content.Items.LowerPricedChests.itemIndex, DLC2Content.Items.LowerPricedChestsConsumed.itemIndex, CharacterMasterNotificationQueue.TransformationType.SaleStarRegen);
Util.PlaySound("Play_item_proc_lowerPricedChest", base.gameObject);
}
CostTypeDef.PayCostResults payCostResults = costTypeDef.PayCost(num, activator, base.gameObject, rng, itemIndex);
foreach (ItemIndex item in payCostResults.itemsTaken)
{
CreateItemTakenOrb(component.corePosition, base.gameObject, item);
if (item != itemIndex)
{
PurchaseInteraction.onItemSpentOnPurchase?.Invoke(this, activator);
}
}
foreach (EquipmentIndex item2 in payCostResults.equipmentTaken)
{
PurchaseInteraction.onEquipmentSpentOnPurchase?.Invoke(this, activator, item2);
}
IEnumerable<StatDef> statDefsToIncrement = purchaseStatNames.Select(StatDef.Find);
StatManager.OnPurchase(component, costType, statDefsToIncrement);
onPurchase.Invoke(activator);
lastActivator = activator;
}
[Server]
public static void CreateItemTakenOrb(Vector3 effectOrigin, GameObject targetObject, ItemIndex itemIndex)
{
if (!NetworkServer.active)
{
Debug.LogWarning("[Server] function 'System.Void RoR2.PurchaseInteraction::CreateItemTakenOrb(UnityEngine.Vector3,UnityEngine.GameObject,RoR2.ItemIndex)' called on client");
return;
}
GameObject effectPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/OrbEffects/ItemTakenOrbEffect");
EffectData effectData = new EffectData
{
origin = effectOrigin,
genericFloat = 1.5f,
genericUInt = (uint)(itemIndex + 1)
};
effectData.SetNetworkedObjectReference(targetObject);
EffectManager.SpawnEffect(effectPrefab, effectData, transmit: true);
}
public bool ShouldDisplayHologram(GameObject viewer)
{
return available;
}
public GameObject GetHologramContentPrefab()
{
return LegacyResourcesAPI.Load<GameObject>("Prefabs/CostHologramContent");
}
private void CacheViewerBody(Transform _viewer)
{
if (!(_viewer == null) && (!viewerBody || !(viewerTransform == _viewer)) && _viewer.TryGetComponent<CharacterBody>(out var component))
{
viewerTransform = _viewer;
viewerBody = component;
}
}
public void ScaleCost(float scalar)
{
Networkcost = (int)Mathf.Floor((float)cost * scalar);
}
public void UpdateHologramContent(GameObject hologramContentObject, Transform viewer)
{
CostHologramContent component = hologramContentObject.GetComponent<CostHologramContent>();
GetComponent<HologramProjector>();
CacheViewerBody(viewer);
if (!component)
{
return;
}
if ((bool)viewerBody && costType.Equals(CostTypeIndex.Money))
{
if (TeamManager.LongstandingSolitudesInParty() > 0)
{
component.displayValue = cost * (TeamManager.LongstandingSolitudesInParty() + 1);
}
else
{
component.displayValue = cost;
}
}
else
{
component.displayValue = cost;
}
component.costType = costType;
}
public bool ShouldIgnoreSpherecastForInteractibility(Interactor activator)
{
return false;
}
public bool ShouldShowOnScanner()
{
return available;
}
public bool ShouldProximityHighlight()
{
return shouldProximityHighlight;
}
private void OnEnable()
{
InstanceTracker.Add(this);
}
private void OnDisable()
{
InstanceTracker.Remove(this);
}
[RuntimeInitializeOnLoadMethod]
private static void Init()
{
TeleporterInteraction.onTeleporterBeginChargingGlobal += OnTeleporterBeginCharging;
}
private static void OnTeleporterBeginCharging(TeleporterInteraction teleporterInteraction)
{
if (!NetworkServer.active)
{
return;
}
foreach (PurchaseInteraction instances in InstanceTracker.GetInstancesList<PurchaseInteraction>())
{
if (instances.setUnavailableOnTeleporterActivated)
{
instances.SetAvailable(newAvailable: false);
instances.CancelInvoke("SetUnavailableTemporarily");
}
}
}
public IInspectInfoProvider GetInspectInfoProvider()
{
if (currentInspectIndex < cachedInspectInfoProviders.Length)
{
return cachedInspectInfoProviders[currentInspectIndex];
}
return null;
}
public void SetInspectInfoProvider(int newInspectIndex)
{
currentInspectIndex = newInspectIndex;
}
private void UNetVersion()
{
}
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (forceAll)
{
writer.Write(displayNameToken);
writer.Write(contextToken);
writer.Write(available);
writer.WritePackedUInt32((uint)cost);
writer.Write(lockGameObject);
return true;
}
bool flag = false;
if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(displayNameToken);
}
if ((base.syncVarDirtyBits & 2u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(contextToken);
}
if ((base.syncVarDirtyBits & 4u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(available);
}
if ((base.syncVarDirtyBits & 8u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.WritePackedUInt32((uint)cost);
}
if ((base.syncVarDirtyBits & 0x10u) != 0)
{
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
flag = true;
}
writer.Write(lockGameObject);
}
if (!flag)
{
writer.WritePackedUInt32(base.syncVarDirtyBits);
}
return flag;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (initialState)
{
displayNameToken = reader.ReadString();
contextToken = reader.ReadString();
available = reader.ReadBoolean();
cost = (int)reader.ReadPackedUInt32();
___lockGameObjectNetId = reader.ReadNetworkId();
return;
}
int num = (int)reader.ReadPackedUInt32();
if (((uint)num & (true ? 1u : 0u)) != 0)
{
displayNameToken = reader.ReadString();
}
if (((uint)num & 2u) != 0)
{
contextToken = reader.ReadString();
}
if (((uint)num & 4u) != 0)
{
available = reader.ReadBoolean();
}
if (((uint)num & 8u) != 0)
{
cost = (int)reader.ReadPackedUInt32();
}
if (((uint)num & 0x10u) != 0)
{
lockGameObject = reader.ReadGameObject();
}
}
public override void PreStartClient()
{
if (!___lockGameObjectNetId.IsEmpty())
{
NetworklockGameObject = ClientScene.FindLocalObject(___lockGameObjectNetId);
}
}
}