优化架构

This commit is contained in:
huangxiaolei
2022-11-23 18:05:11 +08:00
parent 3efed3defe
commit 43403202b5
6760 changed files with 33748 additions and 554768 deletions

View File

@@ -0,0 +1,74 @@
package config
import (
"encoding/json"
"hk4e/logger"
"io/ioutil"
"os"
"strings"
)
type AvatarConfigAbility struct {
AbilityName string `json:"abilityName"`
}
type AvatarConfig struct {
Abilities []*AvatarConfigAbility `json:"abilities"`
TargetAbilities []*AvatarConfigAbility `json:"targetAbilities"`
}
type AbilityEmbryoEntry struct {
Name string
Abilities []string
}
func (g *GameDataConfig) loadAbilityEmbryos() {
dirPath := g.binPrefix + "Avatar"
fileList, err := ioutil.ReadDir(dirPath)
if err != nil {
logger.LOG.Error("open dir error: %v", err)
return
}
embryoList := make([]*AbilityEmbryoEntry, 0)
for _, file := range fileList {
fileName := file.Name()
if !strings.Contains(fileName, "ConfigAvatar_") {
continue
}
startIndex := strings.Index(fileName, "ConfigAvatar_")
endIndex := strings.Index(fileName, ".json")
if startIndex == -1 || endIndex == -1 || startIndex+13 > endIndex {
logger.LOG.Error("file name format error: %v", fileName)
continue
}
avatarName := fileName[startIndex+13 : endIndex]
fileData, err := os.ReadFile(dirPath + "/" + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
avatarConfig := new(AvatarConfig)
err = json.Unmarshal(fileData, avatarConfig)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
if len(avatarConfig.Abilities) == 0 {
continue
}
abilityEmbryoEntry := new(AbilityEmbryoEntry)
abilityEmbryoEntry.Name = avatarName
for _, v := range avatarConfig.Abilities {
abilityEmbryoEntry.Abilities = append(abilityEmbryoEntry.Abilities, v.AbilityName)
}
embryoList = append(embryoList, abilityEmbryoEntry)
}
if len(embryoList) == 0 {
logger.LOG.Error("no embryo load")
}
g.AbilityEmbryos = make(map[string]*AbilityEmbryoEntry)
for _, v := range embryoList {
g.AbilityEmbryos[v.Name] = v
}
logger.LOG.Info("load %v AbilityEmbryos", len(g.AbilityEmbryos))
}

102
gs/config/avatar_data.go Normal file
View File

@@ -0,0 +1,102 @@
package config
import (
"encoding/json"
"hk4e/common/utils/endec"
"hk4e/logger"
"os"
"strings"
)
type AvatarData struct {
IconName string `json:"iconName"`
BodyType string `json:"bodyType"`
QualityType string `json:"qualityType"`
ChargeEfficiency int32 `json:"chargeEfficiency"`
InitialWeapon int32 `json:"initialWeapon"`
WeaponType string `json:"weaponType"`
ImageName string `json:"imageName"`
AvatarPromoteId int32 `json:"avatarPromoteId"`
CutsceneShow string `json:"cutsceneShow"`
SkillDepotId int32 `json:"skillDepotId"`
StaminaRecoverSpeed int32 `json:"staminaRecoverSpeed"`
CandSkillDepotIds []int32 `json:"candSkillDepotIds"`
AvatarIdentityType string `json:"avatarIdentityType"`
AvatarPromoteRewardLevelList []int32 `json:"avatarPromoteRewardLevelList"`
AvatarPromoteRewardIdList []int32 `json:"avatarPromoteRewardIdList"`
NameTextMapHash int64 `json:"nameTextMapHash"`
HpBase float64 `json:"hpBase"`
AttackBase float64 `json:"attackBase"`
DefenseBase float64 `json:"defenseBase"`
Critical float64 `json:"critical"`
CriticalHurt float64 `json:"criticalHurt"`
PropGrowCurves []*PropGrowCurve `json:"propGrowCurves"`
Id int32 `json:"id"`
// 计算数据
Name string `json:"-"`
Abilities []int32 `json:"-"`
}
func (g *GameDataConfig) loadAvatarData() {
g.AvatarDataMap = make(map[int32]*AvatarData)
fileNameList := []string{"AvatarExcelConfigData.json"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.excelBinPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
avatarData := new(AvatarData)
err = json.Unmarshal(i, avatarData)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
g.AvatarDataMap[avatarData.Id] = avatarData
}
}
logger.LOG.Info("load %v AvatarData", len(g.AvatarDataMap))
for _, v := range g.AvatarDataMap {
split := strings.Split(v.IconName, "_")
if len(split) > 0 {
v.Name = split[len(split)-1]
info := g.AbilityEmbryos[v.Name]
if info != nil {
v.Abilities = make([]int32, 0)
for _, ability := range info.Abilities {
v.Abilities = append(v.Abilities, endec.Hk4eAbilityHashCode(ability))
}
}
}
}
}
// TODO 成长属性要读表
func (a *AvatarData) GetBaseHpByLevel(level uint8) float64 {
return a.HpBase * float64(level)
}
func (a *AvatarData) GetBaseAttackByLevel(level uint8) float64 {
return a.AttackBase * float64(level)
}
func (a *AvatarData) GetBaseDefenseByLevel(level uint8) float64 {
return a.DefenseBase * float64(level)
}

