#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package Player.PlayerHorse # # @todo:×øÆï # @author hxp # @date 2025-11-04 # @version 1.0 # # ÏêϸÃèÊö: ×øÆï # #------------------------------------------------------------------------------- #"""Version = 2025-11-04 14:30""" #------------------------------------------------------------------------------- import ChConfig import ItemCommon import ShareDefine import NetPackCommon import PlayerControl import ChPyNetSendPack import IPY_GameWorld import IpyGameDataPY import GameFuncComm import PlayerOnline import GameWorld import ObjPool import time HorseLVStart = 1 def DoHorseOpen(curPlayer): PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseClassLV, 0) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseLV, HorseLVStart) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseExp, 0) skinID = GetDefaultHorseSkinID() PlayerControl.SetHorseSkinID(curPlayer, skinID) GameWorld.DebugLog("×øÆï¹¦ÄÜ¿ªÆô! skinID=%s" % (skinID)) SyncHorseClassInfo(curPlayer) RefreshHorseAttr(curPlayer) return True def PlayerHorseLogin(curPlayer): if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse): return SyncHorseClassInfo(curPlayer) SyncHorseSkinInfo(curPlayer) return #// B2 01 ×øÆïÉý¼¶ #tagCSHorseLVUP # #struct tagCSHorseLVUP #{ # tagHead Head; # BYTE IsQuick; // ÊÇ·ñ¿ìËÙÉý¼¶£¬0-Ö»ÏûºÄ1¸öµÀ¾ß£»1-ÏûºÄÉý1¼¶µÄµÀ¾ß #}; def OnHorseLVUP(index, curPackData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) isQuick = curPackData.IsQuick if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse): return classLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseClassLV) horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseLV) curExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseExp) classIpyData = IpyGameDataPY.GetIpyGameData("HorseClass", classLV) if not classIpyData: return maxLV = classIpyData.GetMaxHorseLV() if horseLV >= maxLV: GameWorld.DebugLog("×øÆï¸Ã½×ÒÑÂú¼¶! classLV=%s,horseLV=%s >= %s" % (classLV, horseLV, maxLV)) return needExp = classIpyData.GetLVUPItemCnt() # ËùÐèµÀ¾ßÊý£¬1¸ö=1µã¾­Ñé if needExp <= 0: GameWorld.DebugLog("×øÆï¸Ã½×ûÓÐÉý¼¶ÏûºÄ! classLV=%s,horseLV=%s,needExp=%s" % (classLV, horseLV, needExp)) return costItemCount = 0 if isQuick: costItemCount = max(0, needExp - curExp) elif curExp < needExp: costItemCount = 1 costItemID = IpyGameDataPY.GetFuncCfg("HorseUpItem", 1) if costItemID and costItemCount > 0: costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount) lackCnt = costItemCount - bindCnt - unBindCnt if lackCnt > 0: GameWorld.DebugLog("ÏûºÄµÀ¾ß²»×㣬ÎÞ·¨Éý¼¶×øÆï! costItemID=%s,costItemCount=%s,bindCnt=%s,unBindCnt=%s,lackCnt=%s" % (costItemID, costItemCount, bindCnt, unBindCnt, lackCnt)) return # ¿Û³ýÏûºÄ ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, costItemCount, ChConfig.ItemDel_Horse) addExp = costItemCount # Ôݹ̶¨1¸öµÀ¾ß=1µã¾­Ñé updExp = curExp + addExp GameWorld.DebugLog("×øÆï¼Ó¾­Ñé: classLV=%s,horseLV=%s,curExp=%s,costItemCount=%s,updExp=%s/%s" % (classLV, horseLV, curExp, costItemCount, updExp, needExp)) updHorseLV = horseLV if updExp >= needExp: updExp -= needExp updHorseLV += 1 GameWorld.DebugLog(" Éý¼¶: updHorseLV=%s,updExp=%s" % (updHorseLV, updExp)) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseLV, updHorseLV) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseExp, updExp) SyncHorseClassInfo(curPlayer) # ÓÐÉý¼¶¶îÍâ´¦Àí if updHorseLV > horseLV: RefreshHorseAttr(curPlayer) return #// B2 02 ×øÆï½ø½× #tagCSHorseClassUP # #struct tagCSHorseClassUP #{ # tagHead Head; #}; def OnHorseClassUP(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) playerID = curPlayer.GetPlayerID() if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Horse): return classLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseClassLV) horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseLV) classIpyData = IpyGameDataPY.GetIpyGameData("HorseClass", classLV) if not classIpyData: return maxLV = classIpyData.GetMaxHorseLV() if horseLV < maxLV: GameWorld.DebugLog("×øÆï¸Ã½×δÂú¼¶ÎÞ·¨Éý½×! classLV=%s,horseLV=%s < %s" % (classLV, horseLV, maxLV)) return updClassLV = classLV + 1 if not IpyGameDataPY.GetIpyGameDataNotLog("HorseClass", updClassLV): GameWorld.DebugLog("×øÆïÒÑÂú½×! classLV=%s" % (classLV)) return costItemID = IpyGameDataPY.GetFuncCfg("HorseUpItem", 2) costItemCnt = classIpyData.GetClassUPItemCnt() if not costItemID or not costItemCnt: return itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem) lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList({costItemID:costItemCnt}, itemPack) if lackItemDict: GameWorld.DebugLog("×øÆï½ø½×ÎïÆ·²»×ã! classLV=%s,costItemID=%s,costItemCnt=%s,lackItemDict=%s" % (classLV, costItemID, costItemCnt, lackItemDict), playerID) return ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "HorseClassUP") PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseClassLV, updClassLV) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseLV, HorseLVStart) GameWorld.DebugLog("×øÆï½ø½×: updClassLV=%s" % (updClassLV), playerID) SyncHorseClassInfo(curPlayer) RefreshHorseAttr(curPlayer) return def RefreshHorseAttr(curPlayer): CalcHorseAttr(curPlayer) PlayerOnline.GetOnlinePlayer(curPlayer).RefreshRoleAttr() return def CalcHorseAttr(curPlayer): playerID = curPlayer.GetPlayerID() attrDict = {} classLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseClassLV) horseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseLV) ipyDataMgr = IpyGameDataPY.IPY_Data() for index in range(ipyDataMgr.GetHorseClassCount()): ipyData = ipyDataMgr.GetHorseClassByIndex(index) ipyClassLV = ipyData.GetClassLV() if classLV < ipyClassLV: continue # ½×ÌØÊâÊôÐÔ specAttrIDList = ipyData.GetClassSpecAttrIDList() specAttrValueList = ipyData.GetClassSpecAttrValueList() for index, attrID in enumerate(specAttrIDList): attrValue = specAttrValueList[index] if len(specAttrValueList) > index else 0 attrDict[attrID] = attrDict.get(attrID, 0) + attrValue # ½×»ù´¡ÊôÐÔ attrIDList = ipyData.GetAttrIDList() attrValueList = ipyData.GetClassAttrValueList() for index, attrID in enumerate(attrIDList): attrValue = attrValueList[index] if len(attrValueList) > index else 0 attrDict[attrID] = attrDict.get(attrID, 0) + attrValue # ½×µÈ¼¶ÊôÐÔ if ipyClassLV < classLV: attrLV = ipyData.GetMaxHorseLV() else: attrLV = horseLV perLVAttrValueList = ipyData.GetPerLVAttrValueList() for index, attrID in enumerate(attrIDList): attrValue = perLVAttrValueList[index] if len(perLVAttrValueList) > index else 0 attrDict[attrID] = attrDict.get(attrID, 0) + attrValue * attrLV #GameWorld.DebugLog("×øÆï½×ÊôÐÔ: %s" % attrDict, playerID) # Íâ¹ÛÊôÐÔ for index in range(ipyDataMgr.GetHorseSkinCount()): ipyData = ipyDataMgr.GetHorseSkinByIndex(index) horseSkinID = ipyData.GetSkinID() if not IsHorseSkinCanUse(curPlayer, horseSkinID, ipyData): continue attrIDList = ipyData.GetAttrIDList() if not attrIDList: continue initAttrValueList = ipyData.GetInitAttrValueList() perStarAddList = ipyData.GetAttrPerStarAddList() star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseSkinStar % horseSkinID) for aIndex, attrID in enumerate(attrIDList): initValue = initAttrValueList[aIndex] if len(initAttrValueList) > aIndex else 0 perStarAdd = perStarAddList[aIndex] if len(perStarAddList) > aIndex else 0 attrValue = initValue + perStarAdd * star attrDict[attrID] = attrDict.get(attrID, 0) + attrValue # ±£´æ¼ÆËãÖµ GameWorld.DebugLog("×øÆïÊôÐÔ: %s" % attrDict, playerID) PlayerOnline.GetOnlinePlayer(curPlayer).SetCalcAttr(ChConfig.Def_CalcAttr_Horse, attrDict) return def SyncHorseClassInfo(curPlayer): clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCHorseClassInfo) clientPack.ClassLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseClassLV) clientPack.HorseLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseLV) clientPack.Exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseExp) NetPackCommon.SendFakePack(curPlayer, clientPack) return ## ----------------------------------------- Íâ¹Û -------------------------------------------------- #// B2 03 ×øÆïÍâ¹Û²Ù×÷ #tagCSHorseSkinOP # #struct tagCSHorseSkinOP #{ # tagHead Head; # BYTE OPType; // ²Ù×÷ 1-¼¤»î£»2-Åå´÷£»3-ÉýÐÇ # BYTE SkinID; // Íâ¹ÛID£¬Åå´÷ʱ·¢0¼´ÎªÐ¶Ï #}; def OnHorseSkinOP(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) opType = clientData.OPType horseSkinID = clientData.SkinID # ¼¤»î if opType == 1: AddHorseSkin(curPlayer, horseSkinID) # Åå´÷ elif opType == 2: OnUseHorseSkin(curPlayer, horseSkinID) # Éý¼¶ elif opType == 3: OnHorseSkinStarUP(curPlayer, horseSkinID) return def OnMinute(curPlayer): curTime = int(time.time()) delIDList = [] ipyDataMgr = IpyGameDataPY.IPY_Data() for index in range(ipyDataMgr.GetHorseSkinCount()): ipyData = ipyDataMgr.GetHorseSkinByIndex(index) horseSkinID = ipyData.GetSkinID() if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorseSkinState, horseSkinID): # δ¼¤»îµÄ²»´¦Àí continue endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseSkinEndTime % horseSkinID) if not endTime or endTime > curTime: # ÓÀ¾Ã»òδ¹ýÆÚ continue if DelHorseSkin(curPlayer, horseSkinID, False, "HorseSkinTimeout"): delIDList.append(horseSkinID) if delIDList: RefreshHorseAttr(curPlayer) return def AddHorseSkin(curPlayer, horseSkinID, setExpireTimes=None, isFree=False): if horseSkinID <= 0: return playerID = curPlayer.GetPlayerID() ipyData = IpyGameDataPY.GetIpyGameData("HorseSkin", horseSkinID) if not ipyData: return if ipyData.GetUnlockWay() != 2: GameWorld.DebugLog("·ÇµÀ¾ß¼¤»îµÄ²»ÓÃÌí¼Ó: horseSkinID=%s" % (horseSkinID), playerID) return if not isFree: itemID = ipyData.GetUnlockValue() itemCount = ipyData.GetUnlockNeedCnt() if not itemID or not itemCount: return needItemList = [[itemID, itemCount]] itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem) lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack) if lackItemDict: GameWorld.DebugLog("¼¤»îËùÐèÎïÆ·²»×ã! horseSkinID=%s,lackItemDict=%s" % (horseSkinID, lackItemDict), playerID) return ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "AddHorseSkin") ipyExpireSeconds = ipyData.GetExpireMinutes() * 60 curTime = int(time.time()) state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorseSkinState, horseSkinID) endTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseSkinEndTime % horseSkinID) GameWorld.Log("Ìí¼Ó×øÆïÍâ¹Û: horseSkinID=%s,setExpireTimes=%s,state=%s,endTime=%s,ipyExpireSeconds=%s,curTime=%s" % (horseSkinID, setExpireTimes, state, endTime, ipyExpireSeconds, curTime), playerID) updEndTime = endTime # Ö¸¶¨Ê±³¤µÄ£¬ÈçGMÖ¸¶¨ if setExpireTimes > 0: updEndTime = curTime + setExpireTimes GameWorld.Log(" Ö¸¶¨Ê±³¤: horseSkinID=%s,updEndTime=%s" % (horseSkinID, updEndTime), playerID) # ÓÀ¾Ã elif ipyExpireSeconds == 0 or setExpireTimes == 0: updEndTime = 0 GameWorld.Log(" ÓÀ¾Ãʱ³¤: horseSkinID=%s,updEndTime=%s" % (horseSkinID, updEndTime), playerID) else: # δ¹ýÆÚ if endTime > curTime: updEndTime = endTime + ipyExpireSeconds GameWorld.Log(" ÀÛ¼Óʱ³¤: horseSkinID=%s,updEndTime=%s" % (horseSkinID, updEndTime), playerID) else: updEndTime = curTime + ipyExpireSeconds GameWorld.Log(" ÖØÐ¼¤»î: horseSkinID=%s,updEndTime=%s" % (horseSkinID, updEndTime), playerID) GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorseSkinState, horseSkinID, 1) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseSkinEndTime % horseSkinID, updEndTime) RefreshHorseAttr(curPlayer) SyncHorseSkinInfo(curPlayer, [horseSkinID]) return True def DelHorseSkin(curPlayer, horseSkinID, isRefreshAttr=True, notifyMail=""): playerID = curPlayer.GetPlayerID() ipyData = IpyGameDataPY.GetIpyGameData("HorseSkin", horseSkinID) if not ipyData: return if not GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorseSkinState, horseSkinID): return GameWorld.Log("ɾ³ý×øÆïÍâ¹Û: horseSkinID=%s,notifyMail=%s" % (horseSkinID, notifyMail), playerID) GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorseSkinState, horseSkinID, 0) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseSkinEndTime % horseSkinID, 0) # ÐǼ¶²»ÖØÖã¬ÖØÐ¼¤»îºóÔÙ´ÎÉúЧ if PlayerControl.GetHorseSkinID(curPlayer) == horseSkinID: defaultSkinID = GetDefaultHorseSkinID() PlayerControl.SetHorseSkinID(curPlayer, defaultSkinID) GameWorld.DebugLog("Íæ¼ÒÅå´÷µÄ×øÆïÍâ¹Û±»É¾³ý£¬Ëæ»úÖØÖÃĬÈÏ! defaultSkinID=%s" % defaultSkinID, playerID) if isRefreshAttr: RefreshHorseAttr(curPlayer) SyncHorseSkinInfo(curPlayer, [horseSkinID]) if notifyMail: PlayerControl.SendMailByKey(notifyMail, [playerID], [], [horseSkinID]) return True def GetDefaultHorseSkinID(): ipyDataMgr = IpyGameDataPY.IPY_Data() for index in range(ipyDataMgr.GetHorseSkinCount()): ipyData = ipyDataMgr.GetHorseSkinByIndex(index) horseSkinID = ipyData.GetSkinID() if ipyData.GetUnlockWay() != 1: continue if ipyData.GetUnlockValue() > 0: # È¡0½×µÄ continue return horseSkinID return 0 def IsHorseSkinCanUse(curPlayer, horseSkinID, ipyData=None): ## ×øÆïÍâ¹ÛÊÇ·ñ¿ÉÓà state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorseSkinState, horseSkinID) if state: return True if not ipyData: ipyData = IpyGameDataPY.GetIpyGameData("HorseSkin", horseSkinID) if ipyData: unlockWay = ipyData.GetUnlockWay() if unlockWay == 1: classLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseClassLV) if classLV >= ipyData.GetUnlockValue(): return True return False def OnUseHorseSkin(curPlayer, horseSkinID): playerID = curPlayer.GetPlayerID() if horseSkinID and not IsHorseSkinCanUse(curPlayer, horseSkinID): GameWorld.DebugLog("¸Ã×øÆïÍâ¹Û²»¿ÉÓÃ! horseSkinID=%s" % (horseSkinID), playerID) return PlayerControl.SetHorseSkinID(curPlayer, horseSkinID) return def OnHorseSkinStarUP(curPlayer, horseSkinID): playerID = curPlayer.GetPlayerID() if not IsHorseSkinCanUse(curPlayer, horseSkinID): GameWorld.DebugLog("¸Ã×øÆïÍâ¹Û²»¿ÉÓÃ! horseSkinID=%s" % (horseSkinID), playerID) return ipyData = IpyGameDataPY.GetIpyGameData("HorseSkin", horseSkinID) if not ipyData: return starMax = ipyData.GetStarMax() curStar = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseSkinStar % horseSkinID) if curStar >= starMax: GameWorld.DebugLog("ÐǼ¶ÒÑÂú! horseSkinID=%s,curStar=%s >= %s" % (horseSkinID, curStar, starMax), playerID) return if ipyData.GetUnlockWay() != 2: return itemID = ipyData.GetUnlockValue() itemCount = ipyData.GetUnlockNeedCnt() if not itemID or not itemCount: return needItemList = [[itemID, itemCount]] itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem) lackItemDict, delInfoDict = ItemCommon.GetCostItemIndexList(needItemList, itemPack) if lackItemDict: GameWorld.DebugLog("ÉýÐÇËùÐèÎïÆ·²»×ã! horseSkinID=%s,lackItemDict=%s" % (horseSkinID, lackItemDict), playerID) return ItemCommon.DelCostItem(curPlayer, itemPack, delInfoDict, "HorseSkinStarUP") nextStar = curStar + 1 GameWorld.DebugLog("ÉýÐÇ! horseSkinID=%s,nextStar=%s" % (horseSkinID, nextStar), playerID) SetHorseSkinStar(curPlayer, horseSkinID, nextStar) return def SetHorseSkinStar(curPlayer, horseSkinID, setStar): if not IsHorseSkinCanUse(curPlayer, horseSkinID): return ipyData = IpyGameDataPY.GetIpyGameData("HorseSkin", horseSkinID) if not ipyData: return setStar = min(setStar, ipyData.GetStarMax()) PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HorseSkinStar % horseSkinID, setStar) RefreshHorseAttr(curPlayer) SyncHorseSkinInfo(curPlayer, [horseSkinID]) return True def SyncHorseSkinInfo(curPlayer, horseSkinIDList=None): if horseSkinIDList == None: syncIDList = [] ipyDataMgr = IpyGameDataPY.IPY_Data() for index in range(ipyDataMgr.GetHorseSkinCount()): ipyData = ipyDataMgr.GetHorseSkinByIndex(index) syncIDList.append(ipyData.GetSkinID()) else: syncIDList = horseSkinIDList horseSkinList = [] for horseSkinID in syncIDList: state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_HorseSkinState, horseSkinID) if not state and horseSkinIDList == None: continue horseSkin = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCHorseSkin) horseSkin.HorseSkinID = horseSkinID horseSkin.State = state horseSkin.EndTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseSkinEndTime % horseSkinID) horseSkin.Star = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HorseSkinStar % horseSkinID) horseSkinList.append(horseSkin) if not horseSkinList: return clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCHorseSkinInfo) clientPack.HorseSkinList = horseSkinList clientPack.Count = len(clientPack.HorseSkinList) NetPackCommon.SendFakePack(curPlayer, clientPack) return ## -------------------------------------------------------------------------------------------------