feat(player): 重构任务状态管理逻辑
将任务状态相关的 GetTask 和 SetTask 方法从 player 包迁移至 model.PlayerInfo 结构体中, 统一通过 c.Info 调
This commit is contained in:
@@ -121,9 +121,8 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla
|
|||||||
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
|
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
|
||||||
if taskid != 0 {
|
if taskid != 0 {
|
||||||
if foi.Reason == 0 && foi.WinnerId == c.Info.UserID {
|
if foi.Reason == 0 && foi.WinnerId == c.Info.UserID {
|
||||||
if c.GetTask(taskid) == player.Unaccepted {
|
if c.Info.GetTask(taskid) == model.Unaccepted {
|
||||||
c.SetTask(taskid, player.Completed) //设置完成任务
|
c.Info.SetTask(taskid, model.Completed) //设置完成任务
|
||||||
c.Info.TaskList[taskid-1] = 3
|
|
||||||
|
|
||||||
moinfo.PetList[0].Downgrade(1)
|
moinfo.PetList[0].Downgrade(1)
|
||||||
PetID := moinfo.PetList[0].ID
|
PetID := moinfo.PetList[0].ID
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ func (h *Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.
|
|||||||
t.Service = blservice.NewUserService(data.Head.UserID)
|
t.Service = blservice.NewUserService(data.Head.UserID)
|
||||||
t.User = service.NewBaseSysUserService()
|
t.User = service.NewBaseSysUserService()
|
||||||
t.Info = t.Service.Info.Personself()
|
t.Info = t.Service.Info.Personself()
|
||||||
|
|
||||||
if t.Info == nil {
|
if t.Info == nil {
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ func (h Controller) AcceptTask(data *task.AcceptTaskInboundInfo, c *player.Playe
|
|||||||
// //isdaliy = true
|
// //isdaliy = true
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if c.GetTask(int(data.TaskId)) == player.Unaccepted {
|
if c.Info.GetTask(int(data.TaskId)) == model.Unaccepted {
|
||||||
c.SetTask(int(data.TaskId), player.Accepted)
|
c.Info.SetTask(int(data.TaskId), model.Accepted)
|
||||||
|
|
||||||
}
|
}
|
||||||
c.Service.Task.Exec(uint32(data.TaskId), func(t *model.TaskEX) bool {
|
c.Service.Task.Exec(uint32(data.TaskId), func(t *model.TaskEX) bool {
|
||||||
@@ -55,12 +55,12 @@ func (h Controller) AddTaskBuf(data *task.AddTaskBufInboundInfo, c *player.Playe
|
|||||||
* 完成任务
|
* 完成任务
|
||||||
*/
|
*/
|
||||||
func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *player.Player) (result *task.CompleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *player.Player) (result *task.CompleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||||
if c.GetTask(int(data.TaskId)) != player.Accepted { //如果任务没有接受或者已经完成Complete_Task
|
if c.Info.GetTask(int(data.TaskId)) != model.Accepted { //如果任务没有接受或者已经完成Complete_Task
|
||||||
return result, 0
|
return result, 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.SetTask(int(data.TaskId), player.Completed)
|
c.Info.SetTask(int(data.TaskId), model.Completed)
|
||||||
|
|
||||||
result = &task.CompleteTaskOutboundInfo{
|
result = &task.CompleteTaskOutboundInfo{
|
||||||
TaskId: data.TaskId,
|
TaskId: data.TaskId,
|
||||||
@@ -112,8 +112,8 @@ func (h Controller) Get_Task_Buf(data *task.GetTaskBufInboundInfo, c *player.Pla
|
|||||||
*/
|
*/
|
||||||
func (h Controller) Delete_Task(data *task.DeleteTaskInboundInfo, c *player.Player) (result *task.DeleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
func (h Controller) Delete_Task(data *task.DeleteTaskInboundInfo, c *player.Player) (result *task.DeleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||||
|
|
||||||
if c.GetTask(int(data.TaskId)) == player.Accepted {
|
if c.Info.GetTask(int(data.TaskId)) == model.Accepted {
|
||||||
c.SetTask(int(data.TaskId), player.Unaccepted)
|
c.Info.SetTask(int(data.TaskId), model.Unaccepted)
|
||||||
return &task.DeleteTaskOutboundInfo{TaskId: data.TaskId}, 0
|
return &task.DeleteTaskOutboundInfo{TaskId: data.TaskId}, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"blazing/logic/service/common"
|
"blazing/logic/service/common"
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/logic/service/space"
|
"blazing/logic/service/space"
|
||||||
"math/rand"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
@@ -17,7 +16,6 @@ import (
|
|||||||
|
|
||||||
blservice "blazing/modules/blazing/service"
|
blservice "blazing/modules/blazing/service"
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/antlabs/timer"
|
"github.com/antlabs/timer"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
@@ -187,8 +185,7 @@ func (p *Player) SendPack(b []byte) error {
|
|||||||
// 2. 从 string 类型 slice 随机选一个元素
|
// 2. 从 string 类型 slice 随机选一个元素
|
||||||
func RandomStringFromSlice(s []string) string {
|
func RandomStringFromSlice(s []string) string {
|
||||||
|
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
randomIdx := grand.Intn(len(s))
|
||||||
randomIdx := r.Intn(len(s))
|
|
||||||
return s[randomIdx]
|
return s[randomIdx]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,7 +318,8 @@ func (p *Player) ItemAdd(t ...model.ItemInfo) (result []model.ItemInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if p.Service.Item.CheakItem(v.ItemId)+v.ItemCnt > uint32(itemx.Max) {
|
if p.Service.Item.CheakItem(v.ItemId)+v.ItemCnt > uint32(itemx.Max) {
|
||||||
cool.Loger.Error(context.TODO(), "物品超过拥有最大限制", v.ItemId)
|
|
||||||
|
println(p.Info.UserID, "物品超过拥有最大限制", v.ItemId)
|
||||||
t1 := common.NewTomeeHeader(2601, p.Info.UserID)
|
t1 := common.NewTomeeHeader(2601, p.Info.UserID)
|
||||||
t1.Result = uint32(errorcode.ErrorCodes.ErrTooManyOfItem)
|
t1.Result = uint32(errorcode.ErrorCodes.ErrTooManyOfItem)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package player
|
|||||||
import (
|
import (
|
||||||
"blazing/common/data/share"
|
"blazing/common/data/share"
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
|
"blazing/modules/blazing/model"
|
||||||
|
|
||||||
"blazing/logic/service/fight/info"
|
"blazing/logic/service/fight/info"
|
||||||
"blazing/logic/service/space"
|
"blazing/logic/service/space"
|
||||||
@@ -71,7 +72,7 @@ func (lw *Player) CompleteLogin() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
if lw.IsNewPlayer() { //重置新手地图,放到机械仓
|
if lw.IsNewPlayer() { //重置新手地图,放到机械仓
|
||||||
lw.SetTask(4, Completed) //设置新手任务默认完成
|
lw.Info.SetTask(4, model.Completed) //设置新手任务默认完成
|
||||||
lw.Info.MapID = 8
|
lw.Info.MapID = 8
|
||||||
if len(lw.Info.PetList) == 0 {
|
if len(lw.Info.PetList) == 0 {
|
||||||
rr := lw.Service.Pet.PetInfo(0)
|
rr := lw.Service.Pet.PetInfo(0)
|
||||||
@@ -88,7 +89,7 @@ func (lw *Player) CompleteLogin() {
|
|||||||
func (lw *Player) IsNewPlayer() bool {
|
func (lw *Player) IsNewPlayer() bool {
|
||||||
// 遍历84到87的索引
|
// 遍历84到87的索引
|
||||||
for i := 84; i <= 87; i++ {
|
for i := 84; i <= 87; i++ {
|
||||||
if lw.GetTask(i) != Completed {
|
if lw.Info.GetTask(i) != model.Completed {
|
||||||
return true // 只要有一个不等于3,就返回true
|
return true // 只要有一个不等于3,就返回true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
package player
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// TaskStatus 任务状态(与 AS3 对应)
|
|
||||||
type TaskStatus uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
Unaccepted TaskStatus = 0 // 未接受(AS3 中 0 或 2 映射至此)
|
|
||||||
Accepted TaskStatus = 1 // 已接受
|
|
||||||
Completed TaskStatus = 3 // 已完成
|
|
||||||
Reserved TaskStatus = 2 // 预留(AS3 中映射为未接受)
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetTask 设置第 i 个任务的状态(0 ≤ i < 2000)
|
|
||||||
func (m *Player) SetTask(i int, status TaskStatus) error {
|
|
||||||
i-- //下标减1
|
|
||||||
if i < 0 || i >= 4000 {
|
|
||||||
return fmt.Errorf("index out of range: %d (must be 0-1999)", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
byteIdx := i / 4
|
|
||||||
bitOffset := (i % 4) * 2
|
|
||||||
|
|
||||||
// 清除原有 2 位
|
|
||||||
m.Info.TaskList[byteIdx] &^= 0x3 << bitOffset
|
|
||||||
|
|
||||||
// 设置新状态(确保只取低 2 位)
|
|
||||||
m.Info.TaskList[byteIdx] |= byte(status&0x3) << bitOffset
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTask 获取第 i 个任务的状态
|
|
||||||
func (m *Player) GetTask(i int) TaskStatus {
|
|
||||||
i-- //下标减1
|
|
||||||
// if i < 0 || i >= 2000 {
|
|
||||||
// return 0, fmt.Errorf("index out of range: %d", i)
|
|
||||||
// }
|
|
||||||
|
|
||||||
byteIdx := i / 4
|
|
||||||
bitOffset := (i % 4) * 2
|
|
||||||
|
|
||||||
return TaskStatus((m.Info.TaskList[byteIdx] >> bitOffset) & 0x3)
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,5 @@
|
|||||||
package space
|
package space
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/sync/singleflight"
|
|
||||||
)
|
|
||||||
|
|
||||||
var requestGroup singleflight.Group // SingleFlight 实例
|
|
||||||
// MapHotInfo 表示地图热度信息
|
// MapHotInfo 表示地图热度信息
|
||||||
type MapHotInfo struct {
|
type MapHotInfo struct {
|
||||||
MapID uint32 `json:"mapId"` // 地图ID
|
MapID uint32 `json:"mapId"` // 地图ID
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
@@ -397,7 +398,7 @@ func GenPetInfo(
|
|||||||
dv, natureId, abilityTypeEnum, shinyid, level int,
|
dv, natureId, abilityTypeEnum, shinyid, level int,
|
||||||
) *PetInfo {
|
) *PetInfo {
|
||||||
// 创建随机源
|
// 创建随机源
|
||||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
//rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
||||||
// 初始化精灵
|
// 初始化精灵
|
||||||
p := &PetInfo{
|
p := &PetInfo{
|
||||||
@@ -414,14 +415,14 @@ func GenPetInfo(
|
|||||||
|
|
||||||
// ---- 性格 ----
|
// ---- 性格 ----
|
||||||
if natureId == -1 {
|
if natureId == -1 {
|
||||||
p.Nature = uint32(rng.Intn(25))
|
p.Nature = uint32(grand.Intn(25))
|
||||||
} else {
|
} else {
|
||||||
p.Nature = uint32(natureId)
|
p.Nature = uint32(natureId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- 个体值(DV)----
|
// ---- 个体值(DV)----
|
||||||
if dv == -1 {
|
if dv == -1 {
|
||||||
p.Dv = uint32(CalculateIndividualValue(rng))
|
p.Dv = uint32(CalculateIndividualValue())
|
||||||
} else {
|
} else {
|
||||||
if dv < 0 {
|
if dv < 0 {
|
||||||
dv = 0
|
dv = 0
|
||||||
@@ -447,7 +448,7 @@ func GenPetInfo(
|
|||||||
}
|
}
|
||||||
case abilityTypeEnum == -1:
|
case abilityTypeEnum == -1:
|
||||||
// 随机特性
|
// 随机特性
|
||||||
randomIndex := rng.Intn(len(xmlres.PlayerEffectMAP))
|
randomIndex := grand.Intn(len(xmlres.PlayerEffectMAP))
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
for _, v := range xmlres.PlayerEffectMAP {
|
for _, v := range xmlres.PlayerEffectMAP {
|
||||||
@@ -512,8 +513,8 @@ func CalculateIndividual(a int) int {
|
|||||||
|
|
||||||
// CalculateIndividualValue 计算个体值(0-31)
|
// CalculateIndividualValue 计算个体值(0-31)
|
||||||
// 接收外部随机数生成器,便于控制随机性和复用
|
// 接收外部随机数生成器,便于控制随机性和复用
|
||||||
func CalculateIndividualValue(random *rand.Rand) int {
|
func CalculateIndividualValue() int {
|
||||||
// 生成0-40000的随机数,作为个体值计算的输入
|
// 生成0-40000的随机数,作为个体值计算的输入
|
||||||
a := random.Intn(40001)
|
a := grand.Intn(40001)
|
||||||
return CalculateIndividual(a)
|
return CalculateIndividual(a)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/creasty/defaults"
|
"github.com/creasty/defaults"
|
||||||
@@ -67,6 +68,48 @@ func NewPlayerInfo() PlayerInfo {
|
|||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TaskStatus 任务状态(与 AS3 对应)
|
||||||
|
type TaskStatus uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
Unaccepted TaskStatus = 0 // 未接受(AS3 中 0 或 2 映射至此)
|
||||||
|
Accepted TaskStatus = 1 // 已接受
|
||||||
|
Completed TaskStatus = 3 // 已完成
|
||||||
|
Reserved TaskStatus = 2 // 预留(AS3 中映射为未接受)
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetTask 设置第 i 个任务的状态(0 ≤ i < 2000)
|
||||||
|
func (m *PlayerInfo) SetTask(i int, status TaskStatus) error {
|
||||||
|
i-- //下标减1
|
||||||
|
if i < 0 || i >= 4000 {
|
||||||
|
return fmt.Errorf("index out of range: %d (must be 0-1999)", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
byteIdx := i / 4
|
||||||
|
bitOffset := (i % 4) * 2
|
||||||
|
|
||||||
|
// 清除原有 2 位
|
||||||
|
m.TaskList[byteIdx] &^= 0x3 << bitOffset
|
||||||
|
|
||||||
|
// 设置新状态(确保只取低 2 位)
|
||||||
|
m.TaskList[byteIdx] |= byte(status&0x3) << bitOffset
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTask 获取第 i 个任务的状态
|
||||||
|
func (m *PlayerInfo) GetTask(i int) TaskStatus {
|
||||||
|
i-- //下标减1
|
||||||
|
// if i < 0 || i >= 2000 {
|
||||||
|
// return 0, fmt.Errorf("index out of range: %d", i)
|
||||||
|
// }
|
||||||
|
|
||||||
|
byteIdx := i / 4
|
||||||
|
bitOffset := (i % 4) * 2
|
||||||
|
|
||||||
|
return TaskStatus((m.TaskList[byteIdx] >> bitOffset) & 0x3)
|
||||||
|
}
|
||||||
|
|
||||||
type PlayerInfo struct {
|
type PlayerInfo struct {
|
||||||
ExpPool uint32 `struc:"skip" json:"exp_pool"` // 累计经验池
|
ExpPool uint32 `struc:"skip" json:"exp_pool"` // 累计经验池
|
||||||
//LastResetTime time.Time `struc:"skip" json:"last_reset_time"` // 重置时间,比如电池和每日任务
|
//LastResetTime time.Time `struc:"skip" json:"last_reset_time"` // 重置时间,比如电池和每日任务
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ func (s *InfoService) Personself() *model.PlayerInfo {
|
|||||||
tttL, ok := xmlres.TaskMap[i]
|
tttL, ok := xmlres.TaskMap[i]
|
||||||
if ok {
|
if ok {
|
||||||
if tttL.Type == 1 { //日常任务
|
if tttL.Type == 1 { //日常任务
|
||||||
tt.Data.TaskList[i-1] = 0 //重置每日任务
|
|
||||||
|
tt.Data.SetTask(i, model.Unaccepted)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,11 @@ import (
|
|||||||
"blazing/modules/blazing/model"
|
"blazing/modules/blazing/model"
|
||||||
dictmodel "blazing/modules/dict/model"
|
dictmodel "blazing/modules/dict/model"
|
||||||
"blazing/modules/dict/service"
|
"blazing/modules/dict/service"
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/gcache"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
"github.com/gogf/gf/v2/util/grand"
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
)
|
)
|
||||||
@@ -27,14 +30,24 @@ func NewPetFusionMaterialService() *PetFusionMaterialService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cachePetFusionMaterialService = gcache.New()
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *PetFusionMaterialService) ModifyBefore(ctx context.Context, method string, param g.MapStrAny) (err error) {
|
||||||
|
cachePetFusionMaterialService.Clear(context.Background())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// 获取融合材料的特性,返回两个值,一个是指定的特性,另一个是如果配方没找到的情况下,默认的配置
|
// 获取融合材料的特性,返回两个值,一个是指定的特性,另一个是如果配方没找到的情况下,默认的配置
|
||||||
func (s *PetFusionMaterialService) Data(Material1 [4]uint32) uint32 {
|
func (s *PetFusionMaterialService) Data(Material1 [4]uint32) uint32 {
|
||||||
|
|
||||||
fusion, _ := service.NewDictInfoService().DataOne("fusion")
|
cacheKey := strings.Join(gconv.Strings(Material1[:]), ":")
|
||||||
|
println(cacheKey, "获取融合id")
|
||||||
|
|
||||||
fusions := utils.ToMap(fusion, func(t dictmodel.DictInfo) uint32 {
|
fusions := utils.ToMap(service.NewDictInfoService().DataOne("fusion"), func(t dictmodel.DictInfo) uint32 {
|
||||||
|
|
||||||
return gconv.Uint32(t.Remark)
|
return gconv.Uint32(t.Remark) //物品id转id
|
||||||
})
|
})
|
||||||
for _, v := range Material1 {
|
for _, v := range Material1 {
|
||||||
_, ok := fusions[v]
|
_, ok := fusions[v]
|
||||||
@@ -44,42 +57,46 @@ func (s *PetFusionMaterialService) Data(Material1 [4]uint32) uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
m := cool.DBM(s.Model)
|
ret, err := cachePetFusionMaterialService.GetOrSetFuncLock(context.Background(), cacheKey, func(context.Context) (interface{}, error) {
|
||||||
|
|
||||||
var effect model.PetFusionMaterial //一个特性应该是唯一的,但是我们要获取默认随机特性
|
m := cool.DBM(s.Model)
|
||||||
condition := g.Map{
|
|
||||||
"material1": fusions[Material1[0]].ID,
|
|
||||||
"material2": fusions[Material1[1]].ID,
|
|
||||||
"material3": fusions[Material1[2]].ID,
|
|
||||||
"material4": fusions[Material1[3]].ID,
|
|
||||||
"is_enable": 1,
|
|
||||||
}
|
|
||||||
m.Where(condition).Scan(&effect)
|
|
||||||
//这时候有可能效果是空的,那么这时候就再次查询默认的特性,保证每次必会生成一个数据库有的特性
|
|
||||||
//也许这个时候的特性配方就是随机从数据库中查找一个特性
|
|
||||||
|
|
||||||
effect2, _ := service.NewDictInfoService().DataOne("effect")
|
var effect *model.PetFusionMaterial //一个特性应该是唯一的,但是我们要获取默认随机特性
|
||||||
effect2s := utils.ToMap(effect2, func(t dictmodel.DictInfo) uint32 {
|
condition := g.Map{
|
||||||
|
"material1": fusions[Material1[0]].ID,
|
||||||
|
"material2": fusions[Material1[1]].ID,
|
||||||
|
"material3": fusions[Material1[2]].ID,
|
||||||
|
"material4": fusions[Material1[3]].ID,
|
||||||
|
"is_enable": 1,
|
||||||
|
}
|
||||||
|
m.Where(condition).Scan(&effect)
|
||||||
|
//这时候有可能效果是空的,那么这时候就再次查询默认的特性,保证每次必会生成一个数据库有的特性
|
||||||
|
//也许这个时候的特性配方就是随机从数据库中查找一个特性
|
||||||
|
|
||||||
|
return effect, nil
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
effect2s := utils.ToMap(service.NewDictInfoService().DataOne("effect"), func(t dictmodel.DictInfo) uint32 {
|
||||||
|
|
||||||
return gconv.Uint32(t.ID)
|
return gconv.Uint32(t.ID)
|
||||||
})
|
})
|
||||||
|
effect := ret.Interface().(*model.PetFusionMaterial)
|
||||||
|
|
||||||
if effect.Trait1Idx != 0 {
|
if err != nil {
|
||||||
r := grand.Intn(4)
|
r := grand.Intn(len(service.NewDictInfoService().DataOne("effect")) - 1)
|
||||||
switch r {
|
return gconv.Uint32(service.NewDictInfoService().DataOne("effect")[r].Remark)
|
||||||
case 0:
|
|
||||||
return gconv.Uint32(effect2s[effect.Trait1Idx].Remark)
|
|
||||||
case 1:
|
|
||||||
return gconv.Uint32(effect2s[effect.Trait2Idx].Remark)
|
|
||||||
case 2:
|
|
||||||
return gconv.Uint32(effect2s[effect.Trait3Idx].Remark)
|
|
||||||
case 3:
|
|
||||||
return gconv.Uint32(effect2s[effect.Trait4Idx].Remark)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
r := grand.Intn(4)
|
||||||
r := grand.Intn(len(effect2) - 1)
|
switch r {
|
||||||
return gconv.Uint32(effect2[r].Remark)
|
case 0:
|
||||||
|
return gconv.Uint32(effect2s[effect.Trait1Idx].Remark)
|
||||||
|
case 1:
|
||||||
|
return gconv.Uint32(effect2s[effect.Trait2Idx].Remark)
|
||||||
|
case 2:
|
||||||
|
return gconv.Uint32(effect2s[effect.Trait3Idx].Remark)
|
||||||
|
case 3:
|
||||||
|
return gconv.Uint32(effect2s[effect.Trait4Idx].Remark)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,13 @@ package service
|
|||||||
import (
|
import (
|
||||||
"blazing/cool"
|
"blazing/cool"
|
||||||
"blazing/modules/blazing/model"
|
"blazing/modules/blazing/model"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/alpacahq/alpacadecimal"
|
"github.com/alpacahq/alpacadecimal"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/gcache"
|
||||||
"github.com/gogf/gf/v2/util/grand"
|
"github.com/gogf/gf/v2/util/grand"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,22 +28,21 @@ func NewPetFusionService() *PetFusionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cachePetFusionService = gcache.New()
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *PetFusionService) ModifyBefore(ctx context.Context, method string, param g.MapStrAny) (err error) {
|
||||||
|
cachePetFusionService.Clear(context.Background())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//获取主副精灵融合的id,如果不存在,那就给一个保底的id
|
//获取主副精灵融合的id,如果不存在,那就给一个保底的id
|
||||||
|
|
||||||
func (s *PetFusionService) Data(p1, p2, rand uint32) uint32 {
|
func (s *PetFusionService) Data(p1, p2, rand uint32) uint32 {
|
||||||
m := cool.DBM(s.Model)
|
|
||||||
rand = uint32(alpacadecimal.NewFromInt(int64(rand)).Mul(alpacadecimal.NewFromFloat(0.5)).IntPart())
|
rand = uint32(alpacadecimal.NewFromInt(int64(rand)).Mul(alpacadecimal.NewFromFloat(0.5)).IntPart())
|
||||||
var pet []model.PetFusion //一个特性应该是唯一的,但是我们要获取默认随机特性
|
|
||||||
condition := g.Map{
|
|
||||||
"main_pet_id": p1,
|
|
||||||
"sub_pet_id": p2,
|
|
||||||
"is_enable": 1,
|
|
||||||
// "hits between ? and ?" : g.Slice{1, 10},
|
|
||||||
// "exp > 0" : nil,
|
|
||||||
// "category" : g.Slice{100, 200},
|
|
||||||
}
|
|
||||||
m.Where(condition).Scan(&pet)
|
|
||||||
|
|
||||||
|
pet := s.getData(p1, p2)
|
||||||
for _, v := range pet {
|
for _, v := range pet {
|
||||||
|
|
||||||
rr := grand.Intn(100)
|
rr := grand.Intn(100)
|
||||||
@@ -51,19 +54,49 @@ func (s *PetFusionService) Data(p1, p2, rand uint32) uint32 {
|
|||||||
if len(pet) > 0 {
|
if len(pet) > 0 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
pets := s.def()
|
||||||
var pets []model.PetFusion
|
|
||||||
m = cool.DBM(s.Model)
|
|
||||||
m.Where("is_enable", 1).Where("is_default", 1).Scan(&pets)
|
|
||||||
if len(pets) == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
res := pets[grand.Intn(len(pets)-1)]
|
res := pets[grand.Intn(len(pets)-1)]
|
||||||
rr := grand.Intn(100)
|
rr := grand.Intn(100)
|
||||||
if rr < int(res.Probability+int32(rand)) {
|
if rr < int(res.Probability+int32(rand)) {
|
||||||
return uint32(res.ResultPetID)
|
return uint32(res.ResultPetID)
|
||||||
}
|
}
|
||||||
|
//到这里相当于直接失败
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
func (s *PetFusionService) getData(p1, p2 uint32) []model.PetFusion {
|
||||||
|
cacheKey := strings.Join([]string{fmt.Sprintf("%d", p1), fmt.Sprintf("%d", p2)}, ":")
|
||||||
|
//println(cacheKey, "获取融合id")
|
||||||
|
ret, _ := cachePetFusionService.GetOrSetFuncLock(context.Background(), cacheKey, func(context.Context) (interface{}, error) {
|
||||||
|
m := cool.DBM(s.Model)
|
||||||
|
|
||||||
|
var pet []model.PetFusion //一个特性应该是唯一的,但是我们要获取默认随机特性
|
||||||
|
condition := g.Map{
|
||||||
|
"main_pet_id": p1,
|
||||||
|
"sub_pet_id": p2,
|
||||||
|
"is_enable": 1,
|
||||||
|
// "hits between ? and ?" : g.Slice{1, 10},
|
||||||
|
// "exp > 0" : nil,
|
||||||
|
// "category" : g.Slice{100, 200},
|
||||||
|
}
|
||||||
|
m.Where(condition).Scan(&pet)
|
||||||
|
return pet, nil
|
||||||
|
|
||||||
|
}, 0)
|
||||||
|
return ret.Interface().([]model.PetFusion)
|
||||||
|
|
||||||
|
}
|
||||||
|
func (s *PetFusionService) def() []model.PetFusion {
|
||||||
|
|
||||||
|
//println(cacheKey, "获取融合id")
|
||||||
|
ret, _ := cachePetFusionService.GetOrSetFuncLock(context.Background(), "-1", func(context.Context) (interface{}, error) {
|
||||||
|
|
||||||
|
var pets []model.PetFusion
|
||||||
|
m := cool.DBM(s.Model)
|
||||||
|
m.Where("is_enable", 1).Where("is_default", 1).Scan(&pets)
|
||||||
|
|
||||||
|
return pets, nil
|
||||||
|
}, 0)
|
||||||
|
return ret.Interface().([]model.PetFusion)
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"blazing/modules/dict/model"
|
"blazing/modules/dict/model"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/gcache"
|
||||||
"github.com/gogf/gf/v2/util/gconv"
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,29 +54,38 @@ func (s *DictInfoService) Data(ctx context.Context, types []string) (data interf
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (s *DictInfoService) DataOne(types string) (data []model.DictInfo, err error) {
|
func (s *DictInfoService) DataOne(types string) (data []model.DictInfo) {
|
||||||
var (
|
var (
|
||||||
dictInfoModel = model.NewDictInfo()
|
dictInfoModel = model.NewDictInfo()
|
||||||
dictTypeModel = model.NewDictType()
|
dictTypeModel = model.NewDictType()
|
||||||
)
|
)
|
||||||
// 如果typeData为空, 则返回空
|
ret, _ := cacheDict.GetOrSetFunc(context.Background(), types, func(context.Context) (interface{}, error) {
|
||||||
var ty *model.DictType
|
// 如果typeData为空, 则返回空
|
||||||
mType := cool.DBM(dictTypeModel)
|
var ty *model.DictType
|
||||||
mType.Where("key in (?)", types).Scan(&ty)
|
mType := cool.DBM(dictTypeModel)
|
||||||
|
mType.Where("key in (?)", types).Scan(&ty)
|
||||||
|
|
||||||
// 如果typeData为空, 则返回空
|
// 如果typeData为空, 则返回空
|
||||||
if ty == nil {
|
if ty == nil {
|
||||||
return []model.DictInfo{}, nil
|
return []model.DictInfo{}, nil
|
||||||
}
|
}
|
||||||
m := cool.DBM(dictInfoModel)
|
m := cool.DBM(dictInfoModel)
|
||||||
var ress []model.DictInfo
|
var ress []model.DictInfo
|
||||||
m.Where("typeId", ty.ID).Scan(&ress)
|
m.Where("typeId", ty.ID).Scan(&ress)
|
||||||
|
return ress, nil
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
return ret.Interface().([]model.DictInfo)
|
||||||
|
|
||||||
return ress, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
cacheDict = gcache.New()
|
||||||
|
)
|
||||||
|
|
||||||
// ModifyAfter 修改后
|
// ModifyAfter 修改后
|
||||||
func (s *DictInfoService) ModifyAfter(ctx context.Context, method string, param map[string]interface{}) (err error) {
|
func (s *DictInfoService) ModifyAfter(ctx context.Context, method string, param map[string]interface{}) (err error) {
|
||||||
|
cacheDict.Clear(context.Background())
|
||||||
if method == "Delete" {
|
if method == "Delete" {
|
||||||
// 删除后,同时删除子节点
|
// 删除后,同时删除子节点
|
||||||
ids, ok := param["ids"]
|
ids, ok := param["ids"]
|
||||||
|
|||||||
Reference in New Issue
Block a user