View File

@@ -0,0 +1,65 @@
package config
import (
"encoding/json"
"hk4e/gs/constant"
"hk4e/logger"
"os"
)
type AvatarSkillData struct {
Id int32 `json:"id"`
CdTime float64 `json:"cdTime"`
CostElemVal int32 `json:"costElemVal"`
MaxChargeNum int32 `json:"maxChargeNum"`
TriggerID int32 `json:"triggerID"`
IsAttackCameraLock bool `json:"isAttackCameraLock"`
ProudSkillGroupId int32 `json:"proudSkillGroupId"`
CostElemType string `json:"costElemType"`
LockWeightParams []float64 `json:"lockWeightParams"`
NameTextMapHash int64 `json:"nameTextMapHash"`
AbilityName string `json:"abilityName"`
LockShape string `json:"lockShape"`
GlobalValueKey string `json:"globalValueKey"`
// 计算属性
CostElemTypeX *constant.ElementTypeValue `json:"-"`
}
func (g *GameDataConfig) loadAvatarSkillData() {
g.AvatarSkillDataMap = make(map[int32]*AvatarSkillData)
fileNameList := []string{"AvatarSkillExcelConfigData.json"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.excelBinPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
avatarSkillData := new(AvatarSkillData)
err = json.Unmarshal(i, avatarSkillData)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
g.AvatarSkillDataMap[avatarSkillData.Id] = avatarSkillData
}
}
logger.LOG.Info("load %v AvatarSkillData", len(g.AvatarSkillDataMap))
for _, v := range g.AvatarSkillDataMap {
v.CostElemTypeX = constant.ElementTypeConst.STRING_MAP[v.CostElemType]
}
}

View File

