From 3234c016880bd20dc2da7130ca8ea395c084d8f2 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 13 六月 2024 16:10:22 +0800
Subject: [PATCH] 10178 【越南】【香港】【主干】挂机奖励
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGuaji.py | 394 +++++++++++++++++++++++++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py | 4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 113 ++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py | 2
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py | 3
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py | 113 ++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py | 3
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 20 +
8 files changed, 649 insertions(+), 3 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index d61488a..2e703fc 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -45185,6 +45185,119 @@
#------------------------------------------------------
+# B1 09 玩家挂机系统信息 #tagMCGuajiInfo
+
+class tagMCGuajiInfo(Structure):
+ Head = tagHead()
+ QuickAwardCount = 0 #(BYTE QuickAwardCount)// 今日已快速挂机收益次数
+ AwardType = 0 #(BYTE AwardType)// 收益类型: 0-已累计预览;1-领取结算结果(包含常规领取跟快速领取)
+ AwardSeconds = 0 #(DWORD AwardSeconds)// 已累计收益时长,秒
+ Exp = 0 #(DWORD Exp)// 已累计经验,求余亿部分
+ ExpPoint = 0 #(DWORD ExpPoint)// 已累计经验,整除亿部分
+ MoneyInfoLen = 0 #(BYTE MoneyInfoLen)
+ MoneyInfo = "" #(String MoneyInfo)// 已累计货币 [[货币类型, 货币值], ...]
+ ItemInfoLen = 0 #(BYTE ItemInfoLen)
+ ItemInfo = "" #(String ItemInfo)// 已累计物品 [[物品ID, 个数], ...]
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xB1
+ self.Head.SubCmd = 0x09
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.QuickAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.AwardType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.AwardSeconds,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.Exp,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.ExpPoint,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.MoneyInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.MoneyInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.MoneyInfoLen)
+ self.ItemInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.ItemInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemInfoLen)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xB1
+ self.Head.SubCmd = 0x09
+ self.QuickAwardCount = 0
+ self.AwardType = 0
+ self.AwardSeconds = 0
+ self.Exp = 0
+ self.ExpPoint = 0
+ self.MoneyInfoLen = 0
+ self.MoneyInfo = ""
+ self.ItemInfoLen = 0
+ self.ItemInfo = ""
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 1
+ length += 1
+ length += 4
+ length += 4
+ length += 4
+ length += 1
+ length += len(self.MoneyInfo)
+ length += 1
+ length += len(self.ItemInfo)
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteBYTE(data, self.QuickAwardCount)
+ data = CommFunc.WriteBYTE(data, self.AwardType)
+ data = CommFunc.WriteDWORD(data, self.AwardSeconds)
+ data = CommFunc.WriteDWORD(data, self.Exp)
+ data = CommFunc.WriteDWORD(data, self.ExpPoint)
+ data = CommFunc.WriteBYTE(data, self.MoneyInfoLen)
+ data = CommFunc.WriteString(data, self.MoneyInfoLen, self.MoneyInfo)
+ data = CommFunc.WriteBYTE(data, self.ItemInfoLen)
+ data = CommFunc.WriteString(data, self.ItemInfoLen, self.ItemInfo)
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ QuickAwardCount:%d,
+ AwardType:%d,
+ AwardSeconds:%d,
+ Exp:%d,
+ ExpPoint:%d,
+ MoneyInfoLen:%d,
+ MoneyInfo:%s,
+ ItemInfoLen:%d,
+ ItemInfo:%s
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.QuickAwardCount,
+ self.AwardType,
+ self.AwardSeconds,
+ self.Exp,
+ self.ExpPoint,
+ self.MoneyInfoLen,
+ self.MoneyInfo,
+ self.ItemInfoLen,
+ self.ItemInfo
+ )
+ return DumpString
+
+
+m_NAtagMCGuajiInfo=tagMCGuajiInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCGuajiInfo.Head.Cmd,m_NAtagMCGuajiInfo.Head.SubCmd))] = m_NAtagMCGuajiInfo
+
+
+#------------------------------------------------------
# B1 06 通知玩家向目标点移动 #tagMCNotifyPlayerMove
class tagMCNotifyPlayerMove(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 9d57e96..663a9da 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -4376,6 +4376,20 @@
Def_PDictType_TJGNotify_ItemID = "TJGItemID_%s" #脱机挂指定物品掉落显示
Def_PDictType_TJGOnDayEx = "TJGOnDayEx" #是否脱机挂中过天(5点)真实登录后重置
+
+# 挂机收益
+Def_PDict_GuajiCalcTime = "GuajiCalcTime" # 上次统计收益时间戳
+Def_PDict_GuajiAwardSeconds = "GuajiAwardSeconds" # 已累计收益时长,秒
+Def_PDict_GuajiQuickCount = "GuajiQuickCount" # 今日已快速收益次数
+Def_PDict_GuajiExp = "GuajiExp" # 经验
+Def_PDict_GuajiExpPoint = "GuajiExpPoint" # 经验超过E部分
+Def_PDict_GuajiMoneyType = "GuajiMoneyType_%s" # 获得货币类型,参数(索引)
+Def_PDict_GuajiMoneyValue = "GuajiMoneyValue_%s" # 获得货币值,参数(索引)
+Def_PDict_GuajiMoneyUnSeconds = "GuajiMoneyUnSeconds_%s" # 计算获得货币值时未处理收益的累计时长,秒,参数(货币类型)
+Def_PDict_GuajiItemUnSeconds = "GuajiItemUnSeconds" # 计算获得物品次数时未处理收益的累计时长,秒
+Def_PDict_GuajiItemID = "GuajiItemID_%s" # 获得物品ID,参数(索引)
+Def_PDict_GuajiItemCount = "GuajiItemCount_%s" # 获得物品个数,参数(索引)
+
#仙魔之争
Def_PDict_XMZZLastStartTime = "XMZZLastStartTime" #上次开始战斗时间
@@ -5765,7 +5779,8 @@
VIPPrivilege_BossDogzBuy, #44 神兽boss/蓬莱boss购买次数
VIPPrivilege_45, #45 魔化之地boss购买次数
VIPPrivilege_46, #46 情缘副本购买次数
-) = range(1, 47)
+VIPPrivilege_GuajiQuickBuy, #47 快速挂机购买次数
+) = range(1, 48)
(
@@ -6002,7 +6017,8 @@
Def_RewardType_ActLoginAwardNew, # 领取登录活动奖励70
Def_RewardType_ActTask, # 领取任务活动奖励71
Def_RewardType_ActBuyCountGift, # 领取购买次数礼包活动 72
-)= range(73)
+Def_RewardType_Guaji, # 领取挂机收益 73
+)= range(74)
#boss复活相关活动定义
BossRebornActIDList = (
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index d61488a..2e703fc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -45185,6 +45185,119 @@
#------------------------------------------------------
+# B1 09 玩家挂机系统信息 #tagMCGuajiInfo
+
+class tagMCGuajiInfo(Structure):
+ Head = tagHead()
+ QuickAwardCount = 0 #(BYTE QuickAwardCount)// 今日已快速挂机收益次数
+ AwardType = 0 #(BYTE AwardType)// 收益类型: 0-已累计预览;1-领取结算结果(包含常规领取跟快速领取)
+ AwardSeconds = 0 #(DWORD AwardSeconds)// 已累计收益时长,秒
+ Exp = 0 #(DWORD Exp)// 已累计经验,求余亿部分
+ ExpPoint = 0 #(DWORD ExpPoint)// 已累计经验,整除亿部分
+ MoneyInfoLen = 0 #(BYTE MoneyInfoLen)
+ MoneyInfo = "" #(String MoneyInfo)// 已累计货币 [[货币类型, 货币值], ...]
+ ItemInfoLen = 0 #(BYTE ItemInfoLen)
+ ItemInfo = "" #(String ItemInfo)// 已累计物品 [[物品ID, 个数], ...]
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xB1
+ self.Head.SubCmd = 0x09
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.QuickAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.AwardType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.AwardSeconds,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.Exp,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.ExpPoint,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.MoneyInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.MoneyInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.MoneyInfoLen)
+ self.ItemInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.ItemInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemInfoLen)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xB1
+ self.Head.SubCmd = 0x09
+ self.QuickAwardCount = 0
+ self.AwardType = 0
+ self.AwardSeconds = 0
+ self.Exp = 0
+ self.ExpPoint = 0
+ self.MoneyInfoLen = 0
+ self.MoneyInfo = ""
+ self.ItemInfoLen = 0
+ self.ItemInfo = ""
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 1
+ length += 1
+ length += 4
+ length += 4
+ length += 4
+ length += 1
+ length += len(self.MoneyInfo)
+ length += 1
+ length += len(self.ItemInfo)
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteBYTE(data, self.QuickAwardCount)
+ data = CommFunc.WriteBYTE(data, self.AwardType)
+ data = CommFunc.WriteDWORD(data, self.AwardSeconds)
+ data = CommFunc.WriteDWORD(data, self.Exp)
+ data = CommFunc.WriteDWORD(data, self.ExpPoint)
+ data = CommFunc.WriteBYTE(data, self.MoneyInfoLen)
+ data = CommFunc.WriteString(data, self.MoneyInfoLen, self.MoneyInfo)
+ data = CommFunc.WriteBYTE(data, self.ItemInfoLen)
+ data = CommFunc.WriteString(data, self.ItemInfoLen, self.ItemInfo)
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ QuickAwardCount:%d,
+ AwardType:%d,
+ AwardSeconds:%d,
+ Exp:%d,
+ ExpPoint:%d,
+ MoneyInfoLen:%d,
+ MoneyInfo:%s,
+ ItemInfoLen:%d,
+ ItemInfo:%s
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.QuickAwardCount,
+ self.AwardType,
+ self.AwardSeconds,
+ self.Exp,
+ self.ExpPoint,
+ self.MoneyInfoLen,
+ self.MoneyInfo,
+ self.ItemInfoLen,
+ self.ItemInfo
+ )
+ return DumpString
+
+
+m_NAtagMCGuajiInfo=tagMCGuajiInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCGuajiInfo.Head.Cmd,m_NAtagMCGuajiInfo.Head.SubCmd))] = m_NAtagMCGuajiInfo
+
+
+#------------------------------------------------------
# B1 06 通知玩家向目标点移动 #tagMCNotifyPlayerMove
class tagMCNotifyPlayerMove(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
index 73826b8..6af7789 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/GameFuncComm.py
@@ -48,6 +48,7 @@
import PlayerLianTi
import PlayerArena
import PlayerFaQi
+import PlayerGuaji
import PlayerTJG
import PlayerTask
@@ -74,6 +75,7 @@
ShareDefine.GameFuncID_FaQi:lambda curObj:PlayerFaQi.DoFaQiOpen(curObj),
ShareDefine.GameFuncID_LianTi:lambda curObj:PlayerLianTi.DoLianTiOpen(curObj),
ShareDefine.GameFuncID_Championship:lambda curObj:PlayerCrossChampionship.DoChampionshipOpen(curObj),
+ ShareDefine.GameFuncID_Guaji:lambda curObj:PlayerGuaji.DoGuajiOpen(curObj),
#ShareDefine.GameFuncID_RunDaily:lambda curObj:FBCommon.DoFuncOpen_RunDaily(curObj),
#ShareDefine.GameFuncID_RunFamily:lambda curObj:FBCommon.DoFuncOpen_RunFamily(curObj),
#ShareDefine.GameFuncID_RefineExp:lambda curObj:Operate_PlayerBuyZhenQi.DoFuncOpen_RefineExp(curObj),
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 7a5e7bd..1a218e7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -129,6 +129,7 @@
import PlayerArena
import PyGameData
import PlayerTJG
+import PlayerGuaji
import PlayerMineArea
import datetime
@@ -602,6 +603,8 @@
PlayerAssist.DoPlayerOnDay(curPlayer)
#福地
PlayerMineArea.PlayerOnDay(curPlayer)
+ #挂机
+ PlayerGuaji.PlayerOnDay(curPlayer)
#特殊时间点过天的,一般是游戏功能,此时立即同步一次跨服玩家数据
CrossPlayerData.SendMergePlayerDataNow(curPlayer)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGuaji.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGuaji.py
new file mode 100644
index 0000000..a27282c
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGuaji.py
@@ -0,0 +1,394 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerGuaji
+#
+# @todo:挂机收益
+# @author hxp
+# @date 2024-06-12
+# @version 1.0
+#
+# 详细描述: 挂机收益
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2024-06-12 18:00"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import ShareDefine
+import PlayerControl
+import ChPyNetSendPack
+import PlayerWorldAverageLv
+import FormulaControl
+import NetPackCommon
+import IpyGameDataPY
+import ItemControler
+import GameFuncComm
+import GameWorld
+import PlayerVip
+
+import time
+
+Def_Process_Seconds = 60 # 在线定时处理间隔,秒,离线上线后一次性处理
+
+def DoGuajiOpen(curPlayer):
+ openAwardMinutes = IpyGameDataPY.GetFuncCfg("GuajiTime", 1) # 功能开启获得收益时长,分钟
+ AddGuajiAward(curPlayer, openAwardMinutes * 60)
+ return
+
+def OnPlayerLogin(curPlayer):
+ if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Guaji):
+ return
+ if not ProcessGuaji(curPlayer):
+ Sync_GuajiAward(curPlayer)
+ return
+
+def PlayerOnDay(curPlayer):
+ if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Guaji):
+ return
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiQuickCount, 0)
+ Sync_GuajiAward(curPlayer)
+ return
+
+def ProcessGuaji(curPlayer):
+ ## 挂机定时处理收益
+ if GameWorld.IsCrossServer():
+ return
+ if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Guaji):
+ return
+
+ curTime = int(time.time())
+ lastCalcTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiCalcTime)
+ if not lastCalcTime:
+ lastCalcTime = curTime
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiCalcTime, curTime)
+
+ awardSeconds = passSeconds = curTime - lastCalcTime
+ if passSeconds <= Def_Process_Seconds:
+ # 每满x秒统计一次
+ return
+
+ if awardSeconds < Def_Process_Seconds + 10:
+ awardSeconds = Def_Process_Seconds
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiCalcTime, lastCalcTime + awardSeconds)
+ else:
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiCalcTime, curTime)
+
+ return AddGuajiAward(curPlayer, awardSeconds)
+
+def AddGuajiAward(curPlayer, awardSeconds):
+ ## 增加挂机奖励
+ if awardSeconds <= 0:
+ return
+
+ playerID = curPlayer.GetPlayerID()
+ curAwardSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiAwardSeconds)
+ maxSeconds = GetGuajiSecondsMax(curPlayer)
+ if curAwardSeconds >= maxSeconds:
+ GameWorld.DebugLog("挂机收益时长已达上限: curAwardSeconds=%s >= %s" % (curAwardSeconds, maxSeconds), playerID)
+ return
+
+ awardSeconds = min(maxSeconds - curAwardSeconds, awardSeconds)
+ if awardSeconds <= 0:
+ return
+
+ addExp, giveMoneyDict, giveItemDict = CalcGuajiAward(curPlayer, awardSeconds, False)
+
+ updAwardSeconds = curAwardSeconds + awardSeconds
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiAwardSeconds, updAwardSeconds)
+ GameWorld.DebugLog("保存挂机累计收益: curAwardSeconds=%s,updAwardSeconds=%s,maxSeconds=%s" % (curAwardSeconds, updAwardSeconds, maxSeconds), playerID)
+
+ # 经验
+ exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiExpPoint) * ChConfig.Def_PerPointValue \
+ + curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiExp) + addExp
+ updExpPoint = exp / ChConfig.Def_PerPointValue
+ updExp = exp % ChConfig.Def_PerPointValue
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiExpPoint, updExpPoint)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiExp, updExp)
+ GameWorld.DebugLog(" 累计经验: %s亿%s" % (updExpPoint, updExp), playerID)
+
+ # 货币
+ for moneyType, addValue in giveMoneyDict.items():
+ saveNum = GetSaveNum(curPlayer, ChConfig.Def_PDict_GuajiMoneyType, moneyType)
+ if saveNum == None:
+ continue
+ moneyValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiMoneyValue % saveNum)
+ updMoney = min(moneyValue + addValue, ChConfig.Def_UpperLimit_DWord)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyType % saveNum, moneyType)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyValue % saveNum, updMoney)
+ GameWorld.DebugLog(" 累计货币: moneyType=%s,updMoney=%s,saveNum=%s" % (moneyType, updMoney, saveNum), playerID)
+
+ # 物品
+ for itemID, addCount in giveItemDict.items():
+ saveNum = GetSaveNum(curPlayer, ChConfig.Def_PDict_GuajiItemID, itemID)
+ if saveNum == None:
+ continue
+ curCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiItemCount % saveNum)
+ updCount = min(curCount + addCount, ChConfig.Def_UpperLimit_DWord)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemID % saveNum, itemID)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemCount % saveNum, updCount)
+ GameWorld.DebugLog(" 累计物品: itemID=%s,updCount=%s,saveNum=%s" % (itemID, updCount, saveNum), playerID)
+
+ Sync_GuajiAward(curPlayer)
+ return True
+
+def GetSaveNum(curPlayer, key, compValue):
+ for num in range(100):
+ value = curPlayer.NomalDictGetProperty(key % num)
+ if not value or compValue == value:
+ # 空值或者命中
+ return num
+ return
+
+def GetGuajiSecondsMax(curPlayer):
+ ## 挂机收益时长上限,秒
+ # 初始
+ initHours = IpyGameDataPY.GetFuncCfg("GuajiTime", 2) # 初始时长,小时
+
+ # 境界增加
+ curRealmLV = curPlayer.GetOfficialRank()
+ realmAddHours = 0
+ realmAddHoursDict = IpyGameDataPY.GetFuncEvalCfg("GuajiTime", 3, {})
+ realmLVList = realmAddHoursDict.keys()
+ realmLVList.sort()
+ for realmLV in realmLVList:
+ if curRealmLV >= realmLV:
+ realmAddHours = realmAddHoursDict[realmLV]
+ else:
+ break
+
+ totalHours = initHours + realmAddHours
+ return totalHours * 3600
+
+def GetGuajiAwardInfoSave(curPlayer):
+ ## 获取已保存的累计挂机收益信息
+ lastCalcTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiCalcTime)
+ awardSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiAwardSeconds)
+ if lastCalcTime:
+ awardSeconds += max(0, int(time.time() - lastCalcTime))
+ awardSeconds = min(awardSeconds, GetGuajiSecondsMax(curPlayer))
+
+ exp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiExpPoint) * ChConfig.Def_PerPointValue + \
+ curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiExp)
+
+ moneyDict = {}
+ for num in range(100):
+ moneyType = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiMoneyType % num)
+ if not moneyType:
+ break
+ moneyDict[moneyType] = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiMoneyValue % num)
+
+ itemDict = {}
+ for num in range(100):
+ itemID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiItemID % num)
+ if not itemID:
+ break
+ itemDict[itemID] = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiItemCount % num)
+
+ return awardSeconds, exp, moneyDict, itemDict
+
+def CalcGuajiAward(curPlayer, awardSeconds, isQuick):
+ ## 计算挂机收益,只计算收益,不做结算,结算逻辑由外层决定
+
+ playerID = curPlayer.GetPlayerID()
+ reLV = curPlayer.GetLV()
+ lvIpyData = PlayerControl.GetPlayerLVIpyData(reLV)
+ reExp = lvIpyData.GetReExp() if lvIpyData else 0
+ worldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
+ GameWorld.DebugLog("计算挂机收益: awardSeconds=%s,isQuick=%s,reLV=%s,reExp=%s,worldLV=%s"
+ % (awardSeconds, isQuick, reLV, reExp, worldLV), playerID)
+
+ # 经验
+ expRate = GetGuajiExpRate(curPlayer)
+ secondBaseExp = int(eval(FormulaControl.GetCompileFormula("GuajiExp", IpyGameDataPY.GetFuncCfg("GuajiAward", 1))))
+ secondExp = int(secondBaseExp * expRate / float(ChConfig.Def_MaxRateValue))
+ addExp = awardSeconds * secondExp
+ GameWorld.DebugLog(" 每秒经验: %s, addExp=%s,secondBaseExp=%s,expRate=%s" % (secondExp, addExp, secondBaseExp, expRate), playerID)
+
+ # 每秒产出货币
+ moneyDict = {}
+ perSecondMoneyFromulaDict = IpyGameDataPY.GetFuncEvalCfg("GuajiAward", 2, {}) # 每秒获得货币公式 {货币类型:"每秒获得数量公式", ...}
+ for moneyType, formula in perSecondMoneyFromulaDict.items():
+ secondMoney = int(eval(FormulaControl.GetCompileFormula("GuajiMoney_%s" % moneyType, formula)))
+ moneyValue = awardSeconds * secondMoney
+ moneyDict[moneyType] = moneyValue
+ GameWorld.DebugLog(" 每秒货币: moneyType=%s,secondMoney=%s,moneyValue=%s" % (moneyType, secondMoney, moneyValue), playerID)
+
+ # 每x秒产出1货币
+ perMoneyTimeFromulaDict = IpyGameDataPY.GetFuncEvalCfg("GuajiAward", 3, {}) # 每x秒获得1个货币公式 {货币类型:"x秒公式", ...}
+ for moneyType, formula in perMoneyTimeFromulaDict.items():
+ moneyAwardSeconds = awardSeconds
+ if not isQuick:
+ moneyAwardSeconds += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiMoneyUnSeconds % moneyType)
+ oneMoneyNeedSeconds = int(eval(FormulaControl.GetCompileFormula("GuajiMoney_%s" % moneyType, formula)))
+ moneyValue = moneyAwardSeconds / oneMoneyNeedSeconds
+ moneyDict[moneyType] = moneyValue
+ GameWorld.DebugLog(" 每X秒货币: moneyType=%s,oneMoneyNeedSeconds=%s,moneyValue=%s,moneyAwardSeconds=%s"
+ % (moneyType, oneMoneyNeedSeconds, moneyValue, moneyAwardSeconds), playerID)
+
+ if not isQuick:
+ unSeconds = moneyAwardSeconds % oneMoneyNeedSeconds
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyUnSeconds % moneyType, unSeconds)
+ GameWorld.DebugLog(" moneyType=%s,unSeconds=%s" % (moneyType, unSeconds), playerID)
+
+ # 物品
+ giveItemSecondsSet = IpyGameDataPY.GetFuncCfg("GuajiAward", 4) # 每x秒获得一次随机物品机会
+ lvItemRateDict = IpyGameDataPY.GetFuncEvalCfg("GuajiAward", 5, {})
+ itemAwardSeconds = awardSeconds
+ if not isQuick:
+ itemAwardSeconds += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiItemUnSeconds)
+
+ itemAwardTimes = itemAwardSeconds / giveItemSecondsSet # 给物品次数
+ GameWorld.DebugLog(" 给物品次数: %s, itemAwardSeconds=%s,giveItemSecondsSet=%s" % (itemAwardTimes, itemAwardSeconds, giveItemSecondsSet), playerID)
+
+ if not isQuick:
+ unSeconds = itemAwardSeconds % giveItemSecondsSet
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemUnSeconds, unSeconds)
+ GameWorld.DebugLog(" 给物品未处理秒数=%s" % unSeconds, playerID)
+
+ lvList = lvItemRateDict.keys()
+ lvList.sort()
+ itemRateList = []
+ for lv in lvList:
+ if reLV >= lv:
+ itemRateList = lvItemRateDict[lv]
+ else:
+ break
+
+ dropCountTotal = 0
+ itemDict = {}
+ maxRate = itemRateList[-1][0]
+ GameWorld.DebugLog(" itemRateList=%s,maxRate=%s" % (itemRateList, maxRate), playerID)
+ if itemAwardTimes > 100: # 超过x次的,先进行批量处理
+ preRate = 0
+ for rateInfo in itemRateList:
+ rate, itemInfo = rateInfo
+ curRate = rate - preRate
+ preRate = rate
+ if curRate <= 0:
+ continue
+ totalRate = curRate * itemAwardTimes # 总概率
+ dropCount = totalRate / maxRate # 可掉落件数
+ rateEx = totalRate % maxRate # 剩余概率
+ if GameWorld.CanHappen(rateEx, maxRate):
+ dropCount += 1
+ dropCountTotal += dropCount # 产出是是空物品也要算执行掉落次数
+ GameWorld.DebugLog(" 挂机物品: itemInfo=%s,curRate=%s,totalRate=%s,rateEx=%s,dropCount=%s,dropCountTotal=%s"
+ % (itemInfo, curRate, totalRate, rateEx, dropCount, dropCountTotal), playerID)
+ if not dropCount:
+ continue
+
+ if not itemInfo:
+ continue
+ itemID, itemCount = itemInfo
+ itemDict[itemID] = itemDict.get(itemID, 0) + itemCount * dropCount
+
+ awardTimesEx = itemAwardTimes - dropCountTotal
+ GameWorld.DebugLog(" awardTimesEx=%s" % awardTimesEx, playerID)
+ if awardTimesEx > 0:
+ for _ in range(awardTimesEx):
+ itemInfo = GameWorld.GetResultByRandomList(itemRateList)
+ if not itemInfo:
+ continue
+ itemID, itemCount = itemInfo
+ itemDict[itemID] = itemDict.get(itemID, 0) + itemCount
+
+ GameWorld.DebugLog(" itemDict=%s" % (itemDict), playerID)
+ return addExp, moneyDict, itemDict
+
+def GetGuajiExpRate(curPlayer):
+ ## 挂机收益经验加成
+ expRate = curPlayer.GetFightExpRate() # 系统及功能累加
+ expRate += PlayerWorldAverageLv.GetWorldAverageLvExpRate(curPlayer) # 世界等级
+ expRate += PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_FightExpRate) # VIP加成
+ return expRate
+
+def OnGetGuajiAward(curPlayer, isQuick):
+ ## 领取挂机收益
+ # @param isQuick: 是否快速收益
+
+ playerID = curPlayer.GetPlayerID()
+ GameWorld.DebugLog("领取挂机收益! isQuick=%s" % isQuick, playerID)
+
+ if isQuick:
+ quickCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiQuickCount)
+ quickCountFree = IpyGameDataPY.GetFuncCfg("GuajiQuick", 2)
+ vipCanBuyCount = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_GuajiQuickBuy)
+ quickCountMax = quickCountFree + vipCanBuyCount
+ if quickCountToday >= quickCountMax:
+ GameWorld.DebugLog("快速挂机收益次数已达每日上限! quickCountToday=%s" % quickCountToday, playerID)
+ return
+
+ if quickCountToday >= quickCountFree:
+ todayBuyCount = quickCountToday - quickCountFree # 今日已购买次数
+ costMoneyType = IpyGameDataPY.GetFuncCfg("GuajiQuick", 3)
+ costMoneyList = IpyGameDataPY.GetFuncEvalCfg("GuajiQuick", 4)
+ if not costMoneyType or not costMoneyList:
+ return
+ costMoneyValue = costMoneyList[todayBuyCount] if len(costMoneyList) > todayBuyCount else costMoneyList[-1]
+
+ GameWorld.DebugLog(" todayBuyCount=%s,costMoneyType=%s,costMoneyValue=%s"
+ % (todayBuyCount, costMoneyType, costMoneyValue), playerID)
+ if not PlayerControl.PayMoney(curPlayer, costMoneyType, costMoneyValue, "Guaji"):
+ return
+
+ awardSeconds = IpyGameDataPY.GetFuncCfg("GuajiQuick", 1) * 3600
+ exp, moneyDict, itemDict = CalcGuajiAward(curPlayer, awardSeconds, True)
+
+ quickCountToday += 1
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiQuickCount, quickCountToday)
+ GameWorld.DebugLog(" 更新快速挂机收益次数: quickCountToday=%s,quickCountMax=%s" % (quickCountToday, quickCountMax), playerID)
+ else:
+ awardSeconds, exp, moneyDict, itemDict = GetGuajiAwardInfoSave(curPlayer)
+
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiCalcTime, int(time.time())) # 设置统计时间,重新统计
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiAwardSeconds, 0)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiExp, 0)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiExpPoint, 0)
+ for num in range(100):
+ if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiMoneyType % num):
+ break
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyType % num, 0)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiMoneyValue % num, 0)
+ for num in range(100):
+ if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiItemID % num):
+ break
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemID % num, 0)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GuajiItemCount % num, 0)
+ Sync_GuajiAward(curPlayer)
+
+ GameWorld.DebugLog(" 挂机收益: awardSeconds=%s,exp=%s,moneyDict=%s,itemDict=%s" % (awardSeconds, exp, moneyDict, itemDict), playerID)
+
+ playerControl = PlayerControl.PlayerControl(curPlayer)
+ playerControl.AddExp(exp, ShareDefine.Def_ViewExpType_Guaji)
+
+ for moneyType, moneyValue in moneyDict.items():
+ PlayerControl.GiveMoney(curPlayer, moneyType, moneyValue, "Guaji")
+
+ giveItemList = [[itemID, itemCount, 0] for itemID, itemCount in itemDict.items()]
+ ItemControler.GivePlayerItemOrMail(curPlayer, giveItemList, event=["Guaji", False, {}])
+
+ Sync_GuajiAward(curPlayer, 1, awardSeconds, exp, moneyDict, itemDict)
+ return
+
+def Sync_GuajiAward(curPlayer, awardType=0, awardSeconds=0, exp=0, moneyDict=None, itemDict=None):
+ ## 同步挂机收益信息
+
+ # 收益类型: 0-已累计预览;1-领取结算结果(包含常规领取跟快速领取)
+ if awardType == 0:
+ awardSeconds, exp, moneyDict, itemDict = GetGuajiAwardInfoSave(curPlayer)
+
+ clientPack = ChPyNetSendPack.tagMCGuajiInfo()
+ clientPack.QuickAwardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GuajiQuickCount)
+ clientPack.AwardType = awardType
+ clientPack.AwardSeconds = awardSeconds
+ clientPack.Exp = exp % ChConfig.Def_PerPointValue
+ clientPack.ExpPoint = exp / ChConfig.Def_PerPointValue
+ clientPack.MoneyInfo = str([[moneyType, moneyValue] for moneyType, moneyValue in moneyDict.items()]).replace(" ", "") if moneyDict else "[]"
+ clientPack.MoneyInfoLen = len(clientPack.MoneyInfo)
+ clientPack.ItemInfo = str([[itemID, itemCount] for itemID, itemCount in itemDict.items()]).replace(" ", "") if itemDict else "[]"
+ clientPack.ItemInfoLen = len(clientPack.ItemInfo)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
index 3d1f87c..9536a55 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -45,6 +45,7 @@
import time
import PetControl
import ItemControler
+import PlayerGuaji
import PlayerTJG
import AICommon
import PlayerSuccess
@@ -1267,6 +1268,8 @@
#脱机计算
PlayerTJG.ProcessPlayerTJG(curPlayer, tick)
+ #挂机收益
+ PlayerGuaji.ProcessGuaji(curPlayer)
#PK/boss状态
ProcessPKBossState(curPlayer, tick)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index bb76af1..09e759e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -405,7 +405,8 @@
Def_ViewExpType_LYZS, #烈焰战神 特殊特效 8
Def_ViewExpType_Activity, #活跃吸纳 9
Def_ViewExpType_Chuangong, #传功经验10
-) = range(0, 11)
+ Def_ViewExpType_Guaji, #挂机收益11
+) = range(0, 12)
#物品相关操作类型
@@ -1217,6 +1218,7 @@
GameFuncID_LianTi = 207 # 炼体
GameFuncID_Championship = 210 # 排位
GameFuncID_MineArea = 227 # 福地
+GameFuncID_Guaji = 228 # 挂机
# 以下为暂时无用的
GameFuncID_Truck = 33 # 运镖
GameFuncID_RunDaily = 34 # 日常跑环
--
Gitblit v1.8.0