mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
圣遗物追加词条初步
This commit is contained in:
@@ -24,31 +24,32 @@ type GameDataConfig struct {
|
|||||||
jsonPrefix string
|
jsonPrefix string
|
||||||
luaPrefix string
|
luaPrefix string
|
||||||
// 配置表数据
|
// 配置表数据
|
||||||
AvatarDataMap map[int32]*AvatarData // 角色
|
AvatarDataMap map[int32]*AvatarData // 角色
|
||||||
AvatarSkillDataMap map[int32]*AvatarSkillData // 角色技能
|
AvatarSkillDataMap map[int32]*AvatarSkillData // 角色技能
|
||||||
AvatarSkillDepotDataMap map[int32]*AvatarSkillDepotData // 角色技能库
|
AvatarSkillDepotDataMap map[int32]*AvatarSkillDepotData // 角色技能库
|
||||||
DropGroupDataMap map[int32]*DropGroupData // 掉落组
|
DropGroupDataMap map[int32]*DropGroupData // 掉落组
|
||||||
GCGCharDataMap map[int32]*GCGCharData // 角色卡牌
|
GCGCharDataMap map[int32]*GCGCharData // 角色卡牌
|
||||||
GCGSkillDataMap map[int32]*GCGSkillData // 卡牌技能
|
GCGSkillDataMap map[int32]*GCGSkillData // 卡牌技能
|
||||||
SceneDataMap map[int32]*SceneData // 场景
|
SceneDataMap map[int32]*SceneData // 场景
|
||||||
ScenePointMap map[int32]*ScenePoint // 场景传送点
|
ScenePointMap map[int32]*ScenePoint // 场景传送点
|
||||||
SceneTagDataMap map[int32]*SceneTagData // 场景标签
|
SceneTagDataMap map[int32]*SceneTagData // 场景标签
|
||||||
SceneDetailMap map[int32]*SceneDetail // 场景详情LUA配置数据
|
SceneDetailMap map[int32]*SceneDetail // 场景详情LUA配置数据
|
||||||
WorldAreaDataMap map[int32]*WorldAreaData // 世界区域
|
WorldAreaDataMap map[int32]*WorldAreaData // 世界区域
|
||||||
GatherDataMap map[int32]*GatherData // 采集物
|
GatherDataMap map[int32]*GatherData // 采集物
|
||||||
GatherDataPointTypeMap map[int32]*GatherData // 采集物场景节点索引
|
GatherDataPointTypeMap map[int32]*GatherData // 采集物场景节点索引
|
||||||
FetterDataMap map[int32]*FetterData // 角色资料解锁
|
FetterDataMap map[int32]*FetterData // 角色资料解锁
|
||||||
FetterDataAvatarIdMap map[int32][]int32 // 角色资料解锁角色id索引
|
FetterDataAvatarIdMap map[int32][]int32 // 角色资料解锁角色id索引
|
||||||
ItemDataMap map[int32]*ItemData // 统一道具
|
ItemDataMap map[int32]*ItemData // 统一道具
|
||||||
AvatarLevelDataMap map[int32]*AvatarLevelData // 角色等级
|
AvatarLevelDataMap map[int32]*AvatarLevelData // 角色等级
|
||||||
AvatarPromoteDataMap map[int32]map[int32]*AvatarPromoteData // 角色突破
|
AvatarPromoteDataMap map[int32]map[int32]*AvatarPromoteData // 角色突破
|
||||||
PlayerLevelDataMap map[int32]*PlayerLevelData // 玩家等级
|
PlayerLevelDataMap map[int32]*PlayerLevelData // 玩家等级
|
||||||
WeaponLevelDataMap map[int32]*WeaponLevelData // 武器等级
|
WeaponLevelDataMap map[int32]*WeaponLevelData // 武器等级
|
||||||
WeaponPromoteDataMap map[int32]map[int32]*WeaponPromoteData // 角色突破
|
WeaponPromoteDataMap map[int32]map[int32]*WeaponPromoteData // 角色突破
|
||||||
RewardDataMap map[int32]*RewardData // 奖励
|
RewardDataMap map[int32]*RewardData // 奖励
|
||||||
AvatarCostumeDataMap map[int32]*AvatarCostumeData // 角色时装
|
AvatarCostumeDataMap map[int32]*AvatarCostumeData // 角色时装
|
||||||
AvatarFlycloakDataMap map[int32]*AvatarFlycloakData // 角色风之翼
|
AvatarFlycloakDataMap map[int32]*AvatarFlycloakData // 角色风之翼
|
||||||
ReliquaryMainDataMap map[int32]map[int32]*ReliquaryMainData // 圣遗物主属性
|
ReliquaryMainDataMap map[int32]map[int32]*ReliquaryMainData // 圣遗物主属性
|
||||||
|
ReliquaryAffixDataMap map[int32]map[int32]*ReliquaryAffixData // 圣遗物追加属性
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitGameDataConfig() {
|
func InitGameDataConfig() {
|
||||||
@@ -72,7 +73,7 @@ func ReplaceGameDataConfig() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameDataConfig) loadAll() {
|
func (g *GameDataConfig) loadAll() {
|
||||||
pathPrefix := config.CONF.Hk4e.GameDataConfigPath
|
pathPrefix := config.GetConfig().Hk4e.GameDataConfigPath
|
||||||
|
|
||||||
dirInfo, err := os.Stat(pathPrefix)
|
dirInfo, err := os.Stat(pathPrefix)
|
||||||
if err != nil || !dirInfo.IsDir() {
|
if err != nil || !dirInfo.IsDir() {
|
||||||
@@ -133,6 +134,7 @@ func (g *GameDataConfig) load() {
|
|||||||
g.loadAvatarCostumeData() // 角色时装
|
g.loadAvatarCostumeData() // 角色时装
|
||||||
g.loadAvatarFlycloakData() // 角色风之翼
|
g.loadAvatarFlycloakData() // 角色风之翼
|
||||||
g.loadReliquaryMainData() // 圣遗物主属性
|
g.loadReliquaryMainData() // 圣遗物主属性
|
||||||
|
g.loadReliquaryAffixData() // 圣遗物追加属性
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameDataConfig) readCsvFileData(fileName string) []byte {
|
func (g *GameDataConfig) readCsvFileData(fileName string) []byte {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ type ItemData struct {
|
|||||||
ReliquaryType int32 `csv:"ReliquaryType,omitempty"` // 圣遗物类别
|
ReliquaryType int32 `csv:"ReliquaryType,omitempty"` // 圣遗物类别
|
||||||
MainPropDepotId int32 `csv:"MainPropDepotId,omitempty"` // 主属性库ID
|
MainPropDepotId int32 `csv:"MainPropDepotId,omitempty"` // 主属性库ID
|
||||||
AppendPropDepotId int32 `csv:"AppendPropDepotId,omitempty"` // 追加属性库ID
|
AppendPropDepotId int32 `csv:"AppendPropDepotId,omitempty"` // 追加属性库ID
|
||||||
|
AppendPropCount int32 `csv:"AppendPropCount,omitempty"` // 追加属性初始条数
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameDataConfig) loadItemData() {
|
func (g *GameDataConfig) loadItemData() {
|
||||||
|
|||||||
69
gdconf/reliquary_affix_data.go
Normal file
69
gdconf/reliquary_affix_data.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package gdconf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"hk4e/pkg/logger"
|
||||||
|
|
||||||
|
"github.com/jszwec/csvutil"
|
||||||
|
"github.com/mroth/weightedrand"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReliquaryAffixData 圣遗物追加属性配置表
|
||||||
|
type ReliquaryAffixData struct {
|
||||||
|
AppendPropId int32 `csv:"AppendPropId"` // 追加属性ID
|
||||||
|
AppendPropDepotId int32 `csv:"AppendPropDepotId,omitempty"` // 追加属性库ID
|
||||||
|
PropType int32 `csv:"PropType,omitempty"` // 属性类别
|
||||||
|
RandomWeight int32 `csv:"RandomWeight,omitempty"` // 随机权重
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameDataConfig) loadReliquaryAffixData() {
|
||||||
|
g.ReliquaryAffixDataMap = make(map[int32]map[int32]*ReliquaryAffixData)
|
||||||
|
data := g.readCsvFileData("ReliquaryAffixData.csv")
|
||||||
|
var reliquaryAffixDataList []*ReliquaryAffixData
|
||||||
|
err := csvutil.Unmarshal(data, &reliquaryAffixDataList)
|
||||||
|
if err != nil {
|
||||||
|
info := fmt.Sprintf("parse file error: %v", err)
|
||||||
|
panic(info)
|
||||||
|
}
|
||||||
|
for _, reliquaryAffixData := range reliquaryAffixDataList {
|
||||||
|
// 通过主属性库ID找到
|
||||||
|
_, ok := g.ReliquaryAffixDataMap[reliquaryAffixData.AppendPropDepotId]
|
||||||
|
if !ok {
|
||||||
|
g.ReliquaryAffixDataMap[reliquaryAffixData.AppendPropDepotId] = make(map[int32]*ReliquaryAffixData)
|
||||||
|
}
|
||||||
|
// list -> map
|
||||||
|
g.ReliquaryAffixDataMap[reliquaryAffixData.AppendPropDepotId][reliquaryAffixData.AppendPropId] = reliquaryAffixData
|
||||||
|
}
|
||||||
|
logger.Info("ReliquaryAffixData count: %v", len(g.ReliquaryAffixDataMap))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetReliquaryAffixDataByDepotIdAndPropId(appendPropDepotId int32, appendPropId int32) *ReliquaryAffixData {
|
||||||
|
value, exist := CONF.ReliquaryAffixDataMap[appendPropDepotId]
|
||||||
|
if !exist {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return value[appendPropId]
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetReliquaryAffixDataRandomByDepotId(appendPropDepotId int32) *ReliquaryAffixData {
|
||||||
|
appendPropMap, exist := CONF.ReliquaryAffixDataMap[appendPropDepotId]
|
||||||
|
if !exist {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
choices := make([]weightedrand.Choice, 0, len(appendPropMap))
|
||||||
|
for _, data := range appendPropMap {
|
||||||
|
choices = append(choices, weightedrand.NewChoice(data, uint(data.RandomWeight)))
|
||||||
|
}
|
||||||
|
chooser, err := weightedrand.NewChooser(choices...)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("reliquary append random error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
result := chooser.Pick()
|
||||||
|
return result.(*ReliquaryAffixData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetReliquaryAffixDataMap() map[int32]map[int32]*ReliquaryAffixData {
|
||||||
|
return CONF.ReliquaryAffixDataMap
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ type ReliquaryMainData struct {
|
|||||||
MainPropId int32 `csv:"MainPropId"` // 主属性ID
|
MainPropId int32 `csv:"MainPropId"` // 主属性ID
|
||||||
MainPropDepotId int32 `csv:"MainPropDepotId,omitempty"` // 主属性库ID
|
MainPropDepotId int32 `csv:"MainPropDepotId,omitempty"` // 主属性库ID
|
||||||
PropType int32 `csv:"PropType,omitempty"` // 属性类别
|
PropType int32 `csv:"PropType,omitempty"` // 属性类别
|
||||||
Weight int32 `csv:"Weight,omitempty"` // 随机权重
|
RandomWeight int32 `csv:"RandomWeight,omitempty"` // 随机权重
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameDataConfig) loadReliquaryMainData() {
|
func (g *GameDataConfig) loadReliquaryMainData() {
|
||||||
@@ -53,11 +53,11 @@ func GetReliquaryMainDataRandomByDepotId(mainPropDepotId int32) *ReliquaryMainDa
|
|||||||
}
|
}
|
||||||
choices := make([]weightedrand.Choice, 0, len(mainPropMap))
|
choices := make([]weightedrand.Choice, 0, len(mainPropMap))
|
||||||
for _, data := range mainPropMap {
|
for _, data := range mainPropMap {
|
||||||
choices = append(choices, weightedrand.NewChoice(data, uint(data.Weight)))
|
choices = append(choices, weightedrand.NewChoice(data, uint(data.RandomWeight)))
|
||||||
}
|
}
|
||||||
chooser, err := weightedrand.NewChooser(choices...)
|
chooser, err := weightedrand.NewChooser(choices...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("reliquary main error: %v", err)
|
logger.Error("reliquary main random error: %v", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
result := chooser.Pick()
|
result := chooser.Pick()
|
||||||
|
|||||||
@@ -601,6 +601,11 @@
|
|||||||
"field_name": "AppendPropDepotId",
|
"field_name": "AppendPropDepotId",
|
||||||
"field_type": "int32",
|
"field_type": "int32",
|
||||||
"origin_name": "追加属性库ID"
|
"origin_name": "追加属性库ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field_name": "AppendPropCount",
|
||||||
|
"field_type": "int32",
|
||||||
|
"origin_name": "追加属性初始条数"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -983,7 +988,32 @@
|
|||||||
"origin_name": "属性类别"
|
"origin_name": "属性类别"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"field_name": "Weight",
|
"field_name": "RandomWeight",
|
||||||
|
"field_type": "int32",
|
||||||
|
"origin_name": "随机权重"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"table_name": "ReliquaryAffixData",
|
||||||
|
"field_list": [
|
||||||
|
{
|
||||||
|
"field_name": "AppendPropId",
|
||||||
|
"field_type": "int32",
|
||||||
|
"origin_name": "追加属性ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field_name": "AppendPropDepotId",
|
||||||
|
"field_type": "int32",
|
||||||
|
"origin_name": "追加属性库ID"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field_name": "PropType",
|
||||||
|
"field_type": "int32",
|
||||||
|
"origin_name": "属性类别"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field_name": "RandomWeight",
|
||||||
"field_type": "int32",
|
"field_type": "int32",
|
||||||
"origin_name": "随机权重"
|
"origin_name": "随机权重"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ func (g *GameManager) GetAllReliquaryDataConfig() map[int32]*gdconf.ItemData {
|
|||||||
if (itemId >= 20002 && itemId <= 20004) ||
|
if (itemId >= 20002 && itemId <= 20004) ||
|
||||||
itemId == 23334 ||
|
itemId == 23334 ||
|
||||||
(itemId >= 23300 && itemId <= 23340) {
|
(itemId >= 23300 && itemId <= 23340) {
|
||||||
continue
|
|
||||||
// 跳过无效圣遗物
|
// 跳过无效圣遗物
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
allReliquaryDataConfig[itemId] = itemData
|
allReliquaryDataConfig[itemId] = itemData
|
||||||
}
|
}
|
||||||
@@ -43,17 +43,80 @@ func (g *GameManager) AddUserReliquary(userId uint32, itemId uint32) uint64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
reliquaryId := uint64(g.snowflake.GenId())
|
reliquaryId := uint64(g.snowflake.GenId())
|
||||||
// 根据圣遗物类型给予主属性Id
|
// 圣遗物主属性
|
||||||
player.AddReliquary(itemId, reliquaryId, uint32(reliquaryMainConfig.MainPropId))
|
mainPropId := uint32(reliquaryMainConfig.MainPropId)
|
||||||
|
// 玩家添加圣遗物
|
||||||
|
player.AddReliquary(itemId, reliquaryId, mainPropId)
|
||||||
reliquary := player.GetReliquary(reliquaryId)
|
reliquary := player.GetReliquary(reliquaryId)
|
||||||
if reliquary == nil {
|
if reliquary == nil {
|
||||||
logger.Error("reliquary is nil, itemId: %v, reliquaryId: %v", itemId, reliquaryId)
|
logger.Error("reliquary is nil, itemId: %v, reliquaryId: %v", itemId, reliquaryId)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
// 设置圣遗物初始词条
|
||||||
|
g.AppendReliquaryProp(reliquary, reliquaryConfig.AppendPropCount)
|
||||||
g.SendMsg(cmd.StoreItemChangeNotify, userId, player.ClientSeq, g.PacketStoreItemChangeNotifyByReliquary(reliquary))
|
g.SendMsg(cmd.StoreItemChangeNotify, userId, player.ClientSeq, g.PacketStoreItemChangeNotifyByReliquary(reliquary))
|
||||||
return reliquaryId
|
return reliquaryId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendReliquaryProp 圣遗物追加属性
|
||||||
|
func (g *GameManager) AppendReliquaryProp(reliquary *model.Reliquary, count int32) {
|
||||||
|
// 获取圣遗物配置表
|
||||||
|
reliquaryConfig := gdconf.GetItemDataById(int32(reliquary.ItemId))
|
||||||
|
if reliquaryConfig == nil {
|
||||||
|
logger.Error("reliquary config error, itemId: %v", reliquary.ItemId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 主属性配置表
|
||||||
|
reliquaryMainConfig := gdconf.GetReliquaryMainDataByDepotIdAndPropId(reliquaryConfig.MainPropDepotId, int32(reliquary.MainPropId))
|
||||||
|
if reliquaryMainConfig == nil {
|
||||||
|
logger.Error("reliquary main config error, mainPropDepotId: %v, propId: %v", reliquaryConfig.MainPropDepotId, reliquary.MainPropId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 圣遗物追加属性的次数
|
||||||
|
for i := 0; i < int(count); i++ {
|
||||||
|
// 将要添加的属性
|
||||||
|
appendAffixConfig := gdconf.GetReliquaryAffixDataRandomByDepotId(reliquaryConfig.AppendPropDepotId)
|
||||||
|
if appendAffixConfig == nil {
|
||||||
|
logger.Error("append affix config error, appendPropDepotId: %v", reliquaryConfig.AppendPropDepotId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isNotBoth := false
|
||||||
|
// 如果圣遗物词条为0就直接加不用校验是否相同
|
||||||
|
for len(reliquary.AppendPropIdList) > 0 {
|
||||||
|
if isNotBoth {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 追加的属性类型不能相同
|
||||||
|
for i, propId := range reliquary.AppendPropIdList {
|
||||||
|
targetAffixConfig := gdconf.GetReliquaryAffixDataByDepotIdAndPropId(reliquaryConfig.AppendPropDepotId, int32(propId))
|
||||||
|
if targetAffixConfig == nil {
|
||||||
|
logger.Error("target affix config error, propId: %v", propId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 如果类型相同则重新随机获取一个属性
|
||||||
|
// 追加的属性还不能和主属性相同
|
||||||
|
if appendAffixConfig.PropType == targetAffixConfig.PropType || appendAffixConfig.PropType == reliquaryMainConfig.PropType {
|
||||||
|
reliquaryAffixConfig := gdconf.GetReliquaryAffixDataRandomByDepotId(reliquaryConfig.AppendPropDepotId)
|
||||||
|
if reliquaryAffixConfig == nil {
|
||||||
|
logger.Error("reliquary affix config error, appendPropDepotId: %v", reliquaryConfig.AppendPropDepotId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 将属性赋值并重新查找
|
||||||
|
appendAffixConfig = reliquaryAffixConfig
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 如果循环到最后一个还不匹配那就是没有相同的了
|
||||||
|
if i == len(reliquary.AppendPropIdList)-1 {
|
||||||
|
isNotBoth = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 圣遗物添加词条
|
||||||
|
reliquary.AppendPropIdList = append(reliquary.AppendPropIdList, uint32(appendAffixConfig.AppendPropId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GameManager) CostUserReliquary(userId uint32, reliquaryIdList []uint64) {
|
func (g *GameManager) CostUserReliquary(userId uint32, reliquaryIdList []uint64) {
|
||||||
player := USER_MANAGER.GetOnlineUser(userId)
|
player := USER_MANAGER.GetOnlineUser(userId)
|
||||||
if player == nil {
|
if player == nil {
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ func (p *Player) AddReliquary(itemId uint32, reliquaryId uint64, mainPropId uint
|
|||||||
AvatarId: 0,
|
AvatarId: 0,
|
||||||
Guid: 0,
|
Guid: 0,
|
||||||
}
|
}
|
||||||
_ = itemDataConfig
|
|
||||||
p.InitReliquary(reliquary)
|
p.InitReliquary(reliquary)
|
||||||
p.ReliquaryMap[reliquaryId] = reliquary
|
p.ReliquaryMap[reliquaryId] = reliquary
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user