From 180eab3510f793ed008e9504976c3b3063f7ca6d Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 18 十一月 2025 18:21:52 +0800
Subject: [PATCH] 110 【主界面】仙树升级-服务端(免费减时修改为充能减时;特权支持充能额外上限;广告奖励支持领取充能奖励;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py       |   98 ++++++++++++++++++++++++++------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py         |   16 ++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py           |    4 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py         |   10 ++-
 PySysDB/PySysDBPY.h                                                                            |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetTree.py     |   17 +++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldInvest.py |   10 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                |    4 
 8 files changed, 126 insertions(+), 34 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 441f8df..66c3e52 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -1099,6 +1099,7 @@
 	BYTE		ADCntMax;	//每日次数
 	list		ADAwardItemList;	//广告奖励物品列表
 	DWORD		ADMapID;	//对应副本ID,默认给该副本1次次数
+	BYTE		ADAwardType;	//其他奖励类型
 };
 
 //成就表
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 89da7d2..61e0d63 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3792,8 +3792,8 @@
 Def_PDict_TreeLVUPState = "TreeLVUPState" # 仙树升级状态;0-未升级;1-升级中
 Def_PDict_TreeLVUPRemainTime = "TreeLVUPRemainTime" # 仙树升级剩余时间,秒
 Def_PDict_TreeLVUPRefreshTime = "TreeLVUPRefreshTime" # 仙树升级上次刷新时间戳
-Def_PDict_TreeFreeTimeCnt = "TreeFreeTimeCnt" # 今日已领取免费减时次数,过天重置
-Def_PDict_TreeFreeTimeLast = "TreeFreeTimeLast" # 今日上次领取免费减时时间戳,过天重置
+Def_PDict_TreeEnergy = "TreeEnergy" # 当前可用充能次数
+Def_PDict_TreeEnergyTimeLast = "TreeEnergyTimeLast" # 上次获得免费充能次数时间戳
 
 #历练秘笈
 Def_PDict_LLMJLVInfo = "LLMJLVInfo" # 秘笈等级,消耗战锤*100 + 秘笈等级
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index d28ec06..799da4b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -34818,8 +34818,8 @@
                   ("TreeLV", c_ubyte),    # 当前仙树等级
                   ("LVUPState", c_ubyte),    # 0-非升级中;1-升级中
                   ("LVUPRemainTime", c_int),    # 升级剩余时间,秒;当升级中且倒计时为0时可发送B223执行升级包进行升级
-                  ("FreeTimeCnt", c_ubyte),    # 今日已免费减时次数
-                  ("FreeTimeLast", c_int),    # 上次免费减时时间戳
+                  ("Energy", c_ubyte),    # 当前累计充能次数
+                  ("EnergyTimeLast", c_int),    # 上次获得充能次数时间戳
                   ]
 
     def __init__(self):
@@ -34839,8 +34839,8 @@
         self.TreeLV = 0
         self.LVUPState = 0
         self.LVUPRemainTime = 0
-        self.FreeTimeCnt = 0
-        self.FreeTimeLast = 0
+        self.Energy = 0
+        self.EnergyTimeLast = 0
         return
 
     def GetLength(self):
@@ -34856,8 +34856,8 @@
                                 TreeLV:%d,
                                 LVUPState:%d,
                                 LVUPRemainTime:%d,
