#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package GameWorldLogic.FBProcess.GameLogic_MainLevel
|
#
|
# @todo:Ö÷Ï߹ؿ¨
|
# @author hxp
|
# @date 2025-07-10
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: Ö÷Ï߹ؿ¨
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2025-07-10 17:00"""
|
#-------------------------------------------------------------------------------
|
|
import ChConfig
|
import GameWorld
|
import ShareDefine
|
import SkillCommon
|
import IpyGameDataPY
|
import PlayerControl
|
import ChPyNetSendPack
|
import ItemControler
|
import IPY_GameWorld
|
import NetPackCommon
|
import TurnAttack
|
import ItemCommon
|
import NPCCommon
|
import random
|
|
def OnFBPlayerOnLogin(curPlayer):
|
SyncDropBootyInfo(curPlayer)
|
return
|
|
def OnFBPlayerOnDay(curPlayer):
|
ResetBootyDropToday(curPlayer)
|
return
|
|
def ResetBootyDropToday(curPlayer):
|
bootyItemIDList = GetBootyItemIDList()
|
for itemID in bootyItemIDList:
|
if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID):
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BootyDropToday % itemID, 0)
|
SyncDropBootyInfo(curPlayer)
|
return
|
|
def SetBootyDropToday(curPlayer, itemID, updDropToday):
|
updDropToday = min(updDropToday, ChConfig.Def_UpperLimit_DWord)
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BootyDropToday % itemID, updDropToday)
|
GameWorld.DebugLog("¸üнñÈÕµôÂäÕ½ÀûÆ·Êý: itemID=%s,updDropToday=%s" % (itemID, updDropToday), curPlayer.GetPlayerID())
|
SyncDropBootyInfo(curPlayer, itemID)
|
return
|
|
def GetBootyItemIDList():
|
## »ñÈ¡ËùÓеÄÕ½ÀûÆ·ID
|
ipyDataMgr = IpyGameDataPY.IPY_Data()
|
chapterCount = ipyDataMgr.GetMainChapterCount()
|
if not chapterCount:
|
return []
|
ipyData = ipyDataMgr.GetMainChapterByIndex(chapterCount - 1)
|
return [booty[0] for booty in ipyData.GetDailyBootyUpperList()]
|
|
def OnPlayerLineupAttackSuccess(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
|
## »ØºÏÕ½¶·Ö÷¶¯·¢ÆðµÄÍæ¼ÒÕóÈÝÊͷż¼Äܳɹ¦
|
|
if mapID == ChConfig.Def_FBMapID_Main:
|
__doCostZhanchui(curPlayer, atkObj, curSkill)
|
|
return
|
|
def __doCostZhanchui(curPlayer, atkObj, curSkill):
|
## ¿Û³ýÕ½´¸ÏûºÄ
|
costZhanchui = 0
|
isXP = SkillCommon.isXPSkill(curSkill)
|
turnBattleType = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnBattleType)
|
if isXP:
|
costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 2)
|
elif turnBattleType == ChConfig.TurnBattleType_Combo:
|
costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 3)
|
elif turnBattleType == ChConfig.TurnBattleType_AtkBack:
|
costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 4)
|
elif SkillCommon.isTurnNormalAtkSkill(curSkill):
|
costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 1)
|
|
if costZhanchui <= 0:
|
return
|
|
fightPoint = max(curPlayer.GetFightPoint(), 1) # Ö÷ÏßÕ½¶·ÏûºÄ±¶Öµ£¬Ä¬ÈÏ1
|
costZhanchuiTotal = costZhanchui * fightPoint
|
if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, costZhanchuiTotal, isNotify=False):
|
# ²»×ãʱ£¬ÓжàÉÙ¿Û¶àÉÙ
|
nowMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao)
|
PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, min(nowMoney, costZhanchuiTotal), isNotify=False)
|
|
return
|
|
def OnPlayerLineupAttackResult(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
|
|
if mapID == ChConfig.Def_FBMapID_Main:
|
__doKillAward(curPlayer, atkObj, mapID, funcLineID)
|
|
return
|
|
def __doKillAward(curPlayer, atkObj, mapID, funcLineID):
|
## ¼ÆËã»÷ɱ½±Àø
|
turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(atkObj.GetID())
|
if not turnFight:
|
return
|
|
unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
|
if not turnFight.playerKillObjIDList:
|
unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
|
GameWorld.DebugLog("ûÓл÷ɱ²»ÐèÒª´¦Àí! unXiantaoCntExp=%s,unXiantaoCntEquip=%s" % (unXiantaoCntExp, unXiantaoCntEquip))
|
return
|
killCnt = len(turnFight.playerKillObjIDList)
|
# Ö±½ÓÖØÖ㬷ÀÖ¹Òì³£Ê±ÖØ¸´½áËã
|
turnFight.playerKillObjIDList = []
|
|
# ½áËã¾Ñé
|
if unXiantaoCntExp:
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, 0)
|
perExp = IpyGameDataPY.GetFuncCfg("Mainline", 1) # ÿ¸öÕ½´¸Ôö¼Ó¾Ñé
|
totalExp = unXiantaoCntExp * perExp
|
GameWorld.DebugLog("Ôö¼Ó¾Ñé: totalExp=%s,unXiantaoCntExp=%s" % (totalExp, unXiantaoCntExp))
|
PlayerControl.PlayerControl(curPlayer).AddExp(totalExp, ShareDefine.Def_ViewExpType_KillNPC)
|
|
__doMainDrop(curPlayer, killCnt)
|
return
|
|
def __doMainDrop(curPlayer, killCnt):
|
# ×°±¸µôÂä
|
__doDropEquip(curPlayer)
|
|
playerID = curPlayer.GetPlayerID()
|
DailyBootyUpperList, BootyWeightList = [], []
|
chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
|
chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
|
if chapterIpyData:
|
DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
|
BootyWeightList = chapterIpyData.GetBootyWeightList()
|
|
bootyDropUpperDict = {k:v for k, v in DailyBootyUpperList}
|
GameWorld.DebugLog("¿ÉµôÂäÕ½ÀûÆ·ÉÏÏÞ: chapterID=%s,%s,killCnt=%s" % (chapterID, bootyDropUpperDict, killCnt), playerID)
|
|
# ÆäËûÕ½ÀûÆ·µôÂä
|
for _ in range(killCnt):
|
dropInfo = GameWorld.GetResultByWeightList(BootyWeightList)
|
if not dropInfo:
|
continue
|
itemID = dropInfo[0]
|
if not itemID:
|
GameWorld.DebugLog("±¾´Î²»µôÂäÕ½ÀûÆ·!", playerID)
|
continue
|
if itemID not in bootyDropUpperDict:
|
GameWorld.DebugLog("¸ÃÕ½ÀûƷδ½âËø! itemID=%s" % itemID, playerID)
|
continue
|
todyDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
|
dropUpper = bootyDropUpperDict.get(itemID, 0)
|
if todyDropCnt >= dropUpper:
|
GameWorld.DebugLog("Õ½ÀûÆ·ÒÑ´ï½ñÈÕµôÂäÉÏÏÞ! itemID=%s,todyDropCnt=%s >= %s" % (itemID, todyDropCnt, dropUpper), playerID)
|
continue
|
|
dropMin = dropInfo[1] if len(dropInfo) > 1 else 1
|
dropMax = dropInfo[2] if len(dropInfo) > 2 else 1
|
|
if dropMin == dropMax:
|
dropCnt = dropMin
|
else:
|
dropCnt = random.randint(dropMin, dropMax)
|
dropCnt = min(dropCnt, dropUpper - todyDropCnt)
|
|
GameWorld.DebugLog("µôÂäÕ½ÀûÆ·! itemID=%s,dropCnt=%s" % (itemID, dropCnt), playerID)
|
curItem = ItemControler.GetOutPutItemObj(itemID, dropCnt, False, curPlayer=curPlayer)
|
if curItem == None:
|
continue
|
curItem.SetIsBind(1) # Ϊ1ʱ´ú±íÊǵôÂä
|
if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
|
continue
|
SetBootyDropToday(curPlayer, itemID, todyDropCnt + dropCnt)
|
|
return
|
|
def __doDropEquip(curPlayer):
|
## Ö÷ÏßµôÂä×°±¸
|
unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
|
dropOneNeed = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 1) # ÿÏûºÄX¸öÕ½´¸µôÂäÒ»¼þ×°±¸
|
dropEquipCnt = unXiantaoCntEquip / dropOneNeed
|
if dropEquipCnt <= 0:
|
GameWorld.DebugLog("Ö÷ÏßÔݲ»ÄܵôÂä! unXiantaoCntEquip=%s,dropOneNeed=%s,dropEquipCnt=%s" % (unXiantaoCntEquip, dropOneNeed, dropEquipCnt))
|
return
|
dropEquipCnt = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptIdentify, dropEquipCnt)
|
if not dropEquipCnt:
|
GameWorld.DebugLog("µôÂä¼ø¶¨±³°üûÓпռä!")
|
return
|
|
playerID = curPlayer.GetPlayerID()
|
treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)
|
ipyData = IpyGameDataPY.GetIpyGameData("TreeLV", treeLV)
|
if not ipyData:
|
return
|
equipColorRateList = ipyData.GetEquipColorRateList()
|
GameWorld.DebugLog("Ö÷ÏßµôÂä×°±¸: unXiantaoCntEquip=%s,dropEquipCnt=%s,treeLV=%s,equipColorRateList=%s" % (unXiantaoCntEquip, dropEquipCnt, treeLV, equipColorRateList), playerID)
|
|
maxRate = 10000
|
totalRate = 0
|
colorRateList = []
|
for equipColor, colorRate in enumerate(equipColorRateList, 1):
|
if not colorRate:
|
continue
|
totalRate += colorRate
|
colorRateList.append([totalRate, equipColor])
|
|
if totalRate != maxRate:
|
GameWorld.SendGameError("GameWarning", "CutTreeTotalRateError:%s!=%s,treeLV=%s" % (totalRate, maxRate, treeLV))
|
if not colorRateList:
|
return
|
GameWorld.DebugLog(" colorRateList=%s,totalRate=%s" % (colorRateList, totalRate), playerID)
|
|
for _ in range(dropEquipCnt):
|
itemColor = GameWorld.GetResultByRandomList(colorRateList)
|
if not itemColor:
|
continue
|
equipIDList = NPCCommon.__GetEquipIDList(0, color=itemColor, findType="MainEquipDrop")
|
if not equipIDList:
|
continue
|
randEquipID = random.choice(equipIDList)
|
|
curItem = ItemControler.GetOutPutItemObj(randEquipID, 1, False, curPlayer=curPlayer)
|
if curItem == None:
|
continue
|
curItem.SetIsBind(1) # Ϊ1ʱ´ú±íÊǵôÂä
|
|
#GameWorld.DebugLog("µôÂä×°±¸: randEquipID=%s,%s" % (randEquipID, curItem.GetGUID()), playerID)
|
if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
|
continue
|
|
unXiantaoCntEquip -= dropOneNeed
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
|
|
return
|
|
def GMTestKillDrop(curPlayer, killCnt):
|
## GM²âÊÔµôÂä
|
unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + killCnt
|
PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
|
__doMainDrop(curPlayer, killCnt)
|
|
unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
|
GameWorld.DebugAnswer(curPlayer, "Ê£Óàδ½áËã×°±¸µôÂäÕ½´¸Êý:%s" % unXiantaoCntEquip)
|
return
|
|
#// B4 15 Ö÷ÏßµôÂäÎïÆ·²Ù×÷ #tagCSMainDropItemOP
|
#
|
#struct tagCSMainDropItemOP
|
#{
|
# tagHead Head;
|
# BYTE Count;
|
# WORD IndexList[Count]; // µôÂä±³°üÖеÄÎïÆ·¸ñ×ÓË÷ÒýÁбí
|
# BYTE OPType; // 0 - ʰȡ·Ç×°±¸ÎïÆ·£»1 - ·Ö½â£»2 - ´©´÷/Ìæ»»£»
|
# BYTE OPValue; // ²Ù×÷¶îÍâÖ¸ÁîÖµ£¬ÓɲÙ×÷ÀàÐ;ö¶¨£¬Èç´©´÷ʱ¿É·¢ËÍ´©´÷ºóÊÇ·ñ×Ô¶¯·Ö½â
|
#};
|
def OnMainDropItemOP(index, clientData, tick):
|
curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
itemIndexList = clientData.IndexList
|
opType = clientData.OPType
|
opValue = clientData.OPValue
|
|
if opType == 2:
|
__doEquipMainEquip(curPlayer, itemIndexList, opValue)
|
elif opType == 1:
|
__doDecomposeMainEquip(curPlayer, itemIndexList)
|
else:
|
__doPickupMainItem(curPlayer, itemIndexList)
|
|
return
|
|
def __doEquipMainEquip(curPlayer, itemIndexList, isAutoDecompose):
|
playerID = curPlayer.GetPlayerID()
|
GameWorld.DebugLog("´©´÷Ö÷Ïß×°±¸: itemIndexList=%s,isAutoDecompose=%s" % (itemIndexList, isAutoDecompose), playerID)
|
IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
|
|
decomposeIndexList = []
|
for itemIndex in itemIndexList:
|
if itemIndex < 0 or itemIndex >= IdentifyPack.GetCount():
|
continue
|
curEquip = IdentifyPack.GetAt(itemIndex)
|
if not ItemCommon.CheckItemCanUse(curEquip):
|
GameWorld.DebugLog("ÎïÆ·Îª¿Õ»ò²»¿ÉÓÃ: itemIndex=%s" % itemIndex, playerID)
|
continue
|
|
if not ItemCommon.GetIsMainEquip(curEquip):
|
GameWorld.DebugLog("·ÇÖ÷Ïß×°±¸: itemIndex=%s" % itemIndex, playerID)
|
continue
|
|
itemID = curEquip.GetItemTypeID()
|
equipPlace = curEquip.GetEquipPlace()
|
equipPlaceIndex = equipPlace - 1 # Ôݹ̶¨Ö±½Ó×°±¸Î»-1
|
|
GameWorld.DebugLog(" itemIndex=%s,itemID=%s,equipPlace=%s,equipPlaceIndex=%s"
|
% (itemIndex, itemID, equipPlace, equipPlaceIndex), playerID)
|
equipPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)
|
if equipPlaceIndex < 0 or equipPlaceIndex >= equipPack.GetCount():
|
GameWorld.ErrLog("Ö÷Ïß×°±¸¶ÔӦװ±¸Î»ÖÃË÷ÒýÒì³£: itemIndex=%s,equipPlace=%s,equipPlaceIndex=%s"
|
% (itemIndex, equipPlace, equipPlaceIndex), playerID)
|
continue
|
destEquip = equipPack.GetAt(equipPlaceIndex)
|
canDecomp = ItemCommon.CheckItemCanUse(destEquip)
|
|
curEquip.GetItem().SetIsBind(0) # ´©´÷Ê±ÖØÖã¬È¡Ô´SingleItemÐ޸IJ»Í¨Öª
|
if not ItemCommon.DoLogicSwitchItem(curPlayer, curEquip, destEquip, IPY_GameWorld.rptEquip):
|
continue
|
|
if isAutoDecompose and canDecomp:
|
decomposeIndexList.append(itemIndex)
|
|
if decomposeIndexList:
|
__doDecomposeMainEquip(curPlayer, decomposeIndexList)
|
|
# Ë¢ÊôÐÔ
|
|
return
|
|
def __doDecomposeMainEquip(curPlayer, itemIndexList):
|
playerID = curPlayer.GetPlayerID()
|
GameWorld.DebugLog("·Ö½âÖ÷Ïß×°±¸: itemIndexList=%s" % (itemIndexList), playerID)
|
IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
|
|
moneyType = IpyGameDataPY.GetFuncCfg("MainEquipDrop", 2)
|
if not moneyType:
|
return
|
|
moneyTotal = 0
|
|
decomposeIndexList = []
|
for itemIndex in itemIndexList:
|
if itemIndex < 0 or itemIndex >= IdentifyPack.GetCount():
|
continue
|
curEquip = IdentifyPack.GetAt(itemIndex)
|
if not ItemCommon.CheckItemCanUse(curEquip):
|
GameWorld.DebugLog("ÎïÆ·Îª¿Õ»ò²»¿ÉÓÃ: itemIndex=%s" % itemIndex, playerID)
|
continue
|
|
if not ItemCommon.GetIsMainEquip(curEquip):
|
GameWorld.DebugLog("·ÇÖ÷Ïß×°±¸: itemIndex=%s" % itemIndex, playerID)
|
continue
|
itemColor = curEquip.GetItemColor()
|
|
colorIpyData = IpyGameDataPY.GetIpyGameData("EquipColor", itemColor)
|
if not colorIpyData:
|
return
|
moneyBase = colorIpyData.GetMoneyBase() # ·Ö½â»õ±Ò»ù´¡
|
if not moneyBase:
|
return
|
# ¿ÉÒÔ´¦ÀíһЩ¼Ó³É
|
|
decomposeMoney = moneyBase
|
|
moneyTotal += decomposeMoney
|
GameWorld.DebugLog(" itemIndex=%s,itemColor=%s,moneyBase=%s,decomposeMoney=%s,%s"
|
% (itemIndex, itemColor, moneyBase, decomposeMoney, moneyTotal), playerID)
|
|
ItemCommon.DelItem(curPlayer, curEquip, curEquip.GetCount(), True, ChConfig.ItemDel_EquipDecompose)
|
decomposeIndexList.append(itemIndex)
|
|
if not moneyTotal:
|
return
|
|
PlayerControl.GiveMoney(curPlayer, moneyType, moneyTotal, "DecomposeMainEquip", isSysHint=False)
|
return
|
|
def __doPickupMainItem(curPlayer, itemIndexList):
|
playerID = curPlayer.GetPlayerID()
|
GameWorld.DebugLog("ʰȡÖ÷ÏßµôÂäÕ½ÀûÆ·! itemIndexList=%s" % itemIndexList, playerID)
|
IdentifyPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptIdentify)
|
|
itemControl = ItemControler.PlayerItemControler(curPlayer)
|
|
for itemIndex in itemIndexList:
|
if itemIndex < 0 or itemIndex >= IdentifyPack.GetCount():
|
continue
|
curItem = IdentifyPack.GetAt(itemIndex)
|
if not ItemCommon.CheckItemCanUse(curItem):
|
GameWorld.DebugLog("ÎïÆ·Îª¿Õ»ò²»¿ÉÓÃ: itemIndex=%s" % itemIndex, playerID)
|
continue
|
|
if ItemCommon.GetIsMainEquip(curItem):
|
GameWorld.DebugLog("Ö÷Ïß×°±¸²»¿Éʰȡ: itemIndex=%s" % itemIndex, playerID)
|
continue
|
itemID = curItem.GetItemTypeID()
|
item = curItem.GetItem()
|
itemCount = ItemControler.GetItemCount(curItem)
|
GameWorld.DebugLog("Ö÷ÏßÎïÆ·Ê°È¡: itemIndex=%s,itemID=%s,itemCount=%s" % (itemIndex, itemID, itemCount), playerID)
|
if not itemControl.PutInItem(IPY_GameWorld.rptItem, item):
|
return
|
|
curItem.Wipe()
|
|
return
|
|
def SyncDropBootyInfo(curPlayer, itemID=0):
|
if not itemID:
|
syncItemIDList = GetBootyItemIDList()
|
else:
|
syncItemIDList = [itemID]
|
clientPack = ChPyNetSendPack.tagSCDropBootyInfo()
|
clientPack.DropBootyList = []
|
for itemID in syncItemIDList:
|
dropBooty = ChPyNetSendPack.tagSCDropBooty()
|
dropBooty.ItemID = itemID
|
dropBooty.TodayDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
|
clientPack.DropBootyList.append(dropBooty)
|
clientPack.Count = len(clientPack.DropBootyList)
|
NetPackCommon.SendFakePack(curPlayer, clientPack)
|
return
|