@@ -0,0 +1,84 @@
package config
import (
"encoding/json"
"hk4e/common/utils/endec"
"hk4e/gs/constant"
"hk4e/logger"
"os"
)
type InherentProudSkillOpens struct {
ProudSkillGroupId int32 `json:"proudSkillGroupId"`
NeedAvatarPromoteLevel int32 `json:"needAvatarPromoteLevel"`
}
type AvatarSkillDepotData struct {
Id int32 `json:"id"`
EnergySkill int32 `json:"energySkill"`
AttackModeSkill int32 `json:"attackModeSkill"`
Skills []int32 `json:"skills"`
SubSkills []int32 `json:"subSkills"`
ExtraAbilities []string `json:"extraAbilities"`
Talents []int32 `json:"talents"`
InherentProudSkillOpens []*InherentProudSkillOpens `json:"inherentProudSkillOpens"`
TalentStarName string `json:"talentStarName"`
SkillDepotAbilityGroup string `json:"skillDepotAbilityGroup"`
// 计算属性
EnergySkillData *AvatarSkillData `json:"-"`
ElementType *constant.ElementTypeValue `json:"-"`
Abilities []int32 `json:"-"`
}
func (g *GameDataConfig) loadAvatarSkillDepotData() {
g.AvatarSkillDepotDataMap = make(map[int32]*AvatarSkillDepotData)
fileNameList := []string{"AvatarSkillDepotExcelConfigData.json"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.excelBinPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
avatarSkillDepotData := new(AvatarSkillDepotData)
err = json.Unmarshal(i, avatarSkillDepotData)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
g.AvatarSkillDepotDataMap[avatarSkillDepotData.Id] = avatarSkillDepotData
}
}
logger.LOG.Info("load %v AvatarSkillDepotData", len(g.AvatarSkillDepotDataMap))
for _, v := range g.AvatarSkillDepotDataMap {
// set energy skill data
v.EnergySkillData = g.AvatarSkillDataMap[v.EnergySkill]
if v.EnergySkillData != nil {
v.ElementType = v.EnergySkillData.CostElemTypeX
} else {
v.ElementType = constant.ElementTypeConst.None
}
// set embryo abilities if player skill depot
if v.SkillDepotAbilityGroup != "" {
config := g.GameDepot.PlayerAbilities[v.SkillDepotAbilityGroup]
if config != nil {
for _, targetAbility := range config.TargetAbilities {
v.Abilities = append(v.Abilities, endec.Hk4eAbilityHashCode(targetAbility.AbilityName))
}
}
}
}
}

View File

@@ -0,0 +1,59 @@
package config
import (
"github.com/jszwec/csvutil"
"hk4e/logger"
"os"
"strings"
)
type Drop struct {
DropId int32 `csv:"DropId"`
Weight int32 `csv:"Weight"`
Result int32 `csv:"Result"`
IsEnd bool `csv:"IsEnd"`
}
type DropGroupData struct {
DropId int32
WeightAll int32
DropConfig []*Drop
}
func (g *GameDataConfig) loadDropGroupData() {
g.DropGroupDataMap = make(map[int32]*DropGroupData)
fileNameList := []string{"DropGachaAvatarUp.csv", "DropGachaWeaponUp.csv", "DropGachaNormal.csv"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.csvPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
return
}
// 去除第二三行的内容变成标准格式的csv
index1 := strings.Index(string(fileData), "\n")
index2 := strings.Index(string(fileData[(index1+1):]), "\n")
index3 := strings.Index(string(fileData[(index2+1)+(index1+1):]), "\n")
standardCsvData := make([]byte, 0)
standardCsvData = append(standardCsvData, fileData[:index1]...)
standardCsvData = append(standardCsvData, fileData[index3+(index2+1)+(index1+1):]...)
var dropList []*Drop
err = csvutil.Unmarshal(standardCsvData, &dropList)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
return
}
for _, drop := range dropList {
dropGroupData, exist := g.DropGroupDataMap[drop.DropId]
if !exist {
dropGroupData = new(DropGroupData)
dropGroupData.DropId = drop.DropId
dropGroupData.WeightAll = 0
dropGroupData.DropConfig = make([]*Drop, 0)
g.DropGroupDataMap[drop.DropId] = dropGroupData
}
dropGroupData.WeightAll += drop.Weight
dropGroupData.DropConfig = append(dropGroupData.DropConfig, drop)
}
}
logger.LOG.Info("load %v DropGroupData", len(g.DropGroupDataMap))
}

54
gs/config/fetter_data.go Normal file
View File

