pet_home_server/src/server/game/mod/charge/Charge.go
2026-02-26 11:39:22 +08:00

492 lines
12 KiB
Go

package charge
import (
"fmt"
"math"
chargeCfg "server/conf/charge"
mergeDataCfg "server/conf/merge_data"
playroomCfg "server/conf/playroom"
"server/game/mod/item"
"server/game/mod/order"
GoUtil "server/game_util"
"server/msg"
"server/pkg/github.com/name5566/leaf/log"
)
type ChargeMod struct {
FirstCharge int64 // 首次充值时间
LastCharge int64 // 最后一次充值时间
EnergyShop map[int]struct{} // 能量购买次数商店
MaxCharge float64 // 最大充值金额
Charge float64 // 总充值金额
TodayCharge float64 // 当日充值金额
MonthCharge float64 // 当月充值金额
Total int // 总充值次数
LastSpecialCharge int64 // 近35天最大充值的充值时间
SpecialCharge float64 // 近35天最大充值金额
SpecialShop map[int]*SepcialShop // 特殊商店
FreeShop int // 已领取免费商店档次
ChessShop map[int]*ChessShop // 棋子商店
Gift map[int]int // 礼包
Ad bool // 是否购买免广告
AdEndTime int64
PetWorkTime int64 // 宠物打工时间
LastWorkTime int64 // 上次打工时间
WishList *WishList
WeeklyDiscount map[int]int // 每周折扣购买次数
WeeklyEndTime int64
}
type WishList struct {
Count int
ItemId int
SendList []int64
}
type Rand struct {
ChessId int
Diamond int
}
type ChessShop struct {
Diamond int
Count int
Id int
}
type SepcialShop struct {
Grade int
Count int
}
var ChessDiamondCfg = map[int]int{
1: 5,
2: 10,
3: 20,
4: 50,
}
const (
SPECIAL_TYPE_1 = 1 // 特惠礼包1
SPECIAL_TYPE_2 = 2 // 特惠礼包2
)
const (
PLAYROOM_SHOP = 1 // playroom商店
CHESS_SHOP = 2 // 棋子商店
ENERGY_SHOP = 3 // 能量商店
)
const (
secondsIn35Days = 35 * 24 * 3600
secondsIn7Days = 7 * 24 * 3600
secondsIn1Day = 24 * 3600
)
func (c *ChargeMod) InitData() {
if c.SpecialShop == nil {
c.SpecialShop = make(map[int]*SepcialShop)
}
if c.EnergyShop == nil {
c.EnergyShop = make(map[int]struct{})
}
if c.Gift == nil {
c.Gift = make(map[int]int)
}
if c.WishList == nil {
c.WishList = &WishList{
Count: 0,
ItemId: 0,
SendList: make([]int64, 0),
}
}
if c.WeeklyDiscount == nil {
c.WeeklyDiscount = make(map[int]int)
}
}
func (c *ChargeMod) GetMaxCharge() float64 {
return c.MaxCharge
}
func (c *ChargeMod) Login(LogoutTime int64) {
c.LastWorkTime = min(LogoutTime, c.PetWorkTime)
c.PetWorkTime -= c.LastWorkTime
}
// resetSpecialChargeIfExpired 若距上次充値超过 35 天则清零特惠充値记录
func (c *ChargeMod) resetSpecialChargeIfExpired(now int64) {
if c.LastCharge != 0 && now-c.LastCharge > secondsIn35Days {
c.SpecialCharge = 0
}
}
// 零点更新
func (c *ChargeMod) ZeroUpdate(Emit []int) {
Now := GoUtil.Now()
c.resetSpecialChargeIfExpired(Now)
if GoUtil.IsFirstDayOfMonth() {
c.MonthCharge = 0
}
c.FreeShop = 0
SpecialGrade := 1
c.TodayCharge = 0
c.SpecialShop = make(map[int]*SepcialShop)
SpecialShopCount := chargeCfg.GetSpecialShopCount()
for i := 1; i <= 2; i++ {
if c.Total == 0 {
c.SpecialShop[i] = &SepcialShop{Grade: SpecialGrade, Count: 1}
continue
}
m := c.SpecialCharge
M := chargeCfg.GetSpecialShopGrade(m, i)
a := min(2, GoUtil.FullWeeksSince(c.LastSpecialCharge))
SpecialGrade = max(1, M-a)
c.SpecialShop[i] = &SepcialShop{Grade: SpecialGrade, Count: SpecialShopCount}
}
if c.WishList != nil {
c.WishList.SendList = nil
}
if c.IsWeeklyDiscountDay() && c.WeeklyEndTime < Now {
c.WeeklyDiscount = make(map[int]int)
c.WeeklyEndTime = GoUtil.ZeroTimestamp() + secondsIn7Days
}
c.InitChessShop(Emit)
}
// 十二点更新 重置商店
func (c *ChargeMod) NoonUpdate(Emit []int) {
c.InitChessShop(Emit)
}
func (c *ChargeMod) FixBug(Emit []int) {
if len(c.ChessShop) < 5 {
c.InitChessShop(Emit)
}
}
// 充值
func (c *ChargeMod) Fire(ChargeId int) (Item []*item.Item) {
Money := chargeCfg.GetMoneyCharge(ChargeId)
if Money == 0 {
return
}
c.Charge += Money
c.TodayCharge += Money
c.MonthCharge += Money
c.Total++
Now := GoUtil.Now()
if c.FirstCharge == 0 {
c.FirstCharge = Now
}
c.resetSpecialChargeIfExpired(Now)
c.LastCharge = Now
if Money > c.MaxCharge {
c.MaxCharge = Money
}
if Money > c.SpecialCharge {
c.LastSpecialCharge = Now
c.SpecialCharge = Money
}
Item = c.FireDiamondShop(ChargeId)
if Item != nil {
return
}
Item = c.FireEnergyShop(ChargeId)
if Item != nil {
return
}
Item = c.FireSpecialShop(ChargeId)
if Item != nil {
return
}
Item = c.FirePetCoinShop(ChargeId)
if Item != nil {
return
}
Item = c.FireGift(ChargeId)
c.FireAd(ChargeId)
return
}
// 钻石商店
func (c *ChargeMod) FireDiamondShop(ChargeId int) []*item.Item {
return chargeCfg.GetDiamondShopReward(ChargeId)
}
// 宠物币商店
func (c *ChargeMod) FirePetCoinShop(ChargeId int) []*item.Item {
return chargeCfg.GetPetCoinShopReward(ChargeId)
}
// 能量商店
func (c *ChargeMod) FireEnergyShop(ChargeId int) []*item.Item {
id := chargeCfg.GetEnergyShopId(ChargeId)
_, ok := c.EnergyShop[id]
c.EnergyShop[id] = struct{}{}
return chargeCfg.GetEnergyShopReward(ChargeId, ok)
}
// 特惠礼包
func (c *ChargeMod) FireSpecialShop(ChargeId int) []*item.Item {
Type := chargeCfg.GetSpecialShopType(ChargeId)
if _, ok := c.SpecialShop[Type]; !ok {
return nil
}
if c.SpecialShop[Type].Count < 1 {
log.Debug("special shop recharge max, type: %d, charge id: %d", Type, ChargeId)
return nil
}
c.SpecialShop[Type].Count--
return chargeCfg.GetSpecialShopReward(ChargeId)
}
// 通用礼包
func (c *ChargeMod) FireGift(ChargeId int) []*item.Item {
Limit := chargeCfg.GetGiftLimit(ChargeId)
if Limit == 0 {
return nil
}
Id := chargeCfg.GetGiftId(ChargeId)
if v, ok := c.Gift[Id]; ok {
if v >= Limit {
return nil
}
}
c.Gift[Id]++
return chargeCfg.GetGiftReward(ChargeId)
}
// 免广告礼包
func (c *ChargeMod) FireAd(ChargeId int) []*item.Item {
AdChargeId := chargeCfg.GetAdChargeId()
if ChargeId != AdChargeId {
return nil
}
c.Ad = true
return nil
}
// 免广告礼包
func (c *ChargeMod) FireAdReward(ChargeId int) []*item.Item {
Items, PetWorkDay := chargeCfg.GetADReward(ChargeId)
if PetWorkDay != 0 {
Now := GoUtil.Now()
if c.AdEndTime < Now {
c.AdEndTime = Now + int64(PetWorkDay*secondsIn1Day)
} else {
c.AdEndTime += int64(PetWorkDay * secondsIn1Day)
}
c.PetWorkTime += int64(PetWorkDay * secondsIn1Day)
c.Ad = true
}
return Items
}
// 免费商店
func (c *ChargeMod) FireFreeShop() ([]*item.Item, error) {
if c.FreeShop >= 2 {
return nil, fmt.Errorf(" free shop reward max")
}
c.FreeShop++
return chargeCfg.GetFreeShopReward(c.FreeShop), nil
}
// 初始化棋子商店
func (c *ChargeMod) InitChessShop(Emit []int) {
if len(Emit) == 0 {
return
}
c.ChessShop = make(map[int]*ChessShop)
//ColorList := make([]string, 0)
RandList := make([]*Rand, 0)
for _, v := range Emit {
ProduceList := mergeDataCfg.GetEmitProduceType(v)
for _, p := range ProduceList {
ChessList := order.GetChessByDiff(v, 1, order.DIFF_MID, p)
if len(ChessList) == 1 {
ChessList = append(ChessList, ChessList[0]-1)
}
//ColorType := mergeDataCfg.GetColorType(p)
for _, c := range ChessList {
if c == 0 {
continue
}
ChessLv := mergeDataCfg.GetLvById(c)
DynamicLv := mergeDataCfg.GetAdjust(v, p, 0)
ChessLv += DynamicLv
Diamond := math.Round(math.Pow(2, float64(ChessLv-1)) / 5)
Diamond = max(1, Diamond)
RandList = append(RandList, &Rand{ChessId: c, Diamond: int(Diamond)})
}
}
}
randList := make([]interface{}, len(RandList))
for k, v := range RandList {
randList[k] = v
}
L := GoUtil.RandSliceNum2(randList, 5)
for k, v := range L {
Diamond := v.(*Rand).Diamond
ChessId := v.(*Rand).ChessId
if ChessId == 0 {
continue
}
c.ChessShop[k+1] = &ChessShop{Diamond: Diamond, Count: 5, Id: ChessId}
}
}
// 购买能量
func (c *ChargeMod) BuyEnergy(IsWeeklyDiscount bool) ([]*item.Item, []*item.Item, int) {
diamond := 40
if IsWeeklyDiscount {
LimitNum := c.WeeklyDiscount[0]
Discount, WeeklyLimit := chargeCfg.GetWeeklyInfo(0)
if LimitNum < WeeklyLimit {
diamond = int(math.Ceil(float64(diamond) * float64(Discount) / 100.0))
c.WeeklyDiscount[0] = LimitNum + 1
}
}
return []*item.Item{
item.NewItem(item.ITEM_DIAMOND_ID, -diamond),
item.NewItem(item.ITEM_ENERGY_ID, 100),
}, []*item.Item{
item.NewItem(item.ITEM_ENERGY_ID, 100),
}, diamond
}
// 购买棋子
func (c *ChargeMod) BuyChess(Chess int, IsWeeklyDiscount bool) ([]*item.Item, []*item.Item, int, error) {
v, ok := c.ChessShop[Chess]
if !ok {
return nil, nil, 0, fmt.Errorf("BuyChess chess id not exist id:%d", Chess)
}
if v.Count <= 0 {
return nil, nil, 0, fmt.Errorf("BuyChess chess count less zero id:%d", Chess)
}
v.Count--
diamond := v.Diamond
if IsWeeklyDiscount {
LimitNum := c.WeeklyDiscount[Chess]
Discount, WeeklyLimit := chargeCfg.GetWeeklyInfo(Chess)
if LimitNum < WeeklyLimit {
diamond = int(math.Ceil(float64(diamond) * float64(Discount) / 100))
if diamond == v.Diamond {
diamond -= 1
}
diamond = max(1, diamond)
c.WeeklyDiscount[Chess] = LimitNum + 1
}
}
return []*item.Item{
item.NewItem(item.ITEM_DIAMOND_ID, diamond),
}, []*item.Item{
item.NewItem(v.Id, 1),
}, v.Id, nil
}
// 棋子商店解锁
func (c *ChargeMod) TriggerChargeUnlock(Lv int, Emit []int) {
c.InitChessShop(Emit)
}
// 添加心愿单
func (c *ChargeMod) AddWish(Id, Type int) ([]*item.Item, error) {
ItemId := 0
switch Type {
case PLAYROOM_SHOP:
ItemId, _, _, _ = playroomCfg.GetShopItem(Id)
}
if ItemId == 0 {
return nil, fmt.Errorf("AddWish itemid not exist id:%d", Id)
}
var Items []*item.Item
if c.WishList.ItemId != 0 {
if c.WishList.ItemId == ItemId {
return nil, fmt.Errorf("AddWish itemid already exist id:%d", Id)
}
Items = append(Items, item.NewItem(item.ITEM_ENERGY_ID, c.WishList.Count))
c.WishList.Count = 0
}
c.WishList.ItemId = ItemId
return Items, nil
}
// 获取心愿单奖励
func (c *ChargeMod) GetWish() ([]*item.Item, error) {
if c.WishList.ItemId == 0 {
return nil, fmt.Errorf("AddWishCount itemid not exist")
}
Max := chargeCfg.GetWishCount(c.WishList.ItemId)
if c.WishList.Count < Max {
return nil, fmt.Errorf("AddWishCount count max")
}
rewardItemId := c.WishList.ItemId
c.WishList.Count = 0
c.WishList.ItemId = 0
return []*item.Item{item.NewItem(rewardItemId, 1)}, nil
}
// 发送心愿单
func (c *ChargeMod) SendWishBeg(Uids []int64) error {
for _, v := range Uids {
if GoUtil.InArray64(v, c.WishList.SendList) {
return fmt.Errorf("SendWishBeg uid already exist uid:%d", v)
}
}
c.WishList.SendList = append(c.WishList.SendList, Uids...)
return nil
}
// 增加心愿单完成度
func (c *ChargeMod) AddWishCount() {
if c.WishList.ItemId == 0 {
return
}
Max := chargeCfg.GetWishCount(c.WishList.ItemId)
if c.WishList.Count >= Max {
return
}
c.WishList.Count++
}
// 是否在每周折扣日
func (c *ChargeMod) IsWeeklyDiscountDay() bool {
Day := chargeCfg.GetWeeklyDiscountDay()
if Day == -1 {
return false
}
Weekday, _ := GoUtil.GetWeekdayAndHour()
return Weekday == Day || c.WeeklyEndTime > GoUtil.Now()
}
// 重置每周折扣
func (c *ChargeMod) ResetWeeklyDiscount() {
if c.IsWeeklyDiscountDay() {
return
}
c.WeeklyDiscount = make(map[int]int)
}
// 宠物打工数据
func (c *ChargeMod) PetWorkBackData() *msg.LogoutPetWork {
res := &msg.LogoutPetWork{
WorkTime: c.LastWorkTime,
RemainTime: c.PetWorkTime,
}
c.LastWorkTime = 0
return res
}
func (c *ChargeMod) GetWeeklyEndTime() int64 {
return c.WeeklyEndTime
}
func (c *ChargeMod) SetWeeklyEndTime(EndTime int64) {
c.WeeklyEndTime = EndTime
}