Files
test/Assets/PerfectWorld/Scripts/Shop/CECShopBase.cs
T
2025-12-03 16:43:11 +07:00

357 lines
12 KiB
C#

// Filename : CECShopBase.cs
// Creator : Xu Wenbin
// Date : 2013/12/11
// Converted to C#: 2024
using System;
using System.Linq;
using BrewMonster;
namespace PerfectWorld.Scripts.Shop
{
// 封装 gshop 和 backshop 等的数据访问 / Encapsulates data access for gshop and backshop etc.
public static class CECShopConstants
{
public const int CECSHOP_INVALID_PRICE = -1;
public const int BUY_COUNT = 4;
}
public abstract class CECShopBase : CECObservable<CECShopBase>
{
private CECShopItemOwnerNPC m_ownerNPC = new CECShopItemOwnerNPC(0);
// CECShopBase
public void OnItemChange()
{
CECShopBaseChange change = new CECShopBaseChange((uint)CECShopBaseChange.ChangeMask.ITEM_CHANGED);
NotifyObservers(change);
}
public bool ValidateTimeStamp()
{
return GetLocalTimeStamp() == GetServerTimeStamp();
}
public void SetOwnerNPCID(uint ownerNPCID)
{
if (ownerNPCID == m_ownerNPC.GetOwnerNPCID())
{
return;
}
m_ownerNPC.SetOwnerNPCID(ownerNPCID);
OnItemChange();
}
public uint GetOwnerNPCID()
{
return m_ownerNPC.GetOwnerNPCID();
}
public bool HasOwnerNPC()
{
return !m_ownerNPC.IsEmpty();
}
public CECShopItemOwnerNPC GetOwnerNPC()
{
return m_ownerNPC;
}
public bool MatchOwnerNPC(GShopItem rhs)
{
return m_ownerNPC.MatchItem(rhs);
}
public bool IsValid(int itemIndex, int buyIndex)
{
bool bValid = false;
GShopItem? pItem = GetItem(itemIndex);
if (pItem.HasValue)
{
if (buyIndex >= 0 && buyIndex < CECShopConstants.BUY_COUNT)
{
bValid = true;
}
}
return bValid;
}
public bool ReadyToBuy(int itemIndex, int buyIndex)
{
bool result = false;
int[] buyType = new int[CECShopConstants.BUY_COUNT];
if (IsValid(itemIndex, buyIndex) && CalcBuyType(itemIndex, buyType))
{
for (int i = 0; i < CECShopConstants.BUY_COUNT; ++i)
{
if (buyType[i] == buyIndex)
{
result = true;
break;
}
}
}
return result;
}
public bool CalcBuyType(int itemIndex, int[] buyTypes)
{
bool bOK = false;
GShopItem? pItem = GetItem(itemIndex);
if (pItem.HasValue)
{
GShopItem item = pItem.Value;
int[] typeDefault = new int[CECShopConstants.BUY_COUNT];
int[] typeNew = new int[CECShopConstants.BUY_COUNT];
int index1 = 0;
int index2 = 0;
for (int i = 0; i < CECShopConstants.BUY_COUNT; i++)
{
typeDefault[i] = -1;
typeNew[i] = -1;
if (item.buy != null && i < item.buy.Length)
{
if (item.buy[i].type == 3 && item.buy[i].price > 0)
{
typeNew[index1] = i;
index1++;
}
else if (item.buy[i].type == -1 && item.buy[i].price > 0)
{
typeDefault[index2] = i;
index2++;
}
}
}
if (index1 > 0)
{
Array.Copy(typeNew, buyTypes, CECShopConstants.BUY_COUNT);
bOK = true;
}
else if (index2 > 0)
{
Array.Copy(typeDefault, buyTypes, CECShopConstants.BUY_COUNT);
bOK = true;
}
}
return bOK;
}
public bool HasSameBuyType(int itemIndexA, int itemIndexB)
{
int[] typeA = new int[CECShopConstants.BUY_COUNT];
int[] typeB = new int[CECShopConstants.BUY_COUNT];
if (CalcBuyType(itemIndexA, typeA) &&
CalcBuyType(itemIndexB, typeB) &&
typeA.SequenceEqual(typeB))
{
GShopItem? pItemA = GetItem(itemIndexA);
GShopItem? pItemB = GetItem(itemIndexB);
if (pItemA.HasValue && pItemB.HasValue)
{
GShopItem itemA = pItemA.Value;
GShopItem itemB = pItemB.Value;
for (int i = 0; i < CECShopConstants.BUY_COUNT; ++i)
{
int buyIndex = typeA[i];
if (buyIndex != -1)
{
bool priceAValid = (itemA.buy != null && buyIndex < itemA.buy.Length && itemA.buy[buyIndex].price != 0);
bool priceBValid = (itemB.buy != null && buyIndex < itemB.buy.Length && itemB.buy[buyIndex].price != 0);
if (priceAValid != priceBValid)
{
return false;
}
if (!priceAValid)
{
continue;
}
if (itemA.buy[buyIndex].time != itemB.buy[buyIndex].time)
{
return false;
}
}
}
return true;
}
}
return false;
}
public bool CalcBuyIndex(int itemIndex, out int buyIndex, int cash = -1)
{
buyIndex = -1;
bool bOK = false;
GShopItem? pItem = GetItem(itemIndex);
if (pItem.HasValue)
{
GShopItem item = pItem.Value;
// 参考实现 CDlgQShopItem::SetItem / Reference implementation CDlgQShopItem::SetItem
// 判断要显示的购买方式 / Determine which purchase method to display
int[] m_TypeDefault = new int[CECShopConstants.BUY_COUNT];
int[] m_TypeNew = new int[CECShopConstants.BUY_COUNT];
int index1 = 0;
int index2 = 0;
for (int i = 0; i < CECShopConstants.BUY_COUNT; i++)
{
m_TypeDefault[i] = -1;
m_TypeNew[i] = -1;
if (item.buy != null && i < item.buy.Length)
{
if (item.buy[i].type == 3 && item.buy[i].price > 0)
{
m_TypeNew[index1] = i;
index1++;
}
else if (item.buy[i].type == -1 && item.buy[i].price > 0)
{
m_TypeDefault[index2] = i;
index2++;
}
}
}
int m_BuyType = -1;
if (index1 > 0)
{
m_BuyType = 0;
}
else
{
m_BuyType = 1;
}
if (cash == -1)
{
cash = GetCash();
}
for (int i = 0; i < CECShopConstants.BUY_COUNT; i++)
{
int BuyIndex = 0;
if (m_BuyType == 0)
{
BuyIndex = m_TypeNew[i];
}
else
{
BuyIndex = m_TypeDefault[i];
}
if (BuyIndex != -1 && item.buy != null && BuyIndex < item.buy.Length)
{
uint price = item.buy[BuyIndex].price;
if (price != 0 && price <= cash)
{
bOK = true;
buyIndex = BuyIndex;
break;
}
}
}
}
return bOK;
}
public int GetPrice(int itemIndex, int buyIndex)
{
int price = CECShopConstants.CECSHOP_INVALID_PRICE;
if (IsValid(itemIndex, buyIndex))
{
GShopItem? pItem = GetItem(itemIndex);
if (pItem.HasValue && pItem.Value.buy != null && buyIndex < pItem.Value.buy.Length)
{
price = (int)pItem.Value.buy[buyIndex].price;
}
}
else
{
UnityEngine.Debug.Assert(false);
}
return price;
}
public uint GetStatus(int itemIndex, int buyIndex)
{
uint status = 0xFFFFFFFF; // -1 as uint
if (IsValid(itemIndex, buyIndex))
{
GShopItem? pItem = GetItem(itemIndex);
if (pItem.HasValue && pItem.Value.buy != null && buyIndex < pItem.Value.buy.Length)
{
status = pItem.Value.buy[buyIndex].status;
}
}
else
{
UnityEngine.Debug.Assert(false);
}
return status;
}
public static bool IsSame(GShopItem lhs, GShopItem rhs)
{
bool result = false;
if (lhs.mainType != rhs.mainType ||
lhs.subType != rhs.subType ||
lhs.id != rhs.id ||
lhs.num != rhs.num ||
lhs.idGift != rhs.idGift ||
lhs.giftNum != rhs.giftNum)
{
return false;
}
result = true;
if (lhs.buy != null && rhs.buy != null)
{
int buyCount = Math.Min(lhs.buy.Length, rhs.buy.Length);
for (int i = 0; i < buyCount && i < CECShopConstants.BUY_COUNT; ++i)
{
if (lhs.buy[i].type != rhs.buy[i].type ||
lhs.buy[i].price != rhs.buy[i].price ||
lhs.buy[i].time != rhs.buy[i].time ||
lhs.buy[i].status != rhs.buy[i].status)
{
result = false;
break;
}
}
}
return result;
}
public static int GetOriginalPrice(int finalPrice, uint discountStatus)
{
int result = finalPrice;
if (discountStatus >= 4 && discountStatus <= 12)
{
float originalPrice = finalPrice * (10.0f / (discountStatus - 3));
if (CECUIConfig.Instance().GetGameUI().bEnableCeilPriceBeforeDiscountToGold)
{
result = (int)Math.Ceiling(originalPrice) + 99;
result /= 100;
result *= 100;
}
else
{
result = (int)Math.Ceiling(originalPrice);
}
}
return result;
}
// Abstract methods
public abstract bool GetFromServer(int beginIndex, int endIndex);
public abstract uint GetLocalTimeStamp();
public abstract uint GetServerTimeStamp();
public abstract int GetCount();
public abstract GShopItem? GetItem(int index);
public abstract int GetCash();
public abstract bool Buy(int itemIndex, int buyIndex);
public abstract bool IsFashionShopEnabled();
public abstract CECShopItemCategory GetFashionShopCategory();
public abstract bool IsFashionShopFlashSaleEnabled();
public abstract string GetFashionShopFlashSaleTitle();
}
}