@@ -0,0 +1,54 @@
package config
import (
"encoding/json"
"hk4e/logger"
"os"
)
type FetterData struct {
AvatarId int32 `json:"avatarId"`
FetterId int32 `json:"fetterId"`
}
func (g *GameDataConfig) loadFetterData() {
g.FetterDataMap = make(map[int32]*FetterData)
fileNameList := []string{"FetterInfoExcelConfigData.json", "FettersExcelConfigData.json", "FetterStoryExcelConfigData.json", "PhotographExpressionExcelConfigData.json", "PhotographPosenameExcelConfigData.json"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.excelBinPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
fetterData := new(FetterData)
err = json.Unmarshal(i, fetterData)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
g.FetterDataMap[fetterData.FetterId] = fetterData
}
}
logger.LOG.Info("load %v FetterData", len(g.FetterDataMap))
g.AvatarFetterDataMap = make(map[int32][]int32)
for _, v := range g.FetterDataMap {
avatarFetterIdList, exist := g.AvatarFetterDataMap[v.AvatarId]
if !exist {
avatarFetterIdList = make([]int32, 0)
}
avatarFetterIdList = append(avatarFetterIdList, v.FetterId)
g.AvatarFetterDataMap[v.AvatarId] = avatarFetterIdList
}
}

60
gs/config/gadget_data.go Normal file
View File

@@ -0,0 +1,60 @@
package config
import (
"encoding/json"
"hk4e/gs/constant"
"hk4e/logger"
"os"
)
type GadgetData struct {
Id int32 `json:"id"`
Type string `json:"type"`
JsonName string `json:"jsonName"`
IsInteractive bool `json:"isInteractive"`
Tags []string `json:"tags"`
ItemJsonName string `json:"itemJsonName"`
InteeIconName string `json:"inteeIconName"`
NameTextMapHash int64 `json:"nameTextMapHash"`
CampID int32 `json:"campID"`
LODPatternName string `json:"LODPatternName"`
// 计算属性
TypeX uint16 `json:"-"`
}
func (g *GameDataConfig) loadGadgetData() {
g.GadgetDataMap = make(map[int32]*GadgetData)
fileNameList := []string{"GadgetExcelConfigData.json"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.excelBinPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
gadgetData := new(GadgetData)
err = json.Unmarshal(i, gadgetData)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
g.GadgetDataMap[gadgetData.Id] = gadgetData
}
}
logger.LOG.Info("load %v GadgetData", len(g.GadgetDataMap))
for _, v := range g.GadgetDataMap {
v.TypeX = constant.EntityTypeConst.STRING_MAP[v.Type]
}
}

View File