-                                FreeTimeCnt:%d,
-                                FreeTimeLast:%d
+                                Energy:%d,
+                                EnergyTimeLast:%d
                                 '''\
                                 %(
                                 self.Cmd,
@@ -34865,8 +34865,8 @@
                                 self.TreeLV,
                                 self.LVUPState,
                                 self.LVUPRemainTime,
-                                self.FreeTimeCnt,
-                                self.FreeTimeLast
+                                self.Energy,
+                                self.EnergyTimeLast
                                 )
         return DumpString
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetTree.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetTree.py
index 3da5631..731ef65 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetTree.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetTree.py
@@ -31,9 +31,26 @@
 def OnExec(curPlayer, cmdList):
     if not cmdList:
         GameWorld.DebugAnswer(curPlayer, "设置仙树: SetTree 等级 剩余时间秒")
+        GameWorld.DebugAnswer(curPlayer, "充能次数: SetTree e 次数 [已累计分钟]")
         return
     
     treeLV = cmdList[0]
+    if treeLV == "e":
+        energy = cmdList[1] if len(cmdList) > 1 else 0
+        energyTime = cmdList[2] if len(cmdList) > 2 else 0
+        energyTime *= 60
+        energyMax = PlayerTree.GetTreeEnergyMax(curPlayer)
+        if energy >= energyMax:
+            energy = energyMax
+            timeLast = 0
+        else:
+            timeLast = int(time.time()) - energyTime
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeEnergy, energy)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeEnergyTimeLast, timeLast)
+        GameWorld.DebugAnswer(curPlayer, "充能次数:%s/%s,累计秒:%s" % (energy, energyMax, energyTime))
+        PlayerTree.SyncTreeInfo(curPlayer)
+        return
+    
     remainTime = cmdList[1] if len(cmdList) > 1 else 0
     ipyData = IpyGameDataPY.GetIpyGameData("TreeLV", treeLV)
     if not ipyData:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 20e83ad..cac39a9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -905,6 +905,7 @@
                         ("BYTE", "ADCntMax", 0),
                         ("list", "ADAwardItemList", 0),
                         ("DWORD", "ADMapID", 0),
+                        ("BYTE", "ADAwardType", 0),
                         ),
 
                 "Success":(
@@ -3503,7 +3504,8 @@
     def GetADID(self): return self.attrTuple[0] # DWORD
     def GetADCntMax(self): return self.attrTuple[1] # 每日次数 BYTE
     def GetADAwardItemList(self): return self.attrTuple[2] # 广告奖励物品列表 list
-    def GetADMapID(self): return self.attrTuple[3] # 对应副本ID,默认给该副本1次次数 DWORD
+    def GetADMapID(self): return self.attrTuple[3] # 对应副本ID,默认给该副本1次次数 DWORD
+    def GetADAwardType(self): return self.attrTuple[4] # 其他奖励类型 BYTE
 
 # 成就表
 class IPY_Success():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index 76605b3..f5bf705 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -3219,7 +3219,7 @@
         PlayerSuccess.GetSuccessAward(curPlayer, dataEx)
     # 仙树免费减时
     elif rewardType == ChConfig.Def_RewardType_TreeFreeTime:
-        PlayerTree.FreeReduceTreeLVTime(curPlayer)
+        PlayerTree.FreeReduceTreeLVTime(curPlayer, dataEx)
     # 广告奖励
     elif rewardType == ChConfig.Def_RewardType_ADAward:
         OnGetADAward(curPlayer, dataEx)
@@ -3377,14 +3377,15 @@
         return
     adCntMax = ipyData.GetADCntMax()
     adCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ADCnt % adID)
-    if adCnt >= adCntMax:
+    if adCntMax and adCnt >= adCntMax:
         GameWorld.DebugLog("今日该广告奖励已达上限! adID=%s,adCnt=%s > %s" % (adID, adCnt, adCntMax))
         return
     adCnt += 1
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ADCnt % adID, adCnt)
     awardItemList = ipyData.GetADAwardItemList()
     adMapID = ipyData.GetADMapID()
-    GameWorld.DebugLog("领取广告奖励! adID=%s,adCnt=%s,adMapID=%s,awardItemList=%s" % (adID, adCnt, adMapID, awardItemList))
+    adAwardType = ipyData.GetADAwardType()
+    GameWorld.DebugLog("领取广告奖励! adID=%s,adCnt=%s,adMapID=%s,adAwardType=%s,awardItemList=%s" % (adID, adCnt, adMapID, adAwardType, awardItemList))
     SyncADCntInfo(curPlayer, [adID])
     
     if adMapID:
@@ -3393,6 +3394,9 @@
     if awardItemList:
         ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["ADAward", False, {}])
         
+    # 领取祝福树充能奖励
+    if adAwardType == 1:
+        PlayerTree.GetTreeEnergyAward(curPlayer, False)
     return
 
 def ADCntOnDay(curPlayer):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldInvest.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldInvest.py
index 500140b..afa61f1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldInvest.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGoldInvest.py
@@ -215,6 +215,16 @@
         addMax += addCnt
     return addMax
 
+def GetTreeEnergyAdd(curPlayer):
+    ## 祝福树能量额外上限
+    addMax = 0
+    arenaCntDict = IpyGameDataPY.GetFuncEvalCfg("InvestPower", 4, {})
+    for investType, addCnt in arenaCntDict.items():
+        if not GetInvestState(curPlayer, int(investType)):
+            continue
+        addMax += addCnt
+    return addMax
+
 #// A5 41 领取投资理财回报 #tagCMGetInvestReward
 #
 #struct    tagCMGetInvestReward
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py
index ae4a7e6..24f9521 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTree.py
@@ -20,6 +20,7 @@
 import NetPackCommon
 import IpyGameDataPY
 import ChPyNetSendPack
+import PlayerGoldInvest
 import PlayerControl
 import IPY_GameWorld
 import PlayerTask
@@ -30,13 +31,17 @@
 def OnPlayerLogin(curPlayer):
     treeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)
     if not treeLV:
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLV, 1)
+        treeLV = 1
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeLV, treeLV)
+        energyInit = IpyGameDataPY.GetFuncCfg("TreeEnergy", 1)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeEnergy, energyInit)
+        GameWorld.DebugLog("初始仙树等级: treeLV=%s,energyInit=%s" % (treeLV, energyInit))
+    RefreshTreeEnergyTime(curPlayer)
     RefreshTreeLVUPTime(curPlayer)
     SyncTreeInfo(curPlayer)
     return
 
 def PlayerOnDay(curPlayer):
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeFreeTimeCnt, 0)
     SyncTreeInfo(curPlayer)
     return
 
@@ -174,34 +179,87 @@
         SyncTreeInfo(curPlayer)
     return True
 
-def FreeReduceTreeLVTime(curPlayer):
-    ## 仙树免费减时
-    dailyFreeCntMax = IpyGameDataPY.GetFuncCfg("TreeLVUP", 3)
-    freeCDSeconds = IpyGameDataPY.GetFuncCfg("TreeLVUP", 4) * 60 # 免费CD,秒
-    
-    freeTimeCntToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeFreeTimeCnt)
-    freeTimeLast = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeFreeTimeLast)
-    
-    if dailyFreeCntMax and freeTimeCntToday >= dailyFreeCntMax:
-        GameWorld.DebugLog("已达今日免费仙树减时次数! freeTimeCntToday=%s >= %s" % (freeTimeCntToday, dailyFreeCntMax))
+def GetTreeEnergyMax(curPlayer):
+    energyMax = IpyGameDataPY.GetFuncCfg("TreeEnergy", 2)
+    energyMax += PlayerGoldInvest.GetTreeEnergyAdd(curPlayer)
+    return energyMax
+
+def RefreshTreeEnergyTime(curPlayer):
+    ## 刷新充能时间
+    energy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeEnergy)
+    energyMax = GetTreeEnergyMax(curPlayer)
+    if energy >= energyMax:
         return
+    energyTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeEnergyTimeLast)
+    updEnergy = energy
+    updEnergyTime = energyTime
     
     curTime = int(time.time())
-    if freeCDSeconds and freeTimeLast and (curTime - freeTimeLast) < freeCDSeconds:
-        GameWorld.DebugLog("免费仙树减时CD未到! passSeconds=%s < %s" % (curTime - freeTimeLast, freeCDSeconds))
+    if not updEnergyTime:
+        updEnergyTime = curTime
+        
+    passSeconds = max(0, curTime - updEnergyTime)
+    energyCDSeconds = IpyGameDataPY.GetFuncCfg("TreeEnergy", 3) * 60 # 免费CD,秒
+    addEnergy = passSeconds / energyCDSeconds
+    if addEnergy > 0:
+        updEnergy += addEnergy
+        if updEnergy >= energyMax:
+            updEnergy = energyMax
+            updEnergyTime = 0
+        else:
+            updEnergyTime = curTime - passSeconds % energyCDSeconds
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeEnergy, updEnergy)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeEnergyTimeLast, updEnergyTime)
+    GameWorld.DebugLog("仙树充能时间刷新! energy=%s,energyTime=%s,addEnergy=%s,updEnergy=%s/%s,updEnergyTime=%s" 
+                       % (energy, energyTime, addEnergy, updEnergy, energyMax, updEnergyTime), curPlayer.GetPlayerID())
+    return
+
+def GetTreeEnergyAward(curPlayer, useMoney=False):
+    ## 领取充能奖励,可消耗货币或广告
+    
+    GameWorld.DebugLog("领取祝福树充能奖励! useMoney=%s" % useMoney)
+    
+    energy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeEnergy)
+    if energy <= 0:
+        GameWorld.DebugLog("没有充能减时次数!")
         return
     
-    reduceTime = IpyGameDataPY.GetFuncCfg("TreeLVUP", 5) * 60
+    reduceTime = IpyGameDataPY.GetFuncCfg("TreeEnergy", 4) * 60
     if reduceTime <= 0:
         return
     
+    if useMoney:
+        moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("TreeEnergy", 5)
+        if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
+            return
+        
     if not ReduceTreeLVUPTime(curPlayer, reduceTime, False):
         return
     
-    freeTimeCntToday += 1
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeFreeTimeCnt, freeTimeCntToday)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeFreeTimeLast, curTime)
+    if useMoney:
+        if not PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, "TreeEnergy"):
+            return
+        
+    energyMax = GetTreeEnergyMax(curPlayer)
+    if energy == energyMax:
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeEnergyTimeLast, int(time.time()))
+        GameWorld.DebugLog("重新开始充能倒计时!")
+        
+    energy -= 1
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreeEnergy, energy)
+    GameWorld.DebugLog("领取能量OK剩余能量: %s/%s" % (energy, energyMax))
     SyncTreeInfo(curPlayer)
+    return
+
+def FreeReduceTreeLVTime(curPlayer, opType=1):
+    ## 仙树领取充能减时
+    
+    # 刷新累计充能次数
+    if opType == 1:
+        RefreshTreeEnergyTime(curPlayer)
+        SyncTreeInfo(curPlayer)
+        return
+    GetTreeEnergyAward(curPlayer, True)
     return
 
 def DoTreeLVUP(curPlayer):
@@ -238,7 +296,7 @@
     clientPack.TreeLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV)
     clientPack.LVUPState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPState)
     clientPack.LVUPRemainTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLVUPRemainTime)
-    clientPack.FreeTimeCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeFreeTimeCnt)
-    clientPack.FreeTimeLast = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeFreeTimeLast)
+    clientPack.Energy = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeEnergy)
+    clientPack.EnergyTimeLast = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeEnergyTimeLast)
     NetPackCommon.SendFakePack(curPlayer, clientPack)
     return

--
Gitblit v1.8.0