2025-07-26 02:06:08 +00:00
|
|
|
|
package model
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2025-12-21 17:18:33 +00:00
|
|
|
|
"blazing/common/data"
|
2025-10-13 19:46:19 +08:00
|
|
|
|
"blazing/common/data/xmlres"
|
2025-11-23 23:38:03 +00:00
|
|
|
|
"blazing/common/utils"
|
2025-07-26 02:06:08 +00:00
|
|
|
|
"blazing/cool"
|
2026-03-07 11:30:17 +08:00
|
|
|
|
"encoding/json"
|
2026-02-17 22:53:45 +08:00
|
|
|
|
|
2026-03-07 11:30:17 +08:00
|
|
|
|
"blazing/modules/config/model"
|
2025-12-30 00:10:59 +08:00
|
|
|
|
"blazing/modules/config/service"
|
2025-11-23 00:06:14 +08:00
|
|
|
|
"errors"
|
|
|
|
|
|
"fmt"
|
2025-10-18 23:58:19 +08:00
|
|
|
|
"math"
|
2025-10-24 00:31:38 +08:00
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
2025-12-08 19:16:37 +08:00
|
|
|
|
"github.com/gogf/gf/v2/util/grand"
|
2025-12-10 14:04:06 +00:00
|
|
|
|
"github.com/jinzhu/copier"
|
2025-11-25 00:55:10 +08:00
|
|
|
|
"github.com/samber/lo"
|
2025-07-26 02:06:08 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2026-01-19 18:51:56 +08:00
|
|
|
|
const TableNamePet = "player_pet"
|
2025-07-26 02:06:08 +00:00
|
|
|
|
|
|
|
|
|
|
// Pet mapped from table <pet>
|
|
|
|
|
|
type Pet struct {
|
2026-01-08 03:30:18 +08:00
|
|
|
|
Base
|
2026-03-11 01:32:49 +08:00
|
|
|
|
PlayerID uint32 `gorm:"not null;index:idx_pet_by_player_id;comment:'所属玩家ID'" json:"player_id"`
|
2026-03-19 20:54:52 +08:00
|
|
|
|
Free int `gorm:"not null;default:0;comment:'是否放生'" json:"free"` //"0为放入仓库,1为放生,2为上架
|
2026-03-11 01:32:49 +08:00
|
|
|
|
CatchTime uint32 `gorm:"not null;comment:'捕捉时间'" json:"catch_time"` //唯一键
|
2026-03-19 20:54:52 +08:00
|
|
|
|
|
2026-03-11 01:32:49 +08:00
|
|
|
|
SalePrice uint32 `gorm:"not null;default:0;comment:'出售价格'" json:"sale_price"`
|
2026-03-11 12:19:13 +08:00
|
|
|
|
SaleCount uint32 `gorm:"not null;default:0;comment:'出售次数'" json:"sale_count"`
|
2025-08-31 06:53:42 +00:00
|
|
|
|
// Owner uint32 `struc:"skip"` //仅作为存储
|
|
|
|
|
|
// FreedTime uint32 `struc:"skip"` //放生时间
|
|
|
|
|
|
//是否可交易,这里应该定义在精灵ID里
|
|
|
|
|
|
//是否上架
|
2026-02-07 20:16:44 +08:00
|
|
|
|
Data PetInfo `gorm:"type:jsonb;not null;comment:'精灵全部数据'" json:"data"`
|
2025-09-23 15:01:52 +00:00
|
|
|
|
}
|
2025-08-31 00:27:07 +08:00
|
|
|
|
|
2026-03-19 14:50:11 +08:00
|
|
|
|
// GetOffShelfFee 计算商品下架扣费规则
|
|
|
|
|
|
// 返回值:allowOffShelf(是否允许下架), feeRate(扣费比例), err(错误信息)
|
|
|
|
|
|
func (tt *Pet) GetOffShelfFee() (bool, float64, error) {
|
|
|
|
|
|
// 获取当前时间
|
|
|
|
|
|
now := time.Now()
|
|
|
|
|
|
// 计算上架到现在的时长(小时)
|
|
|
|
|
|
duration := now.Sub(tt.UpdateTime.Time)
|
|
|
|
|
|
hours := duration.Hours()
|
|
|
|
|
|
|
|
|
|
|
|
// 阶段1:0-24小时(展示期,可下架但阶梯扣费)
|
|
|
|
|
|
if hours >= 0 && hours < 24 {
|
|
|
|
|
|
switch {
|
|
|
|
|
|
case hours < 6:
|
|
|
|
|
|
// 0-6小时:0扣费,允许下架
|
|
|
|
|
|
return true, 0.0, nil
|
|
|
|
|
|
case hours < 12:
|
|
|
|
|
|
// 6-12小时:扣30%,允许下架
|
|
|
|
|
|
return true, 0.3, nil
|
|
|
|
|
|
case hours < 18:
|
|
|
|
|
|
// 12-18小时:扣60%,允许下架
|
|
|
|
|
|
return true, 0.6, nil
|
|
|
|
|
|
case hours < 24:
|
|
|
|
|
|
// 18-24小时:扣90%,允许下架
|
|
|
|
|
|
return true, 0.9, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 阶段2:24-30小时(禁止下架)
|
|
|
|
|
|
if hours >= 24 && hours < 30 {
|
|
|
|
|
|
return false, 0.0, errors.New("24-30小时交易期,禁止下架")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 阶段3:30小时后(自由下架,0扣费)
|
|
|
|
|
|
if hours >= 30 {
|
|
|
|
|
|
return true, 0.0, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 异常情况(上架时间在未来)
|
|
|
|
|
|
return false, 0.0, errors.New("商品未到上架时间,无法操作下架")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CalculateOffShelfAmount 根据扣费比例计算实际扣费金额
|
|
|
|
|
|
func (tt *Pet) CalculateOffShelfAmount(feeRate float64) float64 {
|
|
|
|
|
|
return float64(tt.SalePrice) * feeRate
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-07 02:50:35 +08:00
|
|
|
|
type Attr uint32
|
|
|
|
|
|
|
|
|
|
|
|
func (r Attr) sub() uint32 {
|
|
|
|
|
|
if r > 0 {
|
|
|
|
|
|
return uint32(r) - 1
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
return 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-10 14:19:03 +08:00
|
|
|
|
// PetInfo 精灵信息结构(合并后的优化版本)
|
2025-07-26 02:06:08 +00:00
|
|
|
|
type PetInfo struct {
|
2025-08-31 06:53:42 +00:00
|
|
|
|
|
2025-08-24 17:33:19 +08:00
|
|
|
|
// 精灵编号(@UInt long → uint32)
|
|
|
|
|
|
ID uint32 `fieldDesc:"精灵编号" `
|
|
|
|
|
|
|
|
|
|
|
|
// 名字:默认为全0,补齐到16字节(固定长度 → [16]byte)
|
2026-02-08 17:57:42 +08:00
|
|
|
|
Name string `struc:"[16]byte" json:"Name,omitempty"`
|
2026-03-07 15:15:15 +08:00
|
|
|
|
Gender int `struc:"uint16" fieldDesc:"性别" ` //0:无性别,1:雄性, 2:雌性
|
2026-01-19 18:51:56 +08:00
|
|
|
|
//generation
|
2026-02-08 17:57:42 +08:00
|
|
|
|
|
|
|
|
|
|
Generation uint16 `fieldDesc:"世代" `
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 个体值(@UInt long → uint32)
|
2025-12-07 02:50:35 +08:00
|
|
|
|
Dv uint32 `struc:"uint32" `
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 性格(@UInt long → uint32)
|
|
|
|
|
|
Nature uint32 `fieldDesc:"性格" `
|
|
|
|
|
|
|
|
|
|
|
|
// 等级(@UInt long → uint32)
|
|
|
|
|
|
Level uint32 `fieldDesc:"等级" `
|
|
|
|
|
|
|
|
|
|
|
|
// 当前等级已获得经验(@UInt long → uint32)
|
2026-02-12 04:28:20 +08:00
|
|
|
|
Exp int64 `struc:"uint32"`
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 当前等级所需经验(@UInt long → uint32)
|
2026-02-12 04:28:20 +08:00
|
|
|
|
LvExp int64 `struc:"uint32"`
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 升到下一级的经验(@UInt long → uint32)
|
2026-02-12 04:28:20 +08:00
|
|
|
|
NextLvExp int64 `struc:"uint32"`
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 当前生命(@UInt long → uint32)
|
2025-12-11 12:16:32 +08:00
|
|
|
|
Hp uint32
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 最大生命(@UInt long → uint32)
|
|
|
|
|
|
MaxHp uint32 `fieldDesc:"最大生命" `
|
2025-09-17 00:38:15 +08:00
|
|
|
|
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
|
|
|
|
|
|
Prop [5]uint32 `fieldDesc:"属性" `
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
2025-11-02 18:56:16 +08:00
|
|
|
|
// * ev:生命学习力,攻击学习力,防御学习力,特攻学习力,特防学习力,速度学习力
|
|
|
|
|
|
Ev [6]uint32 `fieldDesc:"属性" `
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
2025-12-14 05:34:39 +08:00
|
|
|
|
SkillListLen uint32 `struc:"sizeof=SkillList" json:"-"`
|
2025-10-26 20:56:03 +08:00
|
|
|
|
|
2025-08-24 17:33:19 +08:00
|
|
|
|
// 技能信息:固定4条,空则赋值0(固定长度List → [4]SkillInfo,零值即符合“赋值0”)
|
2025-10-26 20:56:03 +08:00
|
|
|
|
SkillList []SkillInfo
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 捕捉时间(@UInt long → 若为时间戳用uint32;若需时间类型可改为time.Time,需配合序列化处理)
|
2025-12-14 05:34:39 +08:00
|
|
|
|
CatchTime uint32 //显式忽略,不参与序列化
|
2025-12-03 22:05:28 +08:00
|
|
|
|
OldCatchTime uint32 `struc:"skip" fieldDesc:"旧捕捉时间" `
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 捕捉地图(@UInt long → uint32)
|
2025-12-14 05:34:39 +08:00
|
|
|
|
CatchMap uint32 `json:"CatchMap,omitempty"`
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 未知默认0(@UInt long → uint32)
|
2025-12-14 05:34:39 +08:00
|
|
|
|
CatchRect uint32 `json:"CatchRect,omitempty"`
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 捕获等级默认0(@UInt long → uint32)
|
|
|
|
|
|
CatchLevel uint32 `fieldDesc:"捕获等级 默认为0" `
|
2025-12-14 05:34:39 +08:00
|
|
|
|
EffectInfoLen uint16 `struc:"sizeof=EffectInfo" json:"-"`
|
2025-12-07 01:43:12 +08:00
|
|
|
|
// 特性列表:长度用UShort存储(变长List → []PetEffectInfo + 长度前缀规则) 第一个一定是特性
|
2026-02-08 17:57:42 +08:00
|
|
|
|
EffectInfo []PetEffectInfo
|
2025-08-24 17:33:19 +08:00
|
|
|
|
|
|
|
|
|
|
// 皮肤ID默认0(@UInt long → uint32)
|
|
|
|
|
|
SkinID uint32 `fieldDesc:"皮肤id默认为0" `
|
|
|
|
|
|
|
|
|
|
|
|
// 是否闪光(@UInt long → uint32,0=否,1=是)
|
2026-02-08 17:57:42 +08:00
|
|
|
|
ShinyLen uint32 `struc:"sizeof=ShinyInfo"`
|
2025-12-21 17:18:33 +00:00
|
|
|
|
ShinyInfo []data.GlowFilter `json:"ShinyInfo,omitempty"`
|
2025-12-10 16:03:45 +00:00
|
|
|
|
|
|
|
|
|
|
//时间轮转,然后effect根据type同时只共存一个,特性是1 特质是1,柱子是两种,魂印是一个,然后异色字段,然后特训技能字段
|
|
|
|
|
|
ExtSKill []uint32 `struc:"skip"` //特训技能
|
2025-12-11 12:16:32 +08:00
|
|
|
|
ExtSkin []uint32 `struc:"skip"` //可用皮肤
|
2025-07-26 02:06:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-07 11:30:17 +08:00
|
|
|
|
func (pet *PetInfo) ConfigBoss(bm model.PetBaseConfig) {
|
|
|
|
|
|
var color data.GlowFilter
|
|
|
|
|
|
err := json.Unmarshal([]byte(bm.Color), &color)
|
|
|
|
|
|
if err == nil && color.Alpha != 0 {
|
|
|
|
|
|
pet.ShinyInfo = append(pet.ShinyInfo, color)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
if bm.Hp != 0 {
|
|
|
|
|
|
pet.Hp = uint32(bm.Hp)
|
|
|
|
|
|
pet.MaxHp = uint32(bm.Hp)
|
|
|
|
|
|
}
|
|
|
|
|
|
if len(bm.Prop) == 5 {
|
|
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
|
|
if bm.Prop[i] != 0 {
|
|
|
|
|
|
pet.Prop[i] = bm.Prop[i]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//monster.Prop = [5]uint32(bm.Prop)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if len(bm.SKill) != 0 {
|
|
|
|
|
|
|
|
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
|
|
if bm.SKill[i] != 0 {
|
|
|
|
|
|
pet.SkillList[i].ID = bm.SKill[i]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2026-03-07 13:54:42 +08:00
|
|
|
|
|
2026-03-07 11:30:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-04 20:21:02 +08:00
|
|
|
|
func (pet *PetInfo) Type() int {
|
|
|
|
|
|
return xmlres.PetMAP[int(pet.ID)].Type
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2026-03-01 00:02:41 +08:00
|
|
|
|
func (pet *PetInfo) ModelHP(tt int64) {
|
|
|
|
|
|
if pet.Hp <= 0 {
|
|
|
|
|
|
if tt > int64(pet.Hp) {
|
|
|
|
|
|
pet.Hp = 0
|
|
|
|
|
|
} else {
|
|
|
|
|
|
pet.Hp += uint32(tt)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
pet.Hp += uint32(tt)
|
|
|
|
|
|
if pet.Hp > pet.MaxHp {
|
|
|
|
|
|
pet.Hp = pet.MaxHp
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (pet *PetInfo) HealPP(value int) {
|
|
|
|
|
|
for i := 0; i < len(pet.SkillList); i++ {
|
|
|
|
|
|
if value == -1 {
|
|
|
|
|
|
pet.SkillList[i].PP = uint32(xmlres.SkillMap[int(pet.SkillList[i].ID)].MaxPP)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
pet.SkillList[i].PP += uint32(value)
|
|
|
|
|
|
pet.SkillList[i].PP = utils.Min(pet.SkillList[i].PP, uint32(xmlres.SkillMap[int(pet.SkillList[i].ID)].MaxPP))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-23 00:06:14 +08:00
|
|
|
|
// 定义常量,提升可维护性(避免魔法数字)
|
|
|
|
|
|
const (
|
|
|
|
|
|
maxSingleEV uint32 = 255 // 单个EV最大值
|
|
|
|
|
|
maxTotalEV uint32 = 510 // 6个EV总和最大值
|
|
|
|
|
|
evFieldCount = 6 // EV字段数量(固定6个)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// AddEV 优化后的EV值增加方法(符合Go命名规范:大写导出,动词开头)
|
|
|
|
|
|
// 功能:为宠物6个EV值增加增量,保证单个≤255、总和≤510
|
|
|
|
|
|
// 参数:evadd - 6个EV字段的增量数组(长度必须为6)
|
|
|
|
|
|
// 返回:error - 参数非法/逻辑异常时返回错误;bool - 是否触发了超额削减(方便业务监控)
|
2026-02-12 04:28:20 +08:00
|
|
|
|
func (pet *PetInfo) AddEV(ev_add []int64) (bool, error) {
|
2025-11-23 00:06:14 +08:00
|
|
|
|
// 1. 参数安全校验:避免数组越界panic
|
2026-01-19 18:51:56 +08:00
|
|
|
|
if len(ev_add) != evFieldCount {
|
|
|
|
|
|
return false, fmt.Errorf("evadd长度必须为%d,当前为%d", evFieldCount, len(ev_add))
|
2025-11-23 00:06:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
if len(pet.Ev) != evFieldCount {
|
|
|
|
|
|
return false, errors.New("pet.Ev未初始化或长度不为6")
|
2025-11-22 22:57:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 2. 第一步:直接添加并限制单项最大值(按索引顺序处理)
|
|
|
|
|
|
var tempEV [evFieldCount]uint32
|
2025-11-23 00:06:14 +08:00
|
|
|
|
for i := 0; i < evFieldCount; i++ {
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 直接累加增量
|
2026-02-12 04:28:20 +08:00
|
|
|
|
tempEV[i] = pet.Ev[i] + uint32(ev_add[i])
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 单项不超过255
|
2025-11-23 00:06:14 +08:00
|
|
|
|
if tempEV[i] > maxSingleEV {
|
|
|
|
|
|
tempEV[i] = maxSingleEV
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-22 22:57:32 +08:00
|
|
|
|
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 3. 计算增量后的总和,检查是否超过510
|
2025-11-25 00:55:10 +08:00
|
|
|
|
totalTemp := lo.Sum(tempEV[:])
|
2025-11-22 22:57:32 +08:00
|
|
|
|
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 4. 若总和超额,按索引顺序(0→5)削减(优先削减前面的字段)
|
2025-11-23 00:06:14 +08:00
|
|
|
|
hasCut := false
|
|
|
|
|
|
if totalTemp > maxTotalEV {
|
|
|
|
|
|
overTotal := totalTemp - maxTotalEV // 需要削减的总量
|
|
|
|
|
|
hasCut = true
|
|
|
|
|
|
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 按索引顺序遍历削减(从第0个字段开始,依次处理)
|
|
|
|
|
|
for i := 0; i < evFieldCount && overTotal > 0; i++ {
|
|
|
|
|
|
// 可削减的最大值:最多削减到原始值(不触碰添加前的基础EV)
|
|
|
|
|
|
cutAble := tempEV[i] - pet.Ev[i]
|
|
|
|
|
|
if cutAble <= 0 {
|
|
|
|
|
|
continue // 该字段无增量可削减,跳过
|
2025-11-23 00:06:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 实际削减量:取"可削减量"和"剩余需削减量"的较小值
|
2025-11-23 00:06:14 +08:00
|
|
|
|
cut := cutAble
|
|
|
|
|
|
if cut > overTotal {
|
|
|
|
|
|
cut = overTotal
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 执行削减
|
2025-11-23 09:59:34 +00:00
|
|
|
|
tempEV[i] -= cut
|
2025-11-23 00:06:14 +08:00
|
|
|
|
overTotal -= cut
|
|
|
|
|
|
}
|
2025-11-23 09:59:34 +00:00
|
|
|
|
|
|
|
|
|
|
// 极端情况:即使削减所有增量后仍超额(如原始EV总和已超510),继续按顺序削减原始值
|
|
|
|
|
|
if overTotal > 0 {
|
|
|
|
|
|
for i := 0; i < evFieldCount && overTotal > 0; i++ {
|
|
|
|
|
|
// 此时可削减到0(根据业务需求调整,也可返回错误)
|
|
|
|
|
|
cutAble := tempEV[i]
|
|
|
|
|
|
if cutAble <= 0 {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cut := cutAble
|
|
|
|
|
|
if cut > overTotal {
|
|
|
|
|
|
cut = overTotal
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tempEV[i] -= cut
|
|
|
|
|
|
overTotal -= cut
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-11-23 00:06:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-23 09:59:34 +00:00
|
|
|
|
// 5. 将处理后的结果赋值给原EV数组
|
2025-11-23 00:06:14 +08:00
|
|
|
|
copy(pet.Ev[:], tempEV[:])
|
|
|
|
|
|
|
|
|
|
|
|
return hasCut, nil
|
2025-11-22 22:57:32 +08:00
|
|
|
|
}
|
2025-10-13 19:46:19 +08:00
|
|
|
|
func (pet *PetInfo) Cure() {
|
|
|
|
|
|
pet.Hp = pet.MaxHp
|
2025-10-27 01:11:31 +08:00
|
|
|
|
for i := 0; i < len(pet.SkillList); i++ {
|
2025-10-13 19:46:19 +08:00
|
|
|
|
maxPP, ok := xmlres.SkillMap[int(pet.SkillList[i].ID)]
|
|
|
|
|
|
// 恢复至最大PP值(从配置表获取)
|
|
|
|
|
|
if pet.SkillList[i].ID != 0 && ok {
|
|
|
|
|
|
pet.SkillList[i].PP = uint32(maxPP.MaxPP)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-17 22:36:18 +08:00
|
|
|
|
|
2026-02-17 22:56:55 +08:00
|
|
|
|
// 强制选色,这个是给熔炉用的
|
2026-03-04 14:12:48 +08:00
|
|
|
|
func (pet *PetInfo) FixShiny() bool {
|
2025-12-30 00:45:23 +08:00
|
|
|
|
|
2026-02-21 17:32:40 +08:00
|
|
|
|
co := service.NewShinyService().RandShiny(pet.ID)
|
2026-02-21 18:07:46 +08:00
|
|
|
|
if co != nil {
|
2026-02-23 07:30:30 +08:00
|
|
|
|
pet.ShinyInfo = []data.GlowFilter{*co}
|
2026-03-04 14:12:48 +08:00
|
|
|
|
return true
|
2026-02-21 18:07:46 +08:00
|
|
|
|
}
|
2026-03-04 14:12:48 +08:00
|
|
|
|
return false
|
2026-02-17 22:36:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 比重融合
|
|
|
|
|
|
func (pet *PetInfo) RandomByWeightShiny() {
|
|
|
|
|
|
|
|
|
|
|
|
co := service.NewShinyService().RandomByWeightShiny(pet.ID)
|
2026-02-23 01:24:13 +08:00
|
|
|
|
if co != nil {
|
2026-02-23 07:30:30 +08:00
|
|
|
|
pet.ShinyInfo = []data.GlowFilter{*co}
|
2026-02-23 01:24:13 +08:00
|
|
|
|
}
|
2026-02-17 22:36:18 +08:00
|
|
|
|
|
2025-12-30 00:10:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
func (pet *PetInfo) IsShiny() bool {
|
|
|
|
|
|
|
|
|
|
|
|
return len(pet.ShinyInfo) > 0
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-10-24 23:33:28 +08:00
|
|
|
|
|
2025-12-07 01:43:12 +08:00
|
|
|
|
// 随机特性
|
2025-12-30 02:15:33 +00:00
|
|
|
|
func (pet *PetInfo) RnadEffect() {
|
2025-12-07 01:43:12 +08:00
|
|
|
|
|
|
|
|
|
|
for _, v := range xmlres.PlayerEffectMAP {
|
2025-12-30 02:15:33 +00:00
|
|
|
|
if gconv.Int(v.StarLevel) == 0 {
|
2025-12-07 01:43:12 +08:00
|
|
|
|
ret := &PetEffectInfo{
|
|
|
|
|
|
Idx: uint16(gconv.Int16(v.Idx)),
|
|
|
|
|
|
Status: 1,
|
|
|
|
|
|
EID: uint16(gconv.Int16(v.Eid)),
|
|
|
|
|
|
Args: v.ArgsS,
|
|
|
|
|
|
}
|
2025-12-10 14:04:06 +00:00
|
|
|
|
_, eff, ok := pet.GetEffect(1)
|
|
|
|
|
|
if ok {
|
2026-02-06 00:12:16 +08:00
|
|
|
|
if eff.Idx == ret.Idx {
|
|
|
|
|
|
continue
|
|
|
|
|
|
}
|
2025-12-09 18:49:36 +08:00
|
|
|
|
|
2025-12-10 14:04:06 +00:00
|
|
|
|
copier.Copy(eff, ret)
|
2025-12-09 18:49:36 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
pet.EffectInfo = append(pet.EffectInfo, *ret)
|
2025-12-07 01:43:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2025-12-30 02:15:33 +00:00
|
|
|
|
|
2025-12-07 01:43:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-10 16:03:45 +00:00
|
|
|
|
// 1是特性特质,<!-- Stat: 精灵特效Stat: 0: 无效(默认值), 1: 永久, 2: 有`有效次数'的特效 3: 爆发特效 4: 异能精灵特质,5特训,6魂印-->
|
2025-12-10 14:04:06 +00:00
|
|
|
|
func (pet *PetInfo) GetEffect(ptype int) (int, *PetEffectInfo, bool) {
|
2025-12-07 01:43:12 +08:00
|
|
|
|
|
2025-12-10 14:04:06 +00:00
|
|
|
|
return utils.FindWithIndex(pet.EffectInfo, func(item PetEffectInfo) bool {
|
2025-12-07 02:50:35 +08:00
|
|
|
|
return gconv.Int(xmlres.EffectMAP[int(item.Idx)].Stat) == 1
|
2025-12-07 01:43:12 +08:00
|
|
|
|
})
|
2025-12-10 14:04:06 +00:00
|
|
|
|
|
2025-12-07 01:43:12 +08:00
|
|
|
|
}
|
2025-12-10 14:04:06 +00:00
|
|
|
|
|
2025-11-22 22:57:32 +08:00
|
|
|
|
func (pet *PetInfo) Downgrade(level uint32) {
|
|
|
|
|
|
|
|
|
|
|
|
for pet.Level > uint32(level) {
|
|
|
|
|
|
basic, ok := xmlres.PetMAP[int(pet.ID)]
|
|
|
|
|
|
|
|
|
|
|
|
if ok {
|
|
|
|
|
|
|
2026-03-01 11:25:30 +08:00
|
|
|
|
if basic.EvolvesFrom != 0 && xmlres.PetMAP[int(basic.EvolvesFrom)].EvolvFlag == 0 {
|
|
|
|
|
|
|
2025-11-22 22:57:32 +08:00
|
|
|
|
pet.ID = uint32(basic.EvolvesFrom)
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
pet.Level--
|
|
|
|
|
|
//进行降级操作
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2026-02-03 21:45:20 +08:00
|
|
|
|
pet.NextLvExp = 0
|
|
|
|
|
|
pet.Update(false)
|
2025-11-22 22:57:32 +08:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-13 21:47:07 +08:00
|
|
|
|
// 执行进化逻辑 ,是否进化
|
|
|
|
|
|
func (petinfo *PetInfo) Update(isup bool) {
|
2025-11-20 05:57:29 +08:00
|
|
|
|
|
2025-11-22 22:57:32 +08:00
|
|
|
|
// 最大进化次数限制(防止配置表闭环导致死循环)
|
2026-03-07 18:50:51 +08:00
|
|
|
|
maxEvolveTimes := 1
|
2025-11-22 22:57:32 +08:00
|
|
|
|
evolveCount := 0
|
2025-11-20 05:57:29 +08:00
|
|
|
|
|
2025-11-22 22:57:32 +08:00
|
|
|
|
// 循环进化:直到不满足进化条件 或 达到最大进化次数
|
|
|
|
|
|
for {
|
|
|
|
|
|
// 防止死循环,超出次数直接退出
|
|
|
|
|
|
if evolveCount >= maxEvolveTimes {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2025-12-13 21:47:07 +08:00
|
|
|
|
// 进化完成后,统一更新经验(原逻辑保留)
|
|
|
|
|
|
petinfo.LvExp = petinfo.NextLvExp
|
2025-11-22 22:57:32 +08:00
|
|
|
|
// 获取当前宠物形态的配置
|
|
|
|
|
|
basic, ok := xmlres.PetMAP[int(petinfo.ID)]
|
|
|
|
|
|
// 配置不存在,直接退出循环
|
|
|
|
|
|
if !ok {
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2025-12-13 21:47:07 +08:00
|
|
|
|
petinfo.NextLvExp = calculateExperience(petinfo.Level, basic.GetBasic())
|
|
|
|
|
|
if !isup {
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
2025-11-22 22:57:32 +08:00
|
|
|
|
// 检查是否满足进化条件
|
|
|
|
|
|
canEvolve := basic.EvolvesTo != 0 && // 有明确的进化目标
|
|
|
|
|
|
int(petinfo.Level) >= basic.EvolvingLv && // 等级达到进化要求
|
|
|
|
|
|
basic.IsLarge == 0 // 非最终形态
|
2025-11-20 05:57:29 +08:00
|
|
|
|
|
2025-11-22 22:57:32 +08:00
|
|
|
|
// 不满足进化条件,退出循环
|
|
|
|
|
|
if !canEvolve {
|
|
|
|
|
|
break
|
2025-10-24 23:33:28 +08:00
|
|
|
|
}
|
2025-11-22 22:57:32 +08:00
|
|
|
|
|
|
|
|
|
|
// 执行进化:更新宠物ID为进化后形态
|
|
|
|
|
|
petinfo.ID = uint32(basic.EvolvesTo)
|
|
|
|
|
|
evolveCount++ // 进化次数+1
|
2025-10-18 23:58:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-25 12:29:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-18 23:58:19 +08:00
|
|
|
|
// calculateExperience 计算指定等级和种族值所需的经验值
|
|
|
|
|
|
// level: 当前等级
|
|
|
|
|
|
// baseValue: 种族值
|
2026-02-12 04:28:20 +08:00
|
|
|
|
func calculateExperience(level uint32, baseValue uint32) int64 {
|
2025-10-18 23:58:19 +08:00
|
|
|
|
// 计算 A 部分:向上取整(3.75 * a * (a + 1))
|
|
|
|
|
|
partA := math.Ceil(3.75 * float64(level) * float64(level+1))
|
|
|
|
|
|
|
|
|
|
|
|
// 计算 B 部分:向上取整(b * log(1 + a / 100))
|
|
|
|
|
|
// 这里使用自然对数 math.Log,如果想换底数可以用换底公式
|
|
|
|
|
|
partB := math.Log(1.0 + float64(level)/100.0)
|
|
|
|
|
|
partB = float64(baseValue) * partB
|
|
|
|
|
|
partB = math.Ceil(partB)
|
|
|
|
|
|
|
|
|
|
|
|
// 总经验是两部分之和,并向上取整
|
|
|
|
|
|
totalExp := math.Ceil(partA + partB)
|
2026-02-17 22:36:18 +08:00
|
|
|
|
return int64(totalExp)
|
2025-10-18 23:58:19 +08:00
|
|
|
|
}
|
2025-10-13 19:46:19 +08:00
|
|
|
|
|
2025-08-10 14:19:03 +08:00
|
|
|
|
// PetEffectInfo 精灵特性信息结构
|
2025-09-15 23:18:09 +08:00
|
|
|
|
// <!-- NewSeIdx: 精灵特效索引 (默认0: 无效) -->
|
|
|
|
|
|
// <!-- Type: 0 - 仅单人战斗; 1 - 仅组队战斗; 2 - both; (默认0: 仅单人) -->
|
|
|
|
|
|
// <!-- Eid: 精灵特效eid (默认0: 无效) -->
|
|
|
|
|
|
// <!-- Stat: 精灵特效Stat: 0: 无效(默认值), 1: 永久, 2: 有`有效次数'的特效 3: 爆发特效 4: 异能精灵特质-->
|
|
|
|
|
|
// <!-- Times: 精灵特效可使用次数: 当type==2时有效 (默认值:0) -->
|
|
|
|
|
|
// <!-- Args: 特效参数, 不超过8个 (注意: 每个参数不能超过 65535) -->
|
|
|
|
|
|
// <!-- AdditionType:特效加成类型 1 种族值加成 2 技能威力加成 -->
|
2025-07-26 02:06:08 +00:00
|
|
|
|
type PetEffectInfo struct {
|
2025-09-20 13:12:45 +08:00
|
|
|
|
ItemID uint32 `struc:"uint32" json:"item_id"` //如果是能量珠,就显示
|
|
|
|
|
|
Idx uint16 `struc:"skip" json:"new_se_idx"`
|
2025-12-03 22:05:28 +08:00
|
|
|
|
Type byte `struc:"skip" json:"type"` //pvp pve特性区分,待前端修改实现
|
2025-09-15 23:18:09 +08:00
|
|
|
|
Status byte `struc:"byte" json:"status"` //特性为1,能量珠为2
|
|
|
|
|
|
LeftCount byte `struc:"byte" json:"left_count"` //剩余次数
|
|
|
|
|
|
EID uint16 `struc:"uint16" json:"effect_id"` //特效ID
|
2025-12-14 05:34:39 +08:00
|
|
|
|
ArgsLen uint32 `struc:"sizeof=Args" json:"-"`
|
2025-09-16 22:51:22 +08:00
|
|
|
|
|
|
|
|
|
|
Args []int ` json:"Args"` //自定义参数装载
|
2025-09-15 23:18:09 +08:00
|
|
|
|
|
2025-07-26 02:06:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-26 23:22:10 +00:00
|
|
|
|
// SkillInfo 精灵技能信息结构(SkillInfo)
|
2025-08-15 08:17:43 +00:00
|
|
|
|
type SkillInfo struct {
|
2025-08-31 00:27:07 +08:00
|
|
|
|
ID uint32
|
2025-09-04 19:37:28 +08:00
|
|
|
|
PP uint32
|
2025-08-15 08:17:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-09 23:44:09 +08:00
|
|
|
|
func (s *SkillInfo) Use(count int) {
|
|
|
|
|
|
s.PP -= uint32(count)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-26 02:06:08 +00:00
|
|
|
|
// TableName Pet's table name
|
|
|
|
|
|
func (*Pet) TableName() string {
|
|
|
|
|
|
return TableNamePet
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// GroupName Pet's table group
|
|
|
|
|
|
func (*Pet) GroupName() string {
|
|
|
|
|
|
return "default"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// NewPet create a new Pet
|
|
|
|
|
|
func NewPet() *Pet {
|
|
|
|
|
|
return &Pet{
|
2026-01-08 03:30:18 +08:00
|
|
|
|
Base: *NewBase(),
|
2025-07-26 02:06:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// init 创建表
|
|
|
|
|
|
func init() {
|
|
|
|
|
|
_ = cool.CreateTable(&Pet{})
|
2025-11-25 12:29:50 +08:00
|
|
|
|
|
2025-07-26 02:06:08 +00:00
|
|
|
|
// fmt.Println(err)
|
|
|
|
|
|
}
|
2025-11-25 12:29:50 +08:00
|
|
|
|
|
|
|
|
|
|
// GenPetInfo 生成一个新的精灵实例
|
|
|
|
|
|
// - 参数为 -1 时表示随机生成对应属性
|
|
|
|
|
|
// * @param petTypeId 精灵类型ID
|
|
|
|
|
|
// * @param individualValue 个体值(0-31)
|
|
|
|
|
|
// * @param natureId 性格ID(0-24)
|
|
|
|
|
|
// * @param abilityTypeEnum 特性类型ID(0=无, >0=指定, -1=随机)
|
|
|
|
|
|
// * @param shinyid 闪光ID(-1=随机)
|
|
|
|
|
|
// * @param level 等级(1-100)
|
|
|
|
|
|
// * @return 生成的精灵实体
|
2025-10-24 00:31:38 +08:00
|
|
|
|
func GenPetInfo(
|
|
|
|
|
|
id int,
|
2025-12-21 17:18:33 +00:00
|
|
|
|
dv, natureId, abilityTypeEnum, level int, shinyid []data.GlowFilter,
|
2026-02-08 17:57:42 +08:00
|
|
|
|
gen int,
|
2025-10-24 00:31:38 +08:00
|
|
|
|
) *PetInfo {
|
2026-02-09 01:29:33 +08:00
|
|
|
|
if id == 0 {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
2025-10-24 00:31:38 +08:00
|
|
|
|
// 创建随机源
|
2025-12-08 19:16:37 +08:00
|
|
|
|
//rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
2025-10-24 00:31:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 初始化精灵
|
|
|
|
|
|
p := &PetInfo{
|
|
|
|
|
|
ID: uint32(id),
|
|
|
|
|
|
CatchTime: uint32(time.Now().Unix()),
|
|
|
|
|
|
Level: uint32(level),
|
|
|
|
|
|
EffectInfo: make([]PetEffectInfo, 0),
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---- 处理闪光 ----
|
2025-12-14 19:23:26 +08:00
|
|
|
|
if shinyid != nil {
|
2025-12-10 16:03:45 +00:00
|
|
|
|
//todo 待实现异色字段
|
2025-12-14 19:23:26 +08:00
|
|
|
|
p.ShinyInfo = shinyid
|
2026-02-08 17:57:42 +08:00
|
|
|
|
// r := service.NewShinyService().GetShiny(shinyid)
|
|
|
|
|
|
// if r != nil {
|
|
|
|
|
|
// p.ShinyInfo = append(p.ShinyInfo, *r)
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
2025-12-10 16:03:45 +00:00
|
|
|
|
// p.Shiny = uint32(shinyid)
|
2025-10-24 00:31:38 +08:00
|
|
|
|
}
|
2026-02-08 17:57:42 +08:00
|
|
|
|
if gen == -1 {
|
|
|
|
|
|
|
|
|
|
|
|
p.Gender = grand.N(1, 4)
|
2026-02-09 01:29:33 +08:00
|
|
|
|
if cool.Config.ServerInfo.IsVip != 0 {
|
|
|
|
|
|
p.Gender = grand.N(1, 2)
|
|
|
|
|
|
}
|
2026-02-08 17:57:42 +08:00
|
|
|
|
if p.Gender == 3 || p.Gender == 4 {
|
|
|
|
|
|
p.Gender = 0
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-24 00:31:38 +08:00
|
|
|
|
|
|
|
|
|
|
// ---- 性格 ----
|
|
|
|
|
|
if natureId == -1 {
|
2025-12-08 19:16:37 +08:00
|
|
|
|
p.Nature = uint32(grand.Intn(25))
|
2025-10-24 00:31:38 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
p.Nature = uint32(natureId)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---- 个体值(DV)----
|
|
|
|
|
|
if dv == -1 {
|
2025-12-08 19:16:37 +08:00
|
|
|
|
p.Dv = uint32(CalculateIndividualValue())
|
2025-10-24 00:31:38 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
if dv < 0 {
|
|
|
|
|
|
dv = 0
|
|
|
|
|
|
} else if dv > 31 {
|
|
|
|
|
|
dv = 31
|
|
|
|
|
|
}
|
|
|
|
|
|
p.Dv = uint32(dv)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---- 特性 ----
|
|
|
|
|
|
switch {
|
|
|
|
|
|
case abilityTypeEnum == 0:
|
|
|
|
|
|
// 无特性
|
|
|
|
|
|
case abilityTypeEnum > 0:
|
|
|
|
|
|
// 指定特性
|
|
|
|
|
|
if v, ok := xmlres.PlayerEffectMAP[int(abilityTypeEnum)]; ok {
|
|
|
|
|
|
p.EffectInfo = append(p.EffectInfo, PetEffectInfo{
|
|
|
|
|
|
Idx: uint16(gconv.Int16(v.Idx)),
|
|
|
|
|
|
Status: 1,
|
|
|
|
|
|
EID: uint16(gconv.Int16(v.Eid)),
|
|
|
|
|
|
Args: v.ArgsS,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
case abilityTypeEnum == -1:
|
|
|
|
|
|
|
|
|
|
|
|
for _, v := range xmlres.PlayerEffectMAP {
|
2025-12-30 02:15:33 +00:00
|
|
|
|
if gconv.Int(v.StarLevel) == 0 {
|
|
|
|
|
|
p.EffectInfo = append(p.EffectInfo, PetEffectInfo{
|
|
|
|
|
|
Idx: uint16(gconv.Int16(v.Idx)),
|
|
|
|
|
|
Status: 1,
|
|
|
|
|
|
EID: uint16(gconv.Int16(v.Eid)),
|
|
|
|
|
|
Args: v.ArgsS,
|
|
|
|
|
|
})
|
|
|
|
|
|
break
|
|
|
|
|
|
}
|
2025-12-11 14:34:56 +00:00
|
|
|
|
|
2025-10-24 00:31:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---- 技能学习 ----
|
2025-11-23 23:38:03 +00:00
|
|
|
|
skills := utils.LastFourElements(p.GetLevelRangeCanLearningSkills(0, p.Level), 4) // 最后四个技能
|
2025-10-24 00:31:38 +08:00
|
|
|
|
|
2025-10-26 20:56:03 +08:00
|
|
|
|
for i := 0; i < len(skills) && i < 4; i++ {
|
2025-10-24 00:31:38 +08:00
|
|
|
|
skillID := skills[i]
|
|
|
|
|
|
if info, ok := xmlres.SkillMap[int(skillID)]; ok {
|
2025-10-26 20:56:03 +08:00
|
|
|
|
p.SkillList = append(p.SkillList, SkillInfo{ID: skillID, PP: uint32(info.MaxPP)})
|
|
|
|
|
|
|
2025-10-24 00:31:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-10-31 00:53:22 +08:00
|
|
|
|
if len(p.SkillList) > 4 {
|
|
|
|
|
|
p.SkillList = p.SkillList[:4]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-24 00:31:38 +08:00
|
|
|
|
// ---- 属性计算 ----
|
2026-03-23 22:00:05 +08:00
|
|
|
|
p.CalculatePetPane(0)
|
2025-10-24 00:31:38 +08:00
|
|
|
|
|
2025-12-13 21:47:07 +08:00
|
|
|
|
p.Update(false)
|
2025-10-24 00:31:38 +08:00
|
|
|
|
|
|
|
|
|
|
return p
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 除数数组(放大100倍)
|
|
|
|
|
|
// 数组按递增顺序排列,用于判断个体值等级
|
|
|
|
|
|
var divisors = []int{
|
|
|
|
|
|
600, 1200, 1900, 2700, 3600, 4600, 5700, 6900, 8200, 9600,
|
|
|
|
|
|
11100, 12700, 14400, 16200, 18100, 20100, 22100, 24000,
|
|
|
|
|
|
25800, 27500, 29100, 30600, 32000, 33300, 34500, 35600,
|
|
|
|
|
|
36600, 37500, 38300, 39000, 39600,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CalculateIndividual 根据给定的a值计算个体值
|
|
|
|
|
|
// 返回值表示a大于等于多少个除数(范围:0-31)
|
|
|
|
|
|
func CalculateIndividual(a int) int {
|
|
|
|
|
|
individual := 0
|
|
|
|
|
|
for _, divisor := range divisors {
|
|
|
|
|
|
if a >= divisor {
|
|
|
|
|
|
individual++
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break // 数组是递增的,可提前跳出循环
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return individual
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CalculateIndividualValue 计算个体值(0-31)
|
|
|
|
|
|
// 接收外部随机数生成器,便于控制随机性和复用
|
2025-12-08 19:16:37 +08:00
|
|
|
|
func CalculateIndividualValue() int {
|
2025-10-24 00:31:38 +08:00
|
|
|
|
// 生成0-40000的随机数,作为个体值计算的输入
|
2025-12-08 19:16:37 +08:00
|
|
|
|
a := grand.Intn(40001)
|
2025-10-24 00:31:38 +08:00
|
|
|
|
return CalculateIndividual(a)
|
|
|
|
|
|
}
|