@@ -0,0 +1,149 @@
package config
import (
appConfig "hk4e/common/config"
"hk4e/logger"
"io/ioutil"
"os"
)
var CONF *GameDataConfig = nil
type GameDataConfig struct {
binPrefix string
excelBinPrefix string
csvPrefix string
GameDepot *GameDepot
// 配置表
// BinOutput
// 技能列表
AbilityEmbryos map[string]*AbilityEmbryoEntry
OpenConfigEntries map[string]*OpenConfigEntry
// ExcelBinOutput
FetterDataMap map[int32]*FetterData
AvatarFetterDataMap map[int32][]int32
// 资源
// 场景传送点
ScenePointEntries map[string]*ScenePointEntry
ScenePointIdList []int32
// 角色
AvatarDataMap map[int32]*AvatarData
// 道具
ItemDataMap map[int32]*ItemData
// 角色技能
AvatarSkillDataMap map[int32]*AvatarSkillData
AvatarSkillDepotDataMap map[int32]*AvatarSkillDepotData
// 掉落组配置表
DropGroupDataMap map[int32]*DropGroupData
// GG
GadgetDataMap map[int32]*GadgetData
// 采集物
GatherDataMap map[int32]*GatherData
}
func InitGameDataConfig() {
CONF = new(GameDataConfig)
CONF.binPrefix = ""
CONF.excelBinPrefix = ""
CONF.csvPrefix = ""
CONF.loadAll()
}
func (g *GameDataConfig) load() {
g.loadGameDepot()
// 技能列表
g.loadAbilityEmbryos()
g.loadOpenConfig()
// 资源
g.loadFetterData()
// 场景传送点
g.loadScenePoints()
// 角色
g.loadAvatarData()
// 道具
g.loadItemData()
// 角色技能
g.loadAvatarSkillData()
g.loadAvatarSkillDepotData()
// 掉落组配置表
g.loadDropGroupData()
// GG
g.loadGadgetData()
// 采集物
g.loadGatherData()
}
func (g *GameDataConfig) getResourcePathPrefix() string {
resourcePath := appConfig.CONF.Hk4e.ResourcePath
return resourcePath
}
func (g *GameDataConfig) loadAll() {
resourcePath := g.getResourcePathPrefix()
dirInfo, err := os.Stat(resourcePath)
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data config dir error: %v", err)
return
}
g.binPrefix = resourcePath + "/BinOutput"
g.excelBinPrefix = resourcePath + "/ExcelBinOutput"
g.csvPrefix = resourcePath + "/Csv"
dirInfo, err = os.Stat(g.binPrefix)
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data bin output config dir error: %v", err)
return
}
dirInfo, err = os.Stat(g.excelBinPrefix)
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data excel bin output config dir error: %v", err)
return
}
dirInfo, err = os.Stat(g.csvPrefix)
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data csv config dir error: %v", err)
return
}
g.binPrefix += "/"
g.excelBinPrefix += "/"
g.csvPrefix += "/"
g.load()
}
func (g *GameDataConfig) ReadWorldTerrain() []byte {
resourcePath := g.getResourcePathPrefix()
dirInfo, err := os.Stat(resourcePath)
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data config dir error: %v", err)
return nil
}
dirInfo, err = os.Stat(resourcePath + "/WorldStatic")
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data world static dir error: %v", err)
return nil
}
data, err := os.ReadFile(resourcePath + "/WorldStatic/world_terrain.bin")
if err != nil {
logger.LOG.Error("read world terrain file error: %v", err)
return nil
}
return data
}
func (g *GameDataConfig) WriteWorldTerrain(data []byte) {
resourcePath := g.getResourcePathPrefix()
dirInfo, err := os.Stat(resourcePath)
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data config dir error: %v", err)
return
}
dirInfo, err = os.Stat(resourcePath + "/WorldStatic")
if err != nil || !dirInfo.IsDir() {
logger.LOG.Error("open game data world static dir error: %v", err)
return
}
err = ioutil.WriteFile(resourcePath+"/WorldStatic/world_terrain.bin", data, 0644)
if err != nil {
logger.LOG.Error("write world terrain file error: %v", err)
return
}
}

29
gs/config/game_depot.go Normal file
View File

@@ -0,0 +1,29 @@
package config
import (
"encoding/json"
"hk4e/logger"
"os"
)
type GameDepot struct {
PlayerAbilities map[string]*AvatarConfig
}
func (g *GameDataConfig) loadGameDepot() {
g.GameDepot = new(GameDepot)
playerElementsFilePath := g.binPrefix + "AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json"
playerElementsFile, err := os.ReadFile(playerElementsFilePath)
if err != nil {
logger.LOG.Error("open file error: %v", err)
return
}
playerAbilities := make(map[string]*AvatarConfig)
err = json.Unmarshal(playerElementsFile, &playerAbilities)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
return
}
g.GameDepot.PlayerAbilities = playerAbilities
logger.LOG.Info("load %v PlayerAbilities", len(g.GameDepot.PlayerAbilities))
}

50
gs/config/gather_data.go Normal file
View File

