357 lines
12 KiB
C#
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();
|
|
}
|
|
}
|
|
|