#!/usr/bin/python # -*- coding: GBK -*- #--------------------------------------------------------------------- # #--------------------------------------------------------------------- ##@package FunctionNPCCommon # @todo: ¹¦ÄÜNPC¹ÜÀíÆ÷ # # @author: panwei # @date 2010-4-26 # @version 4.4 # # @note: #--------------------------------------------------------------------- # @change: "2013-04-18 17:00" wdb ÎïÆ·ÑÕɫʹÓÃÐÞ¸Ä # @change: "2013-04-26 16:00" wdb npcÉ̵êÐÞ¸Ä # @change: "2013-05-03 17:00" wdb npcÉ̵êÅä±í·½Ê½ÐÞ¸Ä # @change: "2013-05-20 15:00" wdb ×°±¸¸½¼ÓÊôÐÔ½Ó¿ÚÐÞ¸Ä # @change: "2013-05-30 10:30" wdb ×°±¸±¦Ê¯ÏâǶµ÷Õû # @change: "2013-07-19 20:00" Alee Ìí¼Ó»Ø¹º # @change: "2013-07-22 17:00" Alee ÎïÆ·¿É°´ÊýÁ¿¹ºÂò # @change: "2013-10-12 21:10" Alee ϵͳÌáʾ # @change: "2013-10-22 11:10" Alee ÎïÆ·¼¼ÄÜÔöǿЧ¹û,ͳһº¯ÊýEquipAddAdditionEx # @change: "2013-11-08 22:30" Alee É̳ÇÌí¼Ó´ò¿× # @change: "2013-11-19 11:00" hxp Ð޸ijöÊÛÎïÆ·ÅжϽðÇ®ÉÏÏÞÂß¼­ # @change: "2014-01-16 13:54" xmnathan Õ½ÃËÉ̳ǹºÂò # @change: "2014-01-28 00:55" Alee ¶ñħÉ̵êĬÈÏ׿ԽºÍÌ××° # @change: "2014-02-12 14:00" Alee È¡ÏûºìÃû¹ºÂò³Í·£ # @change: "2014-04-07 11:30" Alee ·â°üDWORDµ¼Ö½ӿÚint±¨´í£¬·À·¶·¶Î§¹ý´ó # @change: "2014-05-05 15:00" xmnathan Ìæ»»ÏµÍ³Ìáʾ # @change: "2014-05-21 17:25" xcc Ôö¼Óħ·½Ñ°±¦»ý·Ö¶Ò»»ÎïÆ·¹¦ÄÜ # @change: "2014-06-05 15:30" hxp É̵êNPCÎïÆ·¹ºÂòÔö¼ÓÿÈտɹºÂò´ÎÊýÉÏÏÞÖ§³Ö # @change: "2014-08-04 16:00" Alee Ì××°ÎïÆ·É̵êÐÞ¸Ä # @change: "2014-08-07 20:40" Alee ±¦²Ø»ý·Ö¶Ò»»×¿Ô½ÊôÐÔ×°±¸¹Ì¶¨2ÌõÊôÐÔ # @change: "2014-10-20 16:20" Alee ¶Ò»»Ì××°3׿Խ # @change: "2014-11-05 15:00" Alee É̵깺Âò°ó¶¨ÐÞ¸Ä # @change: "2014-12-11 16:30" hxp É̵ê¶Ò»»×°±¸Ôö¼ÓÖ§³ÖÅäÖÃ×°±¸¶ÔӦ׿ԽÌõÊý # @change: "2015-01-14 00:30" hxp Ôö¼ÓÎïÆ·±ä¸üʼþ»ã±¨ # @change: "2015-01-14 16:40" ljd Ôö¼ÓÎïÆ·¶Ò»»É̵ê # @change: "2015-01-27 10:50" ljd Ôö¼Ó×°±¸ÎïÆ·À´Ô´±ê¼Ç # @change: "2015-04-03 18:00" hxp ·À·¶»ØÊÕÕ¾Òì³£Çé¿öÎïÆ·Ïûʧ¶øÃ»ÓÐÖØÖñê¼Çλµ¼ÖÂÊýÖµÔ½½ç # @change: "2015-04-16 19:10" ljd É̵긶Ǯʱ´«ÈëÖ§¸¶ÀàÐÍ # @change: "2015-04-27 22:00" hxp Ôö¼ÓBuyItemÁ÷Ïò # @change: "2016-07-20 14:30" hxp »õ±ÒÖ§¸¶Á÷ÏòÕûºÏ # @change: "2016-08-04 18:00" hxp ³öÊۻعº¼Û¸ñÐÞ¸Ä #--------------------------------------------------------------------- #"""Version = 2016-08-04 18:00""" #--------------------------------------------------------------------- import ChConfig import GameWorld import NetPackCommon import ItemControler import ChPyNetSendPack import PlayerControl import IpyGameDataPY import ItemCommon import ObjPool # ÖØÖÃÀàÐÍ ResetType_Day = 1 ResetType_Week = 2 # ½âËøÀàÐÍ UnlockType_FamilyLV = 1 # ¹«»áµÈ¼¶ UnlockType_RandRefresh = 2 # Ëæ»úˢнâËø # ²¿·ÖÉ̵êÀàÐÍ ShopType_HeroSoul = 3 # ½«»ê RefreshShopTypeList = [ShopType_HeroSoul] def DoShopOpen(curPlayer): for shopType in RefreshShopTypeList: DoRandRefreshShopItem(curPlayer, shopType, sysRefresh=True) return def ShopItemOnLogin(curPlayer): SyncShopItemBuyCntInfo(curPlayer) for shopType in RefreshShopTypeList: SyncShopRefreshItemInfo(curPlayer, shopType) return def ShopItemOnDay(curPlayer): for shopType in RefreshShopTypeList: if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopRefreshCnt % shopType): continue PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopRefreshCnt % shopType, 0) SyncShopRefreshItemInfo(curPlayer, shopType) ResetShopItemBuyCount(curPlayer, [ResetType_Day]) return def ShopItemOnWeek(curPlayer): ResetShopItemBuyCount(curPlayer, [ResetType_Week]) return def ResetShopItemBuyCount(curPlayer, resetTypeList): #@param resetTypeList: ÐèÒªÖØÖõÄÀàÐÍÁбí if not resetTypeList: # Ôݶ¨±ØÐëÖ¸¶¨ÀàÐÍÁÐ±í£¬·ÀÖ¹ÖÕÉíÏÞ¹ºµÄÎó±»ÖØÖà return syncIDList = [] ipyDataMgr = IpyGameDataPY.IPY_Data() for i in xrange(ipyDataMgr.GetStoreCount()): shopItem = ipyDataMgr.GetStoreByIndex(i) if not shopItem.GetLimitCnt(): continue if shopItem.GetResetType() not in resetTypeList: continue shopID = shopItem.GetID() curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID) if curBuyCnt <= 0: continue PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, 0) syncIDList.append(shopID) if syncIDList: SyncShopItemBuyCntInfo(curPlayer, syncIDList) return def ResetShopItemBuyCountByShopType(curPlayer, shopTypeList): ##¸ù¾ÝÉ̵êÀàÐÍÖØÖÃÉ̵êÏÞ¹ºÎïÆ·´ÎÊý if not shopTypeList: return syncIDList = [] for shopType in shopTypeList: ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True) if not ipyDataList: continue for ipyData in ipyDataList: if not ipyData.GetLimitCnt(): continue shopID = ipyData.GetID() curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID) if curBuyCnt <= 0: continue PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, 0) syncIDList.append(shopID) if syncIDList: SyncShopItemBuyCntInfo(curPlayer, syncIDList) return def PayAutoBuyItem(curPlayer, lackItemDict, priceType, costType=ChConfig.Def_Cost_Unknown, infoDict={}, isCheck=False, shopItemIndexDict=None): ''' Ö§¸¶×Ô¶¯¹ºÂòÎïÆ·ÏûºÄ£¬´ÓÉ̳ÇÖйºÂò£¬Ö±½Ó¿ÛÇ®£¬²»²úÉúÎïÆ· Ò»°ãÓÃÓÚ»ù´¡É̵ê×Ô¶¯¹ºÂòÎïÆ·£¬²»¿¼ÂǸ´ÔÓµÄÏÞ¹ºÂß¼­ @param isCheck: ÊÇ·ñÖ»ÊǼì²é£¬²»Ö´ÐÐʵ¼ÊÏûºÄÂß¼­ @param shopItemIndexDict: Ö¸¶¨¹ºÂòµÄÉÌÆ·¶ÔÓ¦É̳DZíÉÌÆ·IDË÷Òý×ֵ䣬Èç¹ûûÓÐÖ¸¶¨ÉÌÆ·Ë÷Òý£¬Ôò°´ÏûºÄµÄ¼Û¸ñÀàÐÍ×Ô¶¯ËÑË÷É̳DZí ''' addLimitCountInfo = {} totalMoney = 0 # ¼ÆËã×Ô¶¯¹ºÂòÏûºÄ for itemID, lackCnt in lackItemDict.items(): if lackCnt <= 0: continue curItem = GameWorld.GetGameData().GetItemByTypeID(itemID) if not curItem: return if shopItemIndexDict and itemID in shopItemIndexDict: shopID = shopItemIndexDict[itemID] ipyData = IpyGameDataPY.GetIpyGameData("Store", shopID) else: ipyData = ItemCommon.GetShopItemPriceIpyData(itemID, priceType) if not ipyData: return shopID = ipyData.GetID() shopType = ipyData.GetShopType() priceType = ipyData.GetMoneyType() itemMoney = ipyData.GetMoneyNum() limitBuyCnt = ipyData.GetLimitCnt() if limitBuyCnt: curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID) canBuyCnt = max(0, limitBuyCnt - curBuyCnt) if canBuyCnt < lackCnt: GameWorld.Log("×Ô¶¯¹ºÂò´ÎÊý²»×㣡shopType=%s,shopID=%s,itemID=%s,limitBuyCnt=%s,curBuyCnt=%s,canBuyCnt=%s < %s" % (shopType, shopID, itemID, limitBuyCnt, curBuyCnt, canBuyCnt, lackCnt), curPlayer.GetPlayerID()) return addLimitCountInfo[shopID] = lackCnt totalMoney += (lackCnt * itemMoney) if totalMoney <= 0: return if isCheck: return PlayerControl.HaveMoney(curPlayer, priceType, totalMoney) GameWorld.DebugLog("¿Û³ý×Ô¶¯¹ºÂòÏûºÄ: lackItemDict=%s,priceType=%s,totalMoney=%s,costType=%s,addLimitCountInfo=%s" % (lackItemDict, priceType, totalMoney, costType, addLimitCountInfo), curPlayer.GetPlayerID()) if not PlayerControl.PayMoney(curPlayer, priceType, totalMoney, costType, infoDict): return if addLimitCountInfo: syncIDList = [] for shopID, lackCnt in addLimitCountInfo.items(): curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, curBuyCnt + lackCnt) syncIDList.append(shopID) SyncShopItemBuyCntInfo(curPlayer, syncIDList) return True #// A3 10 ¹ºÂòÉ̳ÇÎïÆ· #tagCSBuyItem # #struct tagCSBuyItem #{ # tagHead Head; # DWORD ShopID; //ÉÌÆ·ID # DWORD BuyCount; //¹ºÂòÊýÁ¿ #}; def PyBuyItem(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) shopID = clientData.ShopID buyCount = clientData.BuyCount OnBuyItem(curPlayer, shopID, buyCount) return def OnBuyItem(curPlayer, shopID, clientBuyCount): GameWorld.DebugLog("¹ºÂòÉ̳ÇÎïÆ·: shopID=%s,clientBuyCount=%s" % (shopID, clientBuyCount)) if GameWorld.IsCrossServer(): return if shopID <= 0 or clientBuyCount <= 0: return ipyData = IpyGameDataPY.GetIpyGameData("Store", shopID) if not ipyData: return shopType = ipyData.GetShopType() limitBuyCnt = ipyData.GetLimitCnt() if limitBuyCnt > 0: curBuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID) canBuyCnt = max(0, limitBuyCnt - curBuyCnt) if canBuyCnt <= 0: GameWorld.DebugLog("ÉÌÆ·ÏÞ¹º´ÎÊýÒÑÂú ! shopType=%s,shopID=%s,curBuyCnt=%s < %s" % (shopType, shopID, curBuyCnt, limitBuyCnt)) return if clientBuyCount > canBuyCnt: clientBuyCount = canBuyCnt itemID, itemCount, isBind = ipyData.GetItemID(), ipyData.GetItemCnt(), 0 itemListEx = ipyData.GetItemListEx() totalItemList = [] if itemID: totalItemList.append([itemID, itemCount * clientBuyCount, isBind]) for itemIDEx, itemCountEx, isBindEx in itemListEx: totalItemList.append([itemIDEx, itemCountEx * clientBuyCount, isBindEx]) if not totalItemList: GameWorld.ErrLog("Store shop item error! shopType=%s,shopID=%s" % (shopType, shopID), curPlayer.GetPlayerID()) return mainItemID = totalItemList[0][0] GameWorld.DebugLog("shopType=%s,shopID=%s,totalItemList=%s" % (shopType, shopID, totalItemList)) # ¼ì²éÊÇ·ñ½âËøÉÌÆ·¹ºÂò if not CheckBuyItemUnlock(curPlayer, shopType, shopID, mainItemID, ipyData): GameWorld.Log("Store shop item lock! shopID=%s,shopID=%s" % (shopType, shopID), curPlayer.GetPlayerID()) return priceType, itemPrice = ipyData.GetMoneyType(), ipyData.GetMoneyNum() itemPrice *= clientBuyCount #if not PlayerControl.HaveMoney(curPlayer, priceType, itemPrice): # return infoDict = {"TotalItemList":totalItemList, "ClientBuyCount":clientBuyCount, "ShopType":shopType, "ShopID":shopID, ChConfig.Def_Cost_Reason_SonKey:mainItemID} if priceType and itemPrice and not PlayerControl.PayMoney(curPlayer, priceType, itemPrice, ChConfig.Def_Cost_BuyStoreItem, infoDict, clientBuyCount): return # ½ñÈÕ¹ºÂò´ÎÊý+1 if limitBuyCnt > 0: updBuyCnt = min(curBuyCnt + clientBuyCount, ChConfig.Def_UpperLimit_DWord) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, updBuyCnt) GameWorld.DebugLog("¸üÐÂÉ̳ÇÎïÆ·ÏÞ¹º´ÎÊý: shopID=%s,curBuyCnt=%s,clientBuyCount=%s,updBuyCnt=%s/%s" % (shopID, curBuyCnt, clientBuyCount, updBuyCnt, limitBuyCnt)) SyncShopItemBuyCntInfo(curPlayer, [shopID]) ItemControler.GivePlayerItemOrMail(curPlayer, totalItemList, event=["BuyItem", False, {}], notifyDataEx=shopID) return def CheckBuyItemUnlock(curPlayer, shopType, shopID, mainItemID, ipyData): ## ¼ì²éÊÇ·ñ½âËøÉÌÆ·¹ºÂò # @return: ÊÇ·ñÒѽâËø¹ºÂò unlockType = ipyData.GetUnlockType() unlockValue = ipyData.GetUnlockValue() # ¹«»áµÈ¼¶½âËø if unlockType == UnlockType_FamilyLV: if not curPlayer.GetFamilyID(): GameWorld.DebugLog("ÎÞ¹«»áÎÞ·¨¹ºÂò! shopID=%s" % shopID) return curFamilyLV = curPlayer.GetFamilyLV() if curFamilyLV <= 0: curFamilyLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FamilyLV) if curFamilyLV < unlockValue: GameWorld.DebugLog("¹«»áµÈ¼¶²»×ãÎÞ·¨¹ºÂò! shopID=%s,curFamilyLV=%s < %s" % (shopID, curFamilyLV, unlockValue)) return # Ëæ»úˢнâËø elif unlockType == UnlockType_RandRefresh: if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID): GameWorld.DebugLog("¸ÃÉÌÆ·Ã»ÓÐËæ»ú½âËøÎÞ·¨¹ºÂò! shopID=%s" % shopID) return return True #// A2 32 Ë¢ÐÂÉ̵ê #tagCSRefreshShop # #struct tagCSRefreshShop #{ # tagHead Head; # WORD ShopType; #}; def OnRefreshShop(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) shopType = clientData.ShopType DoRandRefreshShopItem(curPlayer, shopType) return def DoRandRefreshShopItem(curPlayer, shopType, randCnt=0, sysRefresh=False): ## Ëæ»úË¢ÐÂÉ̵êÎïÆ·£¬ID²»Öظ´ # @param randCnt: Ö¸¶¨ÒªËæ»ú½âËøµÄ¸öÊý ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True) if not ipyDataList: return shopIDWeightDict = {} randWeightList = [] for ipyData in ipyDataList: if ipyData.GetUnlockType() != UnlockType_RandRefresh: continue shopID = ipyData.GetID() randWeight = ipyData.GetUnlockValue() randWeightList.append([randWeight, shopID]) shopIDWeightDict[shopID] = randWeight if not randWeightList: GameWorld.ErrLog("¸ÃÉ̵êûÓпÉËæ»úˢнâËøµÄÉÌÆ·! shopType=%s" % shopType) return refreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopRefreshCnt % shopType) moneyType, moneyValue = 0, 0 if shopType == ShopType_HeroSoul: randCnt = IpyGameDataPY.GetFuncCfg("StoreHeroSoul", 1) freeCnt = IpyGameDataPY.GetFuncCfg("StoreHeroSoul", 3) if not sysRefresh and refreshCnt >= freeCnt: moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("StoreHeroSoul", 2) GameWorld.DebugLog("Ëæ»úË¢ÐÂÉ̵êÉÌÆ·: shopType=%s,randCnt=%s/%s,refreshCnt=%s,moneyType=%s,moneyValue=%s,sysRefresh=%s" % (shopType, randCnt, len(randWeightList), refreshCnt, moneyType, moneyValue, sysRefresh)) if randCnt <= 0: return if moneyType and moneyValue and not PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "RefreshShopItem"): return doCnt = randCnt * 10 randShopIDList = [] syncBuyCntIDList = [] while randWeightList and len(randShopIDList) < randCnt and doCnt > 0: doCnt -= 1 shopID = GameWorld.GetResultByWeightList(randWeightList) if not shopID: continue randShopIDList.append(shopID) randWeight = shopIDWeightDict.get(shopID, 0) if [randWeight, shopID] in randWeightList: randWeightList.remove([randWeight, shopID]) GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID, 1) if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID): PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopBuyCnt % shopID, 0) syncBuyCntIDList.append(shopID) GameWorld.DebugLog("Ëæ»úË¢ÐÂÉÌÆ·Êý: %s,%s" % (len(randShopIDList), randShopIDList)) GameWorld.DebugLog("Ê£ÓàËø¶¨ÉÌÆ·Êý: %s,%s" % (len(randWeightList), randWeightList)) # ÆäËûµÄÉèÖÃδ½âËø for _, shopID in randWeightList: GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID, 0) if not sysRefresh: refreshCnt += 1 PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopRefreshCnt % shopType, refreshCnt) GameWorld.DebugLog("¸üÐÂË¢ÐÂÉ̵ê´ÎÊý=%s" % refreshCnt) if syncBuyCntIDList: SyncShopItemBuyCntInfo(curPlayer, syncBuyCntIDList) SyncShopRefreshItemInfo(curPlayer, shopType, randShopIDList) return def SyncShopRefreshItemInfo(curPlayer, shopType, syncIDList=[]): ##ͬ²½Ë¢Ð½âËøµÄÉÌÆ·ÐÅÏ¢ if not syncIDList: syncIDList = [] ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True) if not ipyDataList: return for ipyData in ipyDataList: shopID = ipyData.GetID() if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_ShopRandUnlock, shopID): continue syncIDList.append(shopID) if not syncIDList: return clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCShopRefreshItemInfo) clientPack.ShopType = shopType clientPack.RefreshCnt = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopRefreshCnt % shopType), 250) clientPack.ShopIDList = syncIDList clientPack.Count = len(clientPack.ShopIDList) NetPackCommon.SendFakePack(curPlayer, clientPack) return def SyncShopItemBuyCntInfo(curPlayer, syncIDList=[]): ##ͬ²½ÉÌÆ·¹ºÂò´ÎÊý objPool = ObjPool.GetPoolMgr() buyCntList = [] if syncIDList: for shopID in syncIDList: buyInfo = objPool.acquire(ChPyNetSendPack.tagSCShopItemBuyCnt) buyInfo.ShopID = shopID buyInfo.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID) buyCntList.append(buyInfo) else: ipyDataMgr = IpyGameDataPY.IPY_Data() for i in xrange(ipyDataMgr.GetStoreCount()): shopItem = ipyDataMgr.GetStoreByIndex(i) if not shopItem.GetLimitCnt(): continue shopID = shopItem.GetID() buyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ShopBuyCnt % shopID) if buyCnt <= 0: continue buyInfo = objPool.acquire(ChPyNetSendPack.tagSCShopItemBuyCnt) buyInfo.ShopID = shopID buyInfo.BuyCnt = buyCnt buyCntList.append(buyInfo) if not buyCntList: return clientPack = objPool.acquire(ChPyNetSendPack.tagSCShopItemBuyCntInfo) clientPack.BuyCntList = buyCntList clientPack.Count = len(clientPack.BuyCntList) NetPackCommon.SendFakePack(curPlayer, clientPack) return