@@ -0,0 +1,50 @@
package config
import (
"encoding/json"
"hk4e/logger"
"os"
)
type GatherData struct {
Id int32 `json:"id"`
PointType int32 `json:"pointType"`
GadgetId int32 `json:"gadgetId"`
ItemId int32 `json:"itemId"`
Cd int32 `json:"cd"`
IsForbidGuest bool `json:"isForbidGuest"`
InitDisableInteract bool `json:"initDisableInteract"`
}
func (g *GameDataConfig) loadGatherData() {
g.GatherDataMap = make(map[int32]*GatherData)
fileNameList := []string{"GatherExcelConfigData.json"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.excelBinPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
gatherData := new(GatherData)
err = json.Unmarshal(i, gatherData)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
g.GatherDataMap[gatherData.Id] = gatherData
}
}
logger.LOG.Info("load %v GatherData", len(g.GatherDataMap))
}

161
gs/config/item_data.go Normal file
View File

@@ -0,0 +1,161 @@
package config
import (
"encoding/json"
"hk4e/gs/constant"
"hk4e/logger"
"os"
)
type ItemUseData struct {
UseOp string `json:"useOp"`
UseParam []string `json:"useParam"`
}
type WeaponProperty struct {
PropType string `json:"propType"`
InitValue float64 `json:"initValue"`
Type string `json:"type"`
FightProp uint16 `json:"-"`
}
type ItemData struct {
Id int32 `json:"id"`
StackLimit int32 `json:"stackLimit"`
MaxUseCount int32 `json:"maxUseCount"`
RankLevel int32 `json:"rankLevel"`
EffectName string `json:"effectName"`
SatiationParams []int32 `json:"satiationParams"`
Rank int32 `json:"rank"`
Weight int32 `json:"weight"`
GadgetId int32 `json:"gadgetId"`
DestroyReturnMaterial []int32 `json:"destroyReturnMaterial"`
DestroyReturnMaterialCount []int32 `json:"destroyReturnMaterialCount"`
ItemUse []*ItemUseData `json:"itemUse"`
// food
FoodQuality string `json:"foodQuality"`
UseTarget string `json:"useTarget"`
IseParam []string `json:"iseParam"`
// string enums
ItemType string `json:"itemType"`
MaterialType string `json:"materialType"`
EquipType string `json:"equipType"`
EffectType string `json:"effectType"`
DestroyRule string `json:"destroyRule"`
// post load enum forms of above
MaterialEnumType uint16 `json:"-"`
ItemEnumType uint16 `json:"-"`
EquipEnumType uint16 `json:"-"`
// relic
MainPropDepotId int32 `json:"mainPropDepotId"`
AppendPropDepotId int32 `json:"appendPropDepotId"`
AppendPropNum int32 `json:"appendPropNum"`
SetId int32 `json:"setId"`
AddPropLevels []int32 `json:"addPropLevels"`
BaseConvExp int32 `json:"baseConvExp"`
MaxLevel int32 `json:"maxLevel"`
// weapon
WeaponPromoteId int32 `json:"weaponPromoteId"`
WeaponBaseExp int32 `json:"weaponBaseExp"`
StoryId int32 `json:"storyId"`
AvatarPromoteId int32 `json:"avatarPromoteId"`
AwakenMaterial int32 `json:"awakenMaterial"`
AwakenCosts []int32 `json:"awakenCosts"`
SkillAffix []int32 `json:"skillAffix"`
WeaponProp []*WeaponProperty `json:"weaponProp"`
// hash
Icon string `json:"icon"`
NameTextMapHash int64 `json:"nameTextMapHash"`
AddPropLevelSet map[int32]bool `json:"-"`
// furniture
Comfort int32 `json:"comfort"`
FurnType []int32 `json:"furnType"`
FurnitureGadgetID []int32 `json:"furnitureGadgetID"`
RoomSceneId int32 `json:"roomSceneId"`
}
func (g *GameDataConfig) loadItemData() {
g.ItemDataMap = make(map[int32]*ItemData)
fileNameList := []string{"MaterialExcelConfigData.json", "WeaponExcelConfigData.json", "ReliquaryExcelConfigData.json", "HomeWorldFurnitureExcelConfigData.json"}
for _, fileName := range fileNameList {
fileData, err := os.ReadFile(g.excelBinPrefix + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
itemData := new(ItemData)
err = json.Unmarshal(i, itemData)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
g.ItemDataMap[itemData.Id] = itemData
}
}
logger.LOG.Info("load %v ItemData", len(g.ItemDataMap))
for _, itemData := range g.ItemDataMap {
itemData.ItemEnumType = constant.ItemTypeConst.STRING_MAP[itemData.ItemType]
itemData.MaterialEnumType = constant.MaterialTypeConst.STRING_MAP[itemData.MaterialType]
if itemData.ItemEnumType == constant.ItemTypeConst.ITEM_RELIQUARY {
itemData.EquipEnumType = constant.EquipTypeConst.STRING_MAP[itemData.EquipType]
if itemData.AddPropLevels != nil || len(itemData.AddPropLevels) > 0 {
itemData.AddPropLevelSet = make(map[int32]bool)
for _, v := range itemData.AddPropLevels {
itemData.AddPropLevelSet[v] = true
}
}
} else if itemData.ItemEnumType == constant.ItemTypeConst.ITEM_WEAPON {
itemData.EquipEnumType = constant.EquipTypeConst.EQUIP_WEAPON
} else {
itemData.EquipEnumType = constant.EquipTypeConst.EQUIP_NONE
}
if itemData.WeaponProp != nil {
for i, v := range itemData.WeaponProp {
v.FightProp = constant.FightPropertyConst.STRING_MAP[v.PropType]
itemData.WeaponProp[i] = v
}
}
if itemData.FurnType != nil {
furnType := make([]int32, 0)
for _, v := range itemData.FurnType {
if v > 0 {
furnType = append(furnType, v)
}
}
itemData.FurnType = furnType
}
if itemData.FurnitureGadgetID != nil {
furnitureGadgetID := make([]int32, 0)
for _, v := range itemData.FurnitureGadgetID {
if v > 0 {
furnitureGadgetID = append(furnitureGadgetID, v)
}
}
itemData.FurnitureGadgetID = furnitureGadgetID
}
}
}

