using CommonAI.Data; using CommonLang; using CommonLang.Log; using System; using System.Collections.Generic; using System.Linq; using System.Text; using XmdsCommon.JSGModule; using XmdsCommon.Plugin; using XmdsCommonServer.Plugin; using XmdsCommonSkill.Plugin.CardSkill; namespace CommonAI.ZoneServer.JSGModule { //卡牌权重变更模块 public class JSGCardRateModule { private String mUniqueInfo; protected static Logger log = LoggerFactory.GetLogger("JSGCardRateModule"); // 卡牌权重变更列表 private List mCardRateChgLists = new List(); // 权重计算辅助结构 private CardWeigthExt mCardWeightExt = new CardWeigthExt(); public JSGCardRateModule() { } public void initUniqueInfo(String uniqueInfo) { this.mUniqueInfo = uniqueInfo; } public void Update() { for(int i = mCardRateChgLists.Count - 1; i >= 0; i--) { CardRateChgData data = mCardRateChgLists[i]; if(data.validTime <= CommonLang.CUtils.localTimeMS || data.validTimes == 0) { mCardRateChgLists.RemoveAt(i); } } } public void AddChanges(CardRateChgData data) { if(data.uniqueID > 0) { for (int i = 0; i < mCardRateChgLists.Count; i++) { CardRateChgData temp = mCardRateChgLists[i]; if (temp.uniqueID == data.uniqueID) { temp.copy(data); return; } } } this.mCardRateChgLists.Add(data); } public GenCardData GetRandomCardType(CardSkillData [] playerCardSkill) { mCardWeightExt.Reset(playerCardSkill); //处理卡牌珠生成逻辑,优先处理最近的 for (int i = mCardRateChgLists.Count - 1; i >= 0; i--) { CardRateChgData data = mCardRateChgLists[i]; if(data.validTime < CommonLang.CUtils.localTimeMS || data.validTimes == 0) { continue; } if(data.validTimes > 0) {data.validTimes--;} // 本类型或者全局已设置,跳过 if (mCardWeightExt.GetSetFlag(data.cardType) || mCardWeightExt.GetSetFlag(CardType.Max)) { continue; } // 区分,能否设置的属性 if (data.chgType == CardRateChgType.Double) { mCardWeightExt.AddDoubleRate(data.cardType, data.value); } else { int finalWeightChg = GetWeightFinalValue(playerCardSkill, data.cardType, data); if (data.chgType == CardRateChgType.Add) { mCardWeightExt.AddWeight(data.cardType, finalWeightChg); } else if (data.chgType == CardRateChgType.Del) { mCardWeightExt.AddWeight(data.cardType, -finalWeightChg); } else if (data.chgType == CardRateChgType.Set) { mCardWeightExt.SetWeight(data.cardType, finalWeightChg); } } } #if JSG_CARD_TEST log.Warn("GetRandomCardType: 权重列表" + mCardWeightExt.ToString()); #endif GenCardData cardData = mCardWeightExt.GetWeightIndex(); if (cardData == null) { log.Error("JSGCardRateModule GetRandomCardType异常:" + mCardWeightExt.ToString() + ", " + (this.mUniqueInfo == null ? "null" : this.mUniqueInfo)); } return cardData; } public CardType GetCardByWeight(bool random) { return this.mCardWeightExt.GetCardOnlyByWeight(random); } /** 获取牌珠实际权重变更值 */ private int GetWeightFinalValue(CardSkillData[] playerCardSkill, CardType cardType, CardRateChgData data) { if (data.isPrecent) { return CUtils.CastInt(data.value * XmdsUnitProp.PER * playerCardSkill[(int)cardType].weight); } return data.value; } } // 卡牌权重数据辅助模块 public class CardWeigthExt { protected static Logger log = LoggerFactory.GetLogger("CardWeigthExt"); protected int[] cardWeight = new int[(int)CardType.Max+1]; private bool[] weightFlag = new bool[(int)CardType.Max+1]; // 是否设置概率 private int [] doubleRate = new int[(int)CardType.Max+1]; // 双球概率 public override string ToString() { return "CardWeigthExt: " + cardWeight[0] + ", " + cardWeight[1] + ", " + cardWeight[2] + ", " + cardWeight[3]; } public void Reset(CardSkillData [] cardSkill) { for (int i = 0; i <= (int)CardType.Max; i++) { this.cardWeight[i] = cardSkill[i].weight; this.weightFlag[i] = false; this.doubleRate[i] = 0; } } public bool GetSetFlag(CardType type) { return weightFlag[(int)type]; } public void AddWeight(CardType type, int value) { this.cardWeight[(int)type] += value; } //public short GetWeight(CardType type) //{ // return this.cardWeight[(int)type]; //} public void SetWeight(CardType type, int value) { this.cardWeight[(int)type] = value; this.weightFlag[(int)type] = true; } public void AddDoubleRate(CardType type, int value) { this.doubleRate[(int)type] += value; } // 考虑各种加成后, 以及双倍效果 public GenCardData GetWeightIndex() { int totalWeight = 0; for (int i = 0; i < (int)CardType.Max; i++) { //本类型未设置的情况下,全局设置了数据 if(!weightFlag[i] && weightFlag[(int)CardType.Max]) { this.cardWeight[i] = this.cardWeight[(int)CardType.Max]; } totalWeight += this.cardWeight[i]; } int randValue = GlobalData.gRandom.Next() % totalWeight; for (int i = 0; i < (int)CardType.Max; i++) { if (randValue < this.cardWeight[i]) { bool doubleCreate = GlobalData.gRandom.Next() % GlobalData.RATE_BASE < doubleRate[i] + doubleRate[(int)CardType.Max]; return new GenCardData((CardType)(i), doubleCreate ? 2 : 1); } randValue -= this.cardWeight[i]; } return null; } // 单纯根据权重获取卡牌 public CardType GetCardOnlyByWeight(bool random) { if (random) { int totalWeight = 0; for (int i = 0; i < (int)CardType.Max; i++) { totalWeight += this.cardWeight[i]; } if(totalWeight <= 0) { log.Error("卡牌总权重为0 : " + totalWeight); return (CardType)(GlobalData.gRandom.Next() % (int)CardType.Max); } else { int randValue = GlobalData.gRandom.Next() % totalWeight; for (int i = 0; i < (int)CardType.Max; i++) { if (randValue < this.cardWeight[i]) { return (CardType)i; } randValue -= this.cardWeight[i]; } return CardType.Max; } } else { int maxWeight = 0, maxIndex = -1; for (int i = 0; i < (int)CardType.Max; i++) { if (maxWeight < this.cardWeight[i]) { maxWeight = this.cardWeight[i]; maxIndex = i; } } return (maxIndex == -1) ? CardType.Max : (CardType)(maxIndex); } } } }