View File

@@ -0,0 +1,93 @@
package config
import (
"encoding/json"
"hk4e/logger"
"io/ioutil"
"os"
"strings"
)
type SkillPointModifier struct {
SkillId int32
Delta int32
}
type OpenConfigEntry struct {
Name string
AddAbilities []string
ExtraTalentIndex int32
SkillPointModifiers []*SkillPointModifier
}
func NewOpenConfigEntry(name string, data []*OpenConfigData) (r *OpenConfigEntry) {
r = new(OpenConfigEntry)
r.Name = name
abilityList := make([]string, 0)
modList := make([]*SkillPointModifier, 0)
for _, v := range data {
if strings.Contains(v.DollarType, "AddAbility") {
abilityList = append(abilityList, v.AbilityName)
} else if v.TalentIndex > 0 {
r.ExtraTalentIndex = v.TalentIndex
} else if strings.Contains(v.DollarType, "ModifySkillPoint") {
modList = append(modList, &SkillPointModifier{
SkillId: v.SkillID,
Delta: v.PointDelta,
})
}
}
r.AddAbilities = abilityList
r.SkillPointModifiers = modList
return r
}
type OpenConfigData struct {
DollarType string `json:"$type"`
AbilityName string `json:"abilityName"`
TalentIndex int32 `json:"talentIndex"`
SkillID int32 `json:"skillID"`
PointDelta int32 `json:"pointDelta"`
}
func (g *GameDataConfig) loadOpenConfig() {
list := make([]*OpenConfigEntry, 0)
folderNames := []string{"Talent/EquipTalents", "Talent/AvatarTalents"}
for _, v := range folderNames {
dirPath := g.binPrefix + v
fileList, err := ioutil.ReadDir(dirPath)
if err != nil {
logger.LOG.Error("open dir error: %v", err)
return
}
for _, file := range fileList {
fileName := file.Name()
if !strings.Contains(fileName, ".json") {
continue
}
config := make(map[string][]*OpenConfigData)
fileData, err := os.ReadFile(dirPath + "/" + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
err = json.Unmarshal(fileData, &config)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
for kk, vv := range config {
entry := NewOpenConfigEntry(kk, vv)
list = append(list, entry)
}
}
}
if len(list) == 0 {
logger.LOG.Error("no open config entries load")
}
g.OpenConfigEntries = make(map[string]*OpenConfigEntry)
for _, v := range list {
g.OpenConfigEntries[v.Name] = v
}
logger.LOG.Info("load %v OpenConfig", len(g.OpenConfigEntries))
}

View File

@@ -0,0 +1,6 @@
package config
type PropGrowCurve struct {
Type string `json:"type"`
GrowCurve string `json:"growCurve"`
}

86
gs/config/scene_points.go Normal file
View File

@@ -0,0 +1,86 @@
package config
import (
"encoding/json"
"hk4e/logger"
"io/ioutil"
"os"
"strconv"
"strings"
)
type ScenePointEntry struct {
Name string
PointData *PointData
}
type ScenePointConfig struct {
Points map[string]*PointData `json:"points"`
}
type PointData struct {
Id int32 `json:"-"`
DollarType string `json:"$type"`
TranPos *Position `json:"tranPos"`
DungeonIds []int32 `json:"dungeonIds"`
DungeonRandomList []int32 `json:"dungeonRandomList"`
TranSceneId int32 `json:"tranSceneId"`
}
type Position struct {
X float64 `json:"x"`
Y float64 `json:"y"`
Z float64 `json:"z"`
}
func (g *GameDataConfig) loadScenePoints() {
g.ScenePointEntries = make(map[string]*ScenePointEntry)
g.ScenePointIdList = make([]int32, 0)
dirPath := g.binPrefix + "Scene/Point"
fileList, err := ioutil.ReadDir(dirPath)
if err != nil {
logger.LOG.Error("open dir error: %v", err)
return
}
for _, file := range fileList {
fileName := file.Name()
if !strings.Contains(fileName, "scene") {
continue
}
startIndex := strings.Index(fileName, "scene")
endIndex := strings.Index(fileName, "_point.json")
if startIndex == -1 || endIndex == -1 || startIndex+5 > endIndex {
logger.LOG.Error("file name format error: %v", fileName)
continue
}
sceneId := fileName[startIndex+5 : endIndex]
fileData, err := os.ReadFile(dirPath + "/" + fileName)
if err != nil {
logger.LOG.Error("open file error: %v", err)
continue
}
scenePointConfig := new(ScenePointConfig)
err = json.Unmarshal(fileData, scenePointConfig)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
if len(scenePointConfig.Points) == 0 {
continue
}
for k, v := range scenePointConfig.Points {
sceneIdInt32, err := strconv.ParseInt(k, 10, 32)
if err != nil {
logger.LOG.Error("parse file error: %v", err)
continue
}
v.Id = int32(sceneIdInt32)
scenePointEntry := new(ScenePointEntry)
scenePointEntry.Name = sceneId + "_" + k
scenePointEntry.PointData = v
g.ScenePointIdList = append(g.ScenePointIdList, int32(sceneIdInt32))
g.ScenePointEntries[scenePointEntry.Name] = scenePointEntry
}
}
logger.LOG.Info("load %v ScenePointEntries", len(g.ScenePointEntries))
}