迁移配置表

This commit is contained in:
flswld
2023-01-18 15:38:50 +08:00
parent 62ae866b1e
commit a00bee14d0
882 changed files with 1639 additions and 324485 deletions

View File

@@ -13,7 +13,6 @@ import (
"hk4e/common/mq"
"hk4e/common/rpc"
"hk4e/gdconf"
gdc "hk4e/gs/config"
"hk4e/gs/dao"
"hk4e/gs/game"
"hk4e/gs/service"
@@ -72,8 +71,6 @@ func Run(ctx context.Context, configFile string) error {
logger.Warn("gs start, appid: %v, gsid: %v", APPID, GSID)
constant.InitConstant()
gdc.InitGameDataConfig()
gdconf.InitGameDataConfig()
db, err := dao.NewDao()

View File

@@ -1,74 +0,0 @@
package config
import (
"encoding/json"
"os"
"strings"
"hk4e/pkg/logger"
)
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 := os.ReadDir(dirPath)
if err != nil {
logger.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.Error("file name format error: %v", fileName)
continue
}
avatarName := fileName[startIndex+13 : endIndex]
fileData, err := os.ReadFile(dirPath + "/" + fileName)
if err != nil {
logger.Error("open file error: %v", err)
continue
}
avatarConfig := new(AvatarConfig)
err = json.Unmarshal(fileData, avatarConfig)
if err != nil {
logger.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.Error("no embryo load")
}
g.AbilityEmbryos = make(map[string]*AbilityEmbryoEntry)
for _, v := range embryoList {
g.AbilityEmbryos[v.Name] = v
}
logger.Info("load %v AbilityEmbryos", len(g.AbilityEmbryos))
}

View File

@@ -1,103 +0,0 @@
package config
import (
"encoding/json"
"os"
"strings"
"hk4e/pkg/endec"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
avatarData := new(AvatarData)
err = json.Unmarshal(i, avatarData)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
g.AvatarDataMap[avatarData.Id] = avatarData
}
}
logger.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

@@ -1,66 +0,0 @@
package config
import (
"encoding/json"
"os"
"hk4e/common/constant"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
avatarSkillData := new(AvatarSkillData)
err = json.Unmarshal(i, avatarSkillData)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
g.AvatarSkillDataMap[avatarSkillData.Id] = avatarSkillData
}
}
logger.Info("load %v AvatarSkillData", len(g.AvatarSkillDataMap))
for _, v := range g.AvatarSkillDataMap {
v.CostElemTypeX = constant.ElementTypeConst.STRING_MAP[v.CostElemType]
}
}

View File

@@ -1,85 +0,0 @@
package config
import (
"encoding/json"
"os"
"hk4e/common/constant"
"hk4e/pkg/endec"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
avatarSkillDepotData := new(AvatarSkillDepotData)
err = json.Unmarshal(i, avatarSkillDepotData)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
g.AvatarSkillDepotDataMap[avatarSkillDepotData.Id] = avatarSkillDepotData
}
}
logger.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

@@ -1,55 +0,0 @@
package config
import (
"encoding/json"
"os"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
fetterData := new(FetterData)
err = json.Unmarshal(i, fetterData)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
g.FetterDataMap[fetterData.FetterId] = fetterData
}
}
logger.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
}
}

View File

@@ -1,61 +0,0 @@
package config
import (
"encoding/json"
"os"
"hk4e/common/constant"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
gadgetData := new(GadgetData)
err = json.Unmarshal(i, gadgetData)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
g.GadgetDataMap[gadgetData.Id] = gadgetData
}
}
logger.Info("load %v GadgetData", len(g.GadgetDataMap))
for _, v := range g.GadgetDataMap {
v.TypeX = constant.EntityTypeConst.STRING_MAP[v.Type]
}
}

View File

@@ -1,97 +0,0 @@
package config
import (
"os"
appConfig "hk4e/common/config"
"hk4e/pkg/logger"
)
var CONF *GameDataConfig = nil
type GameDataConfig struct {
binPrefix string
excelBinPrefix 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
// GG
GadgetDataMap map[int32]*GadgetData
// 采集物
GatherDataMap map[int32]*GatherData
}
func InitGameDataConfig() {
CONF = new(GameDataConfig)
CONF.binPrefix = ""
CONF.excelBinPrefix = ""
CONF.loadAll()
}
func (g *GameDataConfig) load() {
g.loadGameDepot()
// 技能列表
g.loadAbilityEmbryos()
g.loadOpenConfig()
// 资源
g.loadFetterData()
// 场景传送点
g.loadScenePoints()
// 角色
g.loadAvatarData()
// 道具
g.loadItemData()
// 角色技能
g.loadAvatarSkillData()
g.loadAvatarSkillDepotData()
// 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.Error("open game data config dir error: %v", err)
return
}
g.binPrefix = resourcePath + "/BinOutput"
g.excelBinPrefix = resourcePath + "/ExcelBinOutput"
dirInfo, err = os.Stat(g.binPrefix)
if err != nil || !dirInfo.IsDir() {
logger.Error("open game data bin output config dir error: %v", err)
return
}
dirInfo, err = os.Stat(g.excelBinPrefix)
if err != nil || !dirInfo.IsDir() {
logger.Error("open game data excel bin output config dir error: %v", err)
return
}
g.binPrefix += "/"
g.excelBinPrefix += "/"
g.load()
}

View File

@@ -1,30 +0,0 @@
package config
import (
"encoding/json"
"os"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
return
}
playerAbilities := make(map[string]*AvatarConfig)
err = json.Unmarshal(playerElementsFile, &playerAbilities)
if err != nil {
logger.Error("parse file error: %v", err)
return
}
g.GameDepot.PlayerAbilities = playerAbilities
logger.Info("load %v PlayerAbilities", len(g.GameDepot.PlayerAbilities))
}

View File

@@ -1,51 +0,0 @@
package config
import (
"encoding/json"
"os"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
gatherData := new(GatherData)
err = json.Unmarshal(i, gatherData)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
g.GatherDataMap[gatherData.Id] = gatherData
}
}
logger.Info("load %v GatherData", len(g.GatherDataMap))
}

View File

@@ -1,162 +0,0 @@
package config
import (
"encoding/json"
"os"
"hk4e/common/constant"
"hk4e/pkg/logger"
)
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.Error("open file error: %v", err)
continue
}
list := make([]map[string]any, 0)
err = json.Unmarshal(fileData, &list)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
for _, v := range list {
i, err := json.Marshal(v)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
itemData := new(ItemData)
err = json.Unmarshal(i, itemData)
if err != nil {
logger.Error("parse file error: %v", err)
continue
}
g.ItemDataMap[itemData.Id] = itemData
}
}
logger.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

@@ -1,93 +0,0 @@
package config
import (
"encoding/json"
"os"
"strings"
"hk4e/pkg/logger"
)
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 := os.ReadDir(dirPath)
if err != nil {
logger.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.Error("open file error: %v", err)
continue
}
err = json.Unmarshal(fileData, &config)
if err != nil {
logger.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.Error("no open config entries load")
}
g.OpenConfigEntries = make(map[string]*OpenConfigEntry)
for _, v := range list {
g.OpenConfigEntries[v.Name] = v
}
logger.Info("load %v OpenConfig", len(g.OpenConfigEntries))
}

View File

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

View File

@@ -1,86 +0,0 @@
package config
import (
"encoding/json"
"os"
"strconv"
"strings"
"hk4e/pkg/logger"
)
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 := os.ReadDir(dirPath)
if err != nil {
logger.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.Error("file name format error: %v", fileName)
continue
}
sceneId := fileName[startIndex+5 : endIndex]
fileData, err := os.ReadFile(dirPath + "/" + fileName)
if err != nil {
logger.Error("open file error: %v", err)
continue
}
scenePointConfig := new(ScenePointConfig)
err = json.Unmarshal(fileData, scenePointConfig)
if err != nil {
logger.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.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.Info("load %v ScenePointEntries", len(g.ScenePointEntries))
}

View File

@@ -17,7 +17,7 @@ func (c *CommandManager) GMTeleportPlayer(userId, sceneId uint32, posX, posY, po
X: posX,
Y: posY,
Z: posZ,
}, 0)
}, new(model.Vector), 0)
}
// GMAddUserItem 给予玩家物品

View File

@@ -3,6 +3,7 @@ package game
import (
"encoding/json"
"reflect"
"runtime"
"time"
appConfig "hk4e/common/config"
@@ -184,6 +185,7 @@ func (g *GameManager) gameMainLoop() {
tickCost := int64(0)
localEventCost := int64(0)
commandCost := int64(0)
runtime.LockOSThread()
for {
// 消耗CPU时间性能统计
now := time.Now().UnixNano()

View File

@@ -1,9 +1,10 @@
package game
import (
"time"
"hk4e/pkg/logger"
"hk4e/protocol/proto"
"time"
)
type GCGAi struct {

View File

@@ -1,14 +1,15 @@
package game
import (
"math/rand"
"time"
"hk4e/common/constant"
"hk4e/gdconf"
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/protocol/cmd"
"hk4e/protocol/proto"
"math/rand"
"time"
)
// ControllerType 操控者类型

View File

@@ -2,7 +2,7 @@ package game
import (
"hk4e/common/constant"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/pkg/object"
@@ -12,9 +12,9 @@ import (
pb "google.golang.org/protobuf/proto"
)
func (g *GameManager) GetAllAvatarDataConfig() map[int32]*gdc.AvatarData {
allAvatarDataConfig := make(map[int32]*gdc.AvatarData)
for avatarId, avatarData := range gdc.CONF.AvatarDataMap {
func (g *GameManager) GetAllAvatarDataConfig() map[int32]*gdconf.AvatarData {
allAvatarDataConfig := make(map[int32]*gdconf.AvatarData)
for avatarId, avatarData := range gdconf.CONF.AvatarDataMap {
if avatarId < 10000002 || avatarId >= 11000000 {
// 跳过无效角色
continue
@@ -43,7 +43,7 @@ func (g *GameManager) AddUserAvatar(userId uint32, avatarId uint32) {
player.AddAvatar(avatarId)
// 添加初始武器
avatarDataConfig, ok := gdc.CONF.AvatarDataMap[int32(avatarId)]
avatarDataConfig, ok := gdconf.CONF.AvatarDataMap[int32(avatarId)]
if !ok {
logger.Error("config is nil, itemId: %v", avatarId)
return
@@ -210,15 +210,15 @@ func (g *GameManager) PacketAvatarEquipChangeNotify(avatar *model.Avatar, weapon
}
avatarEquipChangeNotify.Weapon = &proto.SceneWeaponInfo{
EntityId: entityId,
GadgetId: uint32(gdc.CONF.ItemDataMap[int32(weapon.ItemId)].GadgetId),
GadgetId: uint32(gdconf.CONF.ItemDataMap[int32(weapon.ItemId)].GadgetId),
ItemId: weapon.ItemId,
Guid: weapon.Guid,
Level: uint32(weapon.Level),
AbilityInfo: new(proto.AbilitySyncStateInfo),
}
itemDataConfig, ok := gdc.CONF.ItemDataMap[int32(weapon.ItemId)]
itemDataConfig, ok := gdconf.CONF.ItemDataMap[int32(weapon.ItemId)]
if ok {
avatarEquipChangeNotify.EquipType = uint32(itemDataConfig.EquipEnumType)
avatarEquipChangeNotify.EquipType = uint32(itemDataConfig.EquipType)
}
return avatarEquipChangeNotify
}
@@ -227,9 +227,9 @@ func (g *GameManager) PacketAvatarEquipTakeOffNotify(avatar *model.Avatar, weapo
avatarEquipChangeNotify := &proto.AvatarEquipChangeNotify{
AvatarGuid: avatar.Guid,
}
itemDataConfig, ok := gdc.CONF.ItemDataMap[int32(weapon.ItemId)]
itemDataConfig, ok := gdconf.CONF.ItemDataMap[int32(weapon.ItemId)]
if ok {
avatarEquipChangeNotify.EquipType = uint32(itemDataConfig.EquipEnumType)
avatarEquipChangeNotify.EquipType = uint32(itemDataConfig.EquipType)
}
return avatarEquipChangeNotify
}
@@ -254,9 +254,9 @@ func (g *GameManager) UpdateUserAvatarFightProp(userId uint32, avatarId uint32)
func (g *GameManager) PacketAvatarInfo(avatar *model.Avatar) *proto.AvatarInfo {
isFocus := false
// if avatar.AvatarId == 10000005 || avatar.AvatarId == 10000007 {
// isFocus = true
// }
if avatar.AvatarId == 10000005 || avatar.AvatarId == 10000007 {
isFocus = true
}
pbAvatar := &proto.AvatarInfo{
IsFocus: isFocus,
AvatarId: avatar.AvatarId,
@@ -279,13 +279,13 @@ func (g *GameManager) PacketAvatarInfo(avatar *model.Avatar) *proto.AvatarInfo {
},
uint32(constant.PlayerPropertyConst.PROP_SATIATION_VAL): {
Type: uint32(constant.PlayerPropertyConst.PROP_SATIATION_VAL),
Val: 0,
Value: &proto.PropValue_Ival{Ival: 0},
Val: int64(avatar.Satiation),
Value: &proto.PropValue_Ival{Ival: int64(avatar.Satiation)},
},
uint32(constant.PlayerPropertyConst.PROP_SATIATION_PENALTY_TIME): {
Type: uint32(constant.PlayerPropertyConst.PROP_SATIATION_PENALTY_TIME),
Val: 0,
Value: &proto.PropValue_Ival{Ival: 0},
Val: int64(avatar.SatiationPenalty),
Value: &proto.PropValue_Ival{Ival: int64(avatar.SatiationPenalty)},
},
},
LifeState: uint32(avatar.LifeState),
@@ -293,9 +293,8 @@ func (g *GameManager) PacketAvatarInfo(avatar *model.Avatar) *proto.AvatarInfo {
FightPropMap: nil,
SkillDepotId: avatar.SkillDepotId,
FetterInfo: &proto.AvatarFetterInfo{
ExpLevel: uint32(avatar.FetterLevel),
ExpNumber: avatar.FetterExp,
// TODO 资料解锁条目
ExpLevel: uint32(avatar.FetterLevel),
ExpNumber: avatar.FetterExp,
FetterList: nil,
RewardedFetterLevelList: []uint32{10},
},
@@ -313,7 +312,7 @@ func (g *GameManager) PacketAvatarInfo(avatar *model.Avatar) *proto.AvatarInfo {
})
}
// 解锁全部资料
for _, v := range gdc.CONF.AvatarFetterDataMap[int32(avatar.AvatarId)] {
for _, v := range gdconf.CONF.FetterDataAvatarIdMap[int32(avatar.AvatarId)] {
pbAvatar.FetterInfo.FetterList = append(pbAvatar.FetterInfo.FetterList, &proto.FetterData{
FetterId: uint32(v),
FetterState: uint32(constant.FetterStateConst.FINISH),

View File

@@ -297,6 +297,9 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector,
continue
}
entityId := g.CreateConfigEntity(scene, newObjectId, newObject)
if entityId == 0 {
continue
}
addEntityIdList = append(addEntityIdList, entityId)
}
// 发送已消失格子里的实体消失通知

View File

@@ -328,14 +328,14 @@ func (g *GameManager) doGachaKlee() (bool, uint32) {
allAvatarList := make([]uint32, 0)
allAvatarDataConfig := g.GetAllAvatarDataConfig()
for k, v := range allAvatarDataConfig {
if v.QualityType == "QUALITY_ORANGE" || v.QualityType == "QUALITY_PURPLE" {
if v.QualityType == 5 || v.QualityType == 4 {
allAvatarList = append(allAvatarList, uint32(k))
}
}
allWeaponList := make([]uint32, 0)
allWeaponDataConfig := g.GetAllWeaponDataConfig()
for k, v := range allWeaponDataConfig {
if v.RankLevel == 5 {
if v.EquipLevel == 5 {
allWeaponList = append(allWeaponList, uint32(k))
}
}
@@ -476,13 +476,13 @@ func (g *GameManager) doGachaOnce(userId uint32, gachaType uint32, mustGetUpEnab
logger.Error("avatar data config not found, avatar id: %v", avatarId)
return false, 0
}
if avatarDataConfig.QualityType == "QUALITY_ORANGE" {
if avatarDataConfig.QualityType == 5 {
itemColor = Orange
logger.Debug("[orange avatar], times: %v, gachaItemId: %v", gachaPoolInfo.OrangeTimes, gachaItemId)
if gachaPoolInfo.OrangeTimes > 90 {
logger.Error("[abnormal orange avatar], times: %v, gachaItemId: %v", gachaPoolInfo.OrangeTimes, gachaItemId)
}
} else if avatarDataConfig.QualityType == "QUALITY_PURPLE" {
} else if avatarDataConfig.QualityType == 4 {
itemColor = Purple
logger.Debug("[purple avatar], times: %v, gachaItemId: %v", gachaPoolInfo.PurpleTimes, gachaItemId)
if gachaPoolInfo.PurpleTimes > 10 {
@@ -500,13 +500,13 @@ func (g *GameManager) doGachaOnce(userId uint32, gachaType uint32, mustGetUpEnab
logger.Error("weapon item data config not found, item id: %v", gachaItemId)
return false, 0
}
if weaponDataConfig.RankLevel == 5 {
if weaponDataConfig.EquipLevel == 5 {
itemColor = Orange
logger.Debug("[orange weapon], times: %v, gachaItemId: %v", gachaPoolInfo.OrangeTimes, gachaItemId)
if gachaPoolInfo.OrangeTimes > 90 {
logger.Error("[abnormal orange weapon], times: %v, gachaItemId: %v", gachaPoolInfo.OrangeTimes, gachaItemId)
}
} else if weaponDataConfig.RankLevel == 4 {
} else if weaponDataConfig.EquipLevel == 4 {
itemColor = Purple
logger.Debug("[purple weapon], times: %v, gachaItemId: %v", gachaPoolInfo.PurpleTimes, gachaItemId)
if gachaPoolInfo.PurpleTimes > 10 {

View File

@@ -58,7 +58,7 @@ func (g *GameManager) GCGStartChallenge(player *model.Player) {
GAME_MANAGER.SendMsg(cmd.GCGGameBriefDataNotify, player.PlayerID, player.ClientSeq, g.PacketGCGGameBriefDataNotify(player, proto.GCGGameBusinessType_GCG_GAME_BUSINESS_TYPE_GUIDE_GROUP, game))
// 玩家进入GCG界面
g.TeleportPlayer(player, constant.EnterReasonConst.DungeonEnter, 79999, new(model.Vector), 2162)
g.TeleportPlayer(player, constant.EnterReasonConst.DungeonEnter, 79999, new(model.Vector), new(model.Vector), 2162)
}
// GCGAskDuelReq GCG决斗请求

View File

@@ -2,7 +2,7 @@ package game
import (
"hk4e/common/constant"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/pkg/logger"
"hk4e/protocol/cmd"
"hk4e/protocol/proto"
@@ -13,14 +13,14 @@ type UserItem struct {
ChangeCount uint32
}
func (g *GameManager) GetAllItemDataConfig() map[int32]*gdc.ItemData {
allItemDataConfig := make(map[int32]*gdc.ItemData)
for itemId, itemData := range gdc.CONF.ItemDataMap {
if itemData.ItemEnumType == constant.ItemTypeConst.ITEM_WEAPON {
func (g *GameManager) GetAllItemDataConfig() map[int32]*gdconf.ItemData {
allItemDataConfig := make(map[int32]*gdconf.ItemData)
for itemId, itemData := range gdconf.CONF.ItemDataMap {
if uint16(itemData.Type) == constant.ItemTypeConst.ITEM_WEAPON {
// 排除武器
continue
}
if itemData.ItemEnumType == constant.ItemTypeConst.ITEM_RELIQUARY {
if uint16(itemData.Type) == constant.ItemTypeConst.ITEM_RELIQUARY {
// 排除圣遗物
continue
}

View File

@@ -5,7 +5,7 @@ import (
"hk4e/common/constant"
"hk4e/common/mq"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/pkg/reflection"
@@ -193,7 +193,7 @@ func (g *GameManager) PacketPlayerStoreNotify(player *model.Player) *proto.Playe
StoreType: proto.StoreType_STORE_TYPE_PACK,
WeightLimit: 30000,
}
itemDataMapConfig := gdc.CONF.ItemDataMap
itemDataMapConfig := gdconf.CONF.ItemDataMap
for _, weapon := range player.WeaponMap {
pbItem := &proto.Item{
ItemId: weapon.ItemId,
@@ -205,7 +205,7 @@ func (g *GameManager) PacketPlayerStoreNotify(player *model.Player) *proto.Playe
logger.Error("config is nil, itemId: %v", weapon.ItemId)
return nil
}
if itemData.ItemEnumType != constant.ItemTypeConst.ITEM_WEAPON {
if uint16(itemData.Type) != constant.ItemTypeConst.ITEM_WEAPON {
continue
}
affixMap := make(map[uint32]uint32)
@@ -233,19 +233,18 @@ func (g *GameManager) PacketPlayerStoreNotify(player *model.Player) *proto.Playe
Guid: reliquary.Guid,
Detail: nil,
}
if itemDataMapConfig[int32(reliquary.ItemId)].ItemEnumType != constant.ItemTypeConst.ITEM_RELIQUARY {
if uint16(itemDataMapConfig[int32(reliquary.ItemId)].Type) != constant.ItemTypeConst.ITEM_RELIQUARY {
continue
}
pbItem.Detail = &proto.Item_Equip{
Equip: &proto.Equip{
Detail: &proto.Equip_Reliquary{
Reliquary: &proto.Reliquary{
Level: uint32(reliquary.Level),
Exp: reliquary.Exp,
PromoteLevel: uint32(reliquary.Promote),
MainPropId: reliquary.MainPropId,
// TODO 圣遗物副词条
AppendPropIdList: nil,
Level: uint32(reliquary.Level),
Exp: reliquary.Exp,
PromoteLevel: uint32(reliquary.Promote),
MainPropId: reliquary.MainPropId,
AppendPropIdList: reliquary.AffixIdList,
},
},
IsLocked: reliquary.Lock,
@@ -260,7 +259,7 @@ func (g *GameManager) PacketPlayerStoreNotify(player *model.Player) *proto.Playe
Detail: nil,
}
itemDataConfig := itemDataMapConfig[int32(item.ItemId)]
if itemDataConfig != nil && itemDataConfig.ItemEnumType == constant.ItemTypeConst.ITEM_FURNITURE {
if itemDataConfig != nil && uint16(itemDataConfig.Type) == constant.ItemTypeConst.ITEM_FURNITURE {
pbItem.Detail = &proto.Item_Furniture{
Furniture: &proto.Furniture{
Count: item.Count,
@@ -312,6 +311,7 @@ func (g *GameManager) PacketOpenStateUpdateNotify() *proto.OpenStateUpdateNotify
OpenStateMap: make(map[uint32]uint32),
}
openStateConstMap := reflection.ConvStructToMap(constant.OpenStateConst)
// 先暂时开放全部功能模块
for _, v := range openStateConstMap {
openStateUpdateNotify.OpenStateMap[uint32(v.(uint16))] = 1
}
@@ -340,6 +340,7 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
// 初始化所有属性
propList := reflection.ConvStructToMap(constant.PlayerPropertyConst)
for fieldName, fieldValue := range propList {
// 排除角色相关的属性
if fieldName == "PROP_EXP" ||
fieldName == "PROP_BREAK_LEVEL" ||
fieldName == "PROP_SATIATION_VAL" ||
@@ -402,7 +403,7 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
// 添加选定的主角
player.AddAvatar(mainCharAvatarId)
// 添加初始武器
avatarDataConfig, ok := gdc.CONF.AvatarDataMap[int32(mainCharAvatarId)]
avatarDataConfig, ok := gdconf.CONF.AvatarDataMap[int32(mainCharAvatarId)]
if !ok {
logger.Error("config is nil, mainCharAvatarId: %v", mainCharAvatarId)
return nil
@@ -412,6 +413,8 @@ func (g *GameManager) CreatePlayer(userId uint32, nickName string, mainCharAvata
// 角色装上初始武器
player.WearWeapon(mainCharAvatarId, weaponId)
player.AddReliquary(24825, uint64(g.snowflake.GenId()), 15007)
player.TeamConfig = model.NewTeamInfo()
player.TeamConfig.GetActiveTeam().SetAvatarIdList([]uint32{mainCharAvatarId})

View File

@@ -4,7 +4,7 @@ import (
"strconv"
"hk4e/common/constant"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/protocol/cmd"
@@ -17,8 +17,12 @@ func (g *GameManager) SceneTransToPointReq(player *model.Player, payloadMsg pb.M
logger.Debug("user get scene trans to point, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.SceneTransToPointReq)
transPointId := strconv.Itoa(int(req.SceneId)) + "_" + strconv.Itoa(int(req.PointId))
transPointConfig, exist := gdc.CONF.ScenePointEntries[transPointId]
scenePointConfig, exist := gdconf.CONF.ScenePointMap[int32(req.SceneId)]
if !exist {
g.CommonRetError(cmd.SceneTransToPointRsp, player, &proto.SceneTransToPointRsp{})
return
}
pointConfig, exist := scenePointConfig.PointMap[int32(req.PointId)]
if !exist {
g.CommonRetError(cmd.SceneTransToPointRsp, player, &proto.SceneTransToPointRsp{})
return
@@ -26,13 +30,15 @@ func (g *GameManager) SceneTransToPointReq(player *model.Player, payloadMsg pb.M
// 传送玩家
sceneId := req.SceneId
transPos := transPointConfig.PointData.TranPos
pos := &model.Vector{
X: transPos.X,
Y: transPos.Y,
Z: transPos.Z,
}
g.TeleportPlayer(player, constant.EnterReasonConst.TransPoint, sceneId, pos, 0)
g.TeleportPlayer(player, constant.EnterReasonConst.TransPoint, sceneId, &model.Vector{
X: pointConfig.TranPos.X,
Y: pointConfig.TranPos.Y,
Z: pointConfig.TranPos.Z,
}, &model.Vector{
X: pointConfig.TranRot.X,
Y: pointConfig.TranRot.Y,
Z: pointConfig.TranRot.Z,
}, 0)
sceneTransToPointRsp := &proto.SceneTransToPointRsp{
PointId: req.PointId,
@@ -54,18 +60,17 @@ func (g *GameManager) MarkMapReq(player *model.Player, payloadMsg pb.Message) {
posYInt = 300
}
// 传送玩家
pos := &model.Vector{
g.TeleportPlayer(player, constant.EnterReasonConst.Gm, req.Mark.SceneId, &model.Vector{
X: float64(req.Mark.Pos.X),
Y: float64(posYInt),
Z: float64(req.Mark.Pos.Z),
}
g.TeleportPlayer(player, constant.EnterReasonConst.Gm, req.Mark.SceneId, pos, 0)
}, new(model.Vector), 0)
}
}
}
// TeleportPlayer 传送玩家至地图上的某个位置
func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint16, sceneId uint32, pos *model.Vector, dungeonId uint32) {
func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint16, sceneId uint32, pos, rot *model.Vector, dungeonId uint32) {
// 传送玩家
newSceneId := sceneId
oldSceneId := player.SceneId
@@ -96,6 +101,9 @@ func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint16, s
player.Pos.X = pos.X
player.Pos.Y = pos.Y
player.Pos.Z = pos.Z
player.Rot.X = rot.X
player.Rot.Y = rot.Y
player.Rot.Z = rot.Z
var enterType proto.EnterType
switch enterReason {
@@ -119,21 +127,30 @@ func (g *GameManager) GetScenePointReq(player *model.Player, payloadMsg pb.Messa
logger.Debug("user get scene point, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.GetScenePointReq)
if req.SceneId != 3 {
getScenePointRsp := &proto.GetScenePointRsp{
SceneId: req.SceneId,
}
g.SendMsg(cmd.GetScenePointRsp, player.PlayerID, player.ClientSeq, getScenePointRsp)
scenePointConfig, exist := gdconf.CONF.ScenePointMap[int32(req.SceneId)]
if !exist {
return
}
getScenePointRsp := &proto.GetScenePointRsp{
SceneId: 3,
UnlockAreaList: []uint32{12, 11, 19, 28, 5, 1, 24, 10, 21, 2, 7, 18, 3, 26, 6, 17, 22, 20, 9, 14, 16, 8, 13, 4, 27, 23},
UnlockedPointList: []uint32{553, 155, 58, 257, 38, 135, 528, 329, 13, 212, 401, 3, 600, 545, 589, 180, 416, 7, 615, 206, 400, 599, 114, 12, 211, 104, 502, 93, 325, 540, 131, 320, 519, 121, 616, 218, 606, 197, 208, 703, 305, 499, 254, 652, 60, 458, 282, 691, 167, 366, 323, 32, 319, 222, 181, 380, 612, 234, 433, 391, 488, 79, 338, 139, 241, 42, 57, 256, 154, 353, 588, 491, 82, 209, 10, 500, 91, 301, 489, 4, 392, 536, 127, 337, 605, 8, 487, 78, 228, 626, 598, 1, 200, 137, 336, 535, 382, 310, 509, 100, 498, 14, 213, 625, 361, 471, 674, 475, 603, 6, 205, 485, 76, 77, 486, 359, 165, 364, 317, 271, 384, 72, 481, 253, 156, 350, 45, 244, 516, 107, 306, 296, 97, 162, 571, 495, 86, 44, 248, 646, 539, 221, 22, 318, 706, 308, 507, 103, 302, 258, 442, 33, 324, 393, 61, 255, 655, 246, 385, 73, 482, 551, 153, 363, 35, 444, 245, 439, 251, 445, 36, 235, 15, 424, 225, 214, 623, 327, 537, 128, 542, 133, 332, 322, 31, 20, 429, 432, 443, 34, 59, 468, 604, 405, 515, 316, 117, 321, 122, 249, 459, 50, 29, 438, 40, 330, 116, 326, 503, 304, 514, 105, 550, 351, 152, 586, 387, 250, 541, 328, 236, 435, 247, 48, 37, 446, 538, 339, 11, 210, 476, 379, 671, 477, 676, 242, 168, 577, 378, 383, 81, 490, 501, 92, 331, 543, 252, 87, 496, 463, 307, 484, 75, 505, 96, 534, 555, 146, 462, 365, 381, 182, 166, 575, 69, 478, 494, 85, 74, 483, 368, 465, 386, 95, 84, 493, 396, 587, 5, 602, 204, 99, 497, 298, 492, 702, 293},
LockedPointList: []uint32{173, 398, 627, 223, 417, 419, 231, 278, 699, 408, 276, 229, 520, 512, 415, 113, 274, 565, 344, 436, 394, 403, 262, 430, 195, 412, 315, 233, 440, 52, 409, 334, 193, 240, 566, 469, 187, 704, 413, 346, 259, 447, 286, 102, 345, 580, 411, 129, 578, 202, 682, 294, 570, 414, 511, 622, 428, 449, 426, 238, 265, 273, 564, 467, 563, 175, 269, 457, 574, 89, 388, 291, 707, 125, 559, 268, 656, 183, 280, 267, 357, 260, 354, 451, 410, 119, 216},
HidePointList: []uint32{458, 515, 459, 514},
GroupUnlimitPointList: []uint32{221, 131, 107, 350, 50, 424, 359},
SceneId: req.SceneId,
}
areaIdMap := make(map[uint32]bool)
for _, worldAreaData := range gdconf.CONF.WorldAreaDataMap {
if uint32(worldAreaData.SceneId) == req.SceneId {
areaIdMap[uint32(worldAreaData.AreaId1)] = true
}
}
areaList := make([]uint32, 0)
for areaId := range areaIdMap {
areaList = append(areaList, areaId)
}
getScenePointRsp.UnlockAreaList = areaList
for _, pointData := range scenePointConfig.PointMap {
if pointData.PointType == gdconf.PointTypeOther {
continue
}
getScenePointRsp.UnlockedPointList = append(getScenePointRsp.UnlockedPointList, uint32(pointData.Id))
}
g.SendMsg(cmd.GetScenePointRsp, player.PlayerID, player.ClientSeq, getScenePointRsp)
}
@@ -142,18 +159,22 @@ func (g *GameManager) GetSceneAreaReq(player *model.Player, payloadMsg pb.Messag
logger.Debug("user get scene area, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.GetSceneAreaReq)
if req.SceneId != 3 {
getSceneAreaRsp := &proto.GetSceneAreaRsp{
SceneId: req.SceneId,
}
g.SendMsg(cmd.GetSceneAreaRsp, player.PlayerID, player.ClientSeq, getSceneAreaRsp)
return
}
getSceneAreaRsp := &proto.GetSceneAreaRsp{
SceneId: 3,
AreaIdList: []uint32{12, 11, 19, 28, 5, 1, 24, 10, 21, 2, 7, 18, 3, 26, 6, 17, 22, 20, 9, 14, 16, 8, 13, 4, 27, 23},
CityInfoList: []*proto.CityInfo{
SceneId: req.SceneId,
}
areaIdMap := make(map[uint32]bool)
for _, worldAreaData := range gdconf.CONF.WorldAreaDataMap {
if uint32(worldAreaData.SceneId) == req.SceneId {
areaIdMap[uint32(worldAreaData.AreaId1)] = true
}
}
areaList := make([]uint32, 0)
for areaId := range areaIdMap {
areaList = append(areaList, areaId)
}
getSceneAreaRsp.AreaIdList = areaList
if req.SceneId == 3 {
getSceneAreaRsp.CityInfoList = []*proto.CityInfo{
{CityId: 1, Level: 10},
{CityId: 2, Level: 10},
{CityId: 3, Level: 10},
@@ -162,7 +183,20 @@ func (g *GameManager) GetSceneAreaReq(player *model.Player, payloadMsg pb.Messag
{CityId: 100, Level: 1},
{CityId: 101, Level: 1},
{CityId: 102, Level: 1},
},
}
}
g.SendMsg(cmd.GetSceneAreaRsp, player.PlayerID, player.ClientSeq, getSceneAreaRsp)
}
func (g *GameManager) EnterWorldAreaReq(player *model.Player, payloadMsg pb.Message) {
logger.Debug("user enter world area, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.EnterWorldAreaReq)
logger.Debug("EnterWorldAreaReq: %v", req)
enterWorldAreaRsp := &proto.EnterWorldAreaRsp{
AreaType: req.AreaType,
AreaId: req.AreaId,
}
g.SendMsg(cmd.EnterWorldAreaRsp, player.PlayerID, player.ClientSeq, enterWorldAreaRsp)
}

View File

@@ -7,7 +7,6 @@ import (
"hk4e/common/constant"
"hk4e/gdconf"
gdc "hk4e/gs/config"
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/pkg/object"
@@ -86,15 +85,22 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
playerWorldSceneInfoListNotify := &proto.PlayerWorldSceneInfoListNotify{
InfoList: []*proto.PlayerWorldSceneInfo{
{SceneId: 1, IsLocked: true, SceneTagIdList: []uint32{}},
{SceneId: 3, IsLocked: false, SceneTagIdList: []uint32{102, 111, 112, 116, 118, 126, 135, 140, 142, 149, 1091, 1094, 1095, 1099, 1101, 1103, 1105, 1110, 1120, 1122, 1125, 1127, 1129, 1131, 1133, 1135, 1137, 1138, 1140, 1143, 1146, 1165, 1168}},
{SceneId: 4, IsLocked: true, SceneTagIdList: []uint32{}},
{SceneId: 5, IsLocked: false, SceneTagIdList: []uint32{121, 1031}},
{SceneId: 6, IsLocked: false, SceneTagIdList: []uint32{144, 146, 1062, 1063}},
{SceneId: 7, IsLocked: true, SceneTagIdList: []uint32{136, 137, 138, 148, 1034}},
{SceneId: 9, IsLocked: true, SceneTagIdList: []uint32{1012, 1016, 1021, 1022, 1060, 1077}},
{SceneId: 1, IsLocked: false, SceneTagIdList: []uint32{}},
{SceneId: 3, IsLocked: false, SceneTagIdList: []uint32{}},
{SceneId: 4, IsLocked: false, SceneTagIdList: []uint32{}},
{SceneId: 5, IsLocked: false, SceneTagIdList: []uint32{}},
{SceneId: 6, IsLocked: false, SceneTagIdList: []uint32{}},
{SceneId: 7, IsLocked: false, SceneTagIdList: []uint32{}},
{SceneId: 9, IsLocked: false, SceneTagIdList: []uint32{}},
},
}
for _, info := range playerWorldSceneInfoListNotify.InfoList {
for _, sceneTagDataConfig := range gdconf.CONF.SceneTagDataMap {
if uint32(sceneTagDataConfig.SceneId) == info.SceneId {
info.SceneTagIdList = append(info.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId))
}
}
}
g.SendMsg(cmd.PlayerWorldSceneInfoListNotify, player.PlayerID, player.ClientSeq, playerWorldSceneInfoListNotify)
g.SendMsg(cmd.SceneForceUnlockNotify, player.PlayerID, player.ClientSeq, new(proto.SceneForceUnlockNotify))
@@ -226,46 +232,6 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
player.SceneLoadState = model.SceneInitFinish
}
func (g *GameManager) CreateConfigEntity(scene *Scene, objectId int64, entityConfig any) uint32 {
switch entityConfig.(type) {
case *gdconf.Monster:
monster := entityConfig.(*gdconf.Monster)
return scene.CreateEntityMonster(&model.Vector{
X: monster.Pos.X,
Y: monster.Pos.Y,
Z: monster.Pos.Z,
}, &model.Vector{
X: monster.Rot.X,
Y: monster.Rot.Y,
Z: monster.Rot.Z,
}, uint32(monster.MonsterId), uint8(monster.Level), g.GetTempFightPropMap(), uint32(monster.ConfigId), objectId)
case *gdconf.Npc:
npc := entityConfig.(*gdconf.Npc)
return scene.CreateEntityNpc(&model.Vector{
X: npc.Pos.X,
Y: npc.Pos.Y,
Z: npc.Pos.Z,
}, &model.Vector{
X: npc.Rot.X,
Y: npc.Rot.Y,
Z: npc.Rot.Z,
}, uint32(npc.NpcId), 0, 0, 0, uint32(npc.ConfigId), objectId)
case *gdconf.Gadget:
gadget := entityConfig.(*gdconf.Gadget)
return scene.CreateEntityGadgetNormal(&model.Vector{
X: gadget.Pos.X,
Y: gadget.Pos.Y,
Z: gadget.Pos.Z,
}, &model.Vector{
X: gadget.Rot.X,
Y: gadget.Rot.Y,
Z: gadget.Rot.Z,
}, uint32(gadget.GadgetId), uint32(gadget.ConfigId), objectId)
default:
return 0
}
}
func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Message) {
logger.Debug("user enter scene done, uid: %v", player.PlayerID)
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
@@ -302,7 +268,14 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
} else {
visionType = proto.VisionType_VISION_TYPE_TRANSPORT
}
entityIdList := scene.GetEntityIdList()
entityMap := scene.GetAllEntity()
entityIdList := make([]uint32, 0)
for _, entity := range entityMap {
if entity.id == activeAvatarEntityId {
continue
}
entityIdList = append(entityIdList, entity.id)
}
g.AddSceneEntityNotify(player, visionType, entityIdList, false, false)
sceneAreaWeatherNotify := &proto.SceneAreaWeatherNotify{
@@ -340,19 +313,6 @@ func (g *GameManager) PostEnterSceneReq(player *model.Player, payloadMsg pb.Mess
g.SendMsg(cmd.PostEnterSceneRsp, player.PlayerID, player.ClientSeq, postEnterSceneRsp)
}
func (g *GameManager) EnterWorldAreaReq(player *model.Player, payloadMsg pb.Message) {
logger.Debug("user enter world area, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.EnterWorldAreaReq)
logger.Debug("EnterWorldAreaReq: %v", req)
enterWorldAreaRsp := &proto.EnterWorldAreaRsp{
AreaType: req.AreaType,
AreaId: req.AreaId,
}
g.SendMsg(cmd.EnterWorldAreaRsp, player.PlayerID, player.ClientSeq, enterWorldAreaRsp)
}
func (g *GameManager) ChangeGameTimeReq(player *model.Player, payloadMsg pb.Message) {
logger.Debug("user change game time, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.ChangeGameTimeReq)
@@ -375,6 +335,76 @@ func (g *GameManager) ChangeGameTimeReq(player *model.Player, payloadMsg pb.Mess
g.SendMsg(cmd.ChangeGameTimeRsp, player.PlayerID, player.ClientSeq, changeGameTimeRsp)
}
// SceneEntityDrownReq 实体溺水请求
func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.SceneEntityDrownReq)
logger.Error("entity drown, entityId: %v", req.EntityId)
// PacketSceneEntityDrownRsp
sceneEntityDrownRsp := new(proto.SceneEntityDrownRsp)
sceneEntityDrownRsp.EntityId = req.EntityId
g.SendMsg(cmd.SceneEntityDrownRsp, player.PlayerID, player.ClientSeq, sceneEntityDrownRsp)
}
// CreateConfigEntity 创建配置表里的实体
func (g *GameManager) CreateConfigEntity(scene *Scene, objectId int64, entityConfig any) uint32 {
switch entityConfig.(type) {
case *gdconf.Monster:
monster := entityConfig.(*gdconf.Monster)
return scene.CreateEntityMonster(&model.Vector{
X: monster.Pos.X,
Y: monster.Pos.Y,
Z: monster.Pos.Z,
}, &model.Vector{
X: monster.Rot.X,
Y: monster.Rot.Y,
Z: monster.Rot.Z,
}, uint32(monster.MonsterId), uint8(monster.Level), g.GetTempFightPropMap(), uint32(monster.ConfigId), objectId)
case *gdconf.Npc:
npc := entityConfig.(*gdconf.Npc)
return scene.CreateEntityNpc(&model.Vector{
X: npc.Pos.X,
Y: npc.Pos.Y,
Z: npc.Pos.Z,
}, &model.Vector{
X: npc.Rot.X,
Y: npc.Rot.Y,
Z: npc.Rot.Z,
}, uint32(npc.NpcId), 0, 0, 0, uint32(npc.ConfigId), objectId)
case *gdconf.Gadget:
gadget := entityConfig.(*gdconf.Gadget)
// 70500000并不是实际的装置id 根据节点类型对应采集物配置表
if gadget.PointType != 0 && gadget.GadgetId == 70500000 {
gatherDataConfig, exist := gdconf.CONF.GatherDataPointTypeMap[gadget.PointType]
if !exist {
return 0
}
return scene.CreateEntityGadgetGather(&model.Vector{
X: gadget.Pos.X,
Y: gadget.Pos.Y,
Z: gadget.Pos.Z,
}, &model.Vector{
X: gadget.Rot.X,
Y: gadget.Rot.Y,
Z: gadget.Rot.Z,
}, uint32(gatherDataConfig.GadgetId), uint32(gatherDataConfig.GatherId), uint32(gadget.ConfigId), objectId)
} else {
return scene.CreateEntityGadgetNormal(&model.Vector{
X: gadget.Pos.X,
Y: gadget.Pos.Y,
Z: gadget.Pos.Z,
}, &model.Vector{
X: gadget.Rot.X,
Y: gadget.Rot.Y,
Z: gadget.Rot.Z,
}, uint32(gadget.GadgetId), uint32(gadget.ConfigId), objectId)
}
default:
return 0
}
}
func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, enterType proto.EnterType) *proto.PlayerEnterSceneNotify {
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId)
@@ -390,12 +420,17 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, en
EnterReason: uint32(constant.EnterReasonConst.Login),
IsFirstLoginEnterScene: true,
WorldType: 1,
SceneTagIdList: make([]uint32, 0),
}
playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(player.SceneId)) + "-" +
strconv.Itoa(int(player.PlayerID)) + "-" +
strconv.Itoa(int(time.Now().Unix())) + "-" +
"296359"
playerEnterSceneNotify.SceneTagIdList = []uint32{102, 111, 112, 116, 118, 126, 135, 140, 142, 149, 1091, 1094, 1095, 1099, 1101, 1103, 1105, 1110, 1120, 1122, 1125, 1127, 1129, 1131, 1133, 1135, 1137, 1138, 1140, 1143, 1146, 1165, 1168}
for _, sceneTagDataConfig := range gdconf.CONF.SceneTagDataMap {
if uint32(sceneTagDataConfig.SceneId) == player.SceneId {
playerEnterSceneNotify.SceneTagIdList = append(playerEnterSceneNotify.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId))
}
}
return playerEnterSceneNotify
}
@@ -435,13 +470,16 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp(
EnterReason: enterReason,
WorldType: 1,
DungeonId: dungeonId,
SceneTagIdList: make([]uint32, 0),
}
playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(player.SceneId)) + "-" +
strconv.Itoa(int(targetPlayer.PlayerID)) + "-" +
strconv.Itoa(int(time.Now().Unix())) + "-" +
"296359"
if player.SceneId == 3 {
playerEnterSceneNotify.SceneTagIdList = []uint32{102, 111, 112, 116, 118, 126, 135, 140, 142, 149, 1091, 1094, 1095, 1099, 1101, 1103, 1105, 1110, 1120, 1122, 1125, 1127, 1129, 1131, 1133, 1135, 1137, 1138, 1140, 1143, 1146, 1165, 1168}
for _, sceneTagDataConfig := range gdconf.CONF.SceneTagDataMap {
if uint32(sceneTagDataConfig.SceneId) == player.SceneId {
playerEnterSceneNotify.SceneTagIdList = append(playerEnterSceneNotify.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId))
}
}
return playerEnterSceneNotify
}
@@ -605,18 +643,6 @@ func (g *GameManager) PacketFightPropMapToPbFightPropList(fightPropMap map[uint3
return fightPropList
}
// SceneEntityDrownReq 实体溺水请求
func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.SceneEntityDrownReq)
logger.Error("entity drown, entityId: %v", req.EntityId)
// PacketSceneEntityDrownRsp
sceneEntityDrownRsp := new(proto.SceneEntityDrownRsp)
sceneEntityDrownRsp.EntityId = req.EntityId
g.SendMsg(cmd.SceneEntityDrownRsp, player.PlayerID, player.ClientSeq, sceneEntityDrownRsp)
}
func (g *GameManager) PacketSceneEntityInfoAvatar(scene *Scene, player *model.Player, avatarId uint32) *proto.SceneEntityInfo {
entity := scene.GetEntity(scene.world.GetPlayerWorldAvatarEntityId(player, avatarId))
if entity == nil {
@@ -851,7 +877,7 @@ func (g *GameManager) PacketSceneAvatarInfo(scene *Scene, player *model.Player,
SkillDepotId: player.AvatarMap[avatarId].SkillDepotId,
Weapon: &proto.SceneWeaponInfo{
EntityId: scene.world.GetPlayerWorldAvatarWeaponEntityId(player, avatarId),
GadgetId: uint32(gdc.CONF.ItemDataMap[int32(weapon.ItemId)].GadgetId),
GadgetId: uint32(gdconf.CONF.ItemDataMap[int32(weapon.ItemId)].GadgetId),
ItemId: weapon.ItemId,
Guid: weapon.Guid,
Level: uint32(weapon.Level),
@@ -905,7 +931,7 @@ func (g *GameManager) PacketSceneGadgetInfoNormal(entity *Entity) *proto.SceneGa
}
func (g *GameManager) PacketSceneGadgetInfoGather(entity *Entity) *proto.SceneGadgetInfo {
gather, ok := gdc.CONF.GatherDataMap[int32(entity.gadgetEntity.gadgetGatherEntity.gatherId)]
gather, ok := gdconf.CONF.GatherDataMap[int32(entity.gadgetEntity.gadgetGatherEntity.gatherId)]
if !ok {
logger.Error("gather data error, gatherId: %v", entity.gadgetEntity.gadgetGatherEntity.gatherId)
return new(proto.SceneGadgetInfo)

View File

@@ -491,7 +491,7 @@ func (g *GameManager) DrownBackHandler(player *model.Player) {
// }
// }
// 传送玩家至安全位置
g.TeleportPlayer(player, constant.EnterReasonConst.Revival, player.SceneId, pos, 0)
g.TeleportPlayer(player, constant.EnterReasonConst.Revival, player.SceneId, pos, new(model.Vector), 0)
}
// 防止重置后又被修改
if player.StaminaInfo.DrownBackDelay != 0 {

View File

@@ -2,7 +2,7 @@ package game
import (
"hk4e/common/constant"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/gs/model"
"hk4e/pkg/endec"
"hk4e/pkg/logger"
@@ -244,12 +244,12 @@ func (g *GameManager) PacketSceneTeamUpdateNotify(world *World) *proto.SceneTeam
sceneTeamAvatar.SceneAvatarInfo = g.PacketSceneAvatarInfo(worldPlayerScene, worldPlayer, worldAvatar.avatarId)
}
// add AbilityControlBlock
avatarDataConfig := gdc.CONF.AvatarDataMap[int32(worldAvatar.avatarId)]
avatarDataConfig := gdconf.CONF.AvatarDataMap[int32(worldAvatar.avatarId)]
acb := sceneTeamAvatar.AbilityControlBlock
embryoId := 0
// add avatar abilities
if avatarDataConfig != nil {
for _, abilityId := range avatarDataConfig.Abilities {
for _, abilityId := range avatarDataConfig.AbilityHashCodeList {
embryoId++
emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId),
@@ -280,9 +280,9 @@ func (g *GameManager) PacketSceneTeamUpdateNotify(world *World) *proto.SceneTeam
// acb.AbilityEmbryoList = append(acb.AbilityEmbryoList, emb)
// }
// add skill depot abilities
skillDepot := gdc.CONF.AvatarSkillDepotDataMap[int32(worldPlayerAvatar.SkillDepotId)]
if skillDepot != nil && len(skillDepot.Abilities) != 0 {
for _, id := range skillDepot.Abilities {
skillDepot := gdconf.CONF.AvatarSkillDepotDataMap[int32(worldPlayerAvatar.SkillDepotId)]
if skillDepot != nil && len(skillDepot.AbilityHashCodeList) != 0 {
for _, id := range skillDepot.AbilityHashCodeList {
embryoId++
emb := &proto.AbilityEmbryo{
AbilityId: uint32(embryoId),

View File

@@ -2,16 +2,16 @@ package game
import (
"hk4e/common/constant"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/pkg/logger"
"hk4e/protocol/cmd"
"hk4e/protocol/proto"
)
func (g *GameManager) GetAllWeaponDataConfig() map[int32]*gdc.ItemData {
allWeaponDataConfig := make(map[int32]*gdc.ItemData)
for itemId, itemData := range gdc.CONF.ItemDataMap {
if itemData.EquipEnumType != constant.EquipTypeConst.EQUIP_WEAPON {
func (g *GameManager) GetAllWeaponDataConfig() map[int32]*gdconf.ItemData {
allWeaponDataConfig := make(map[int32]*gdconf.ItemData)
for itemId, itemData := range gdconf.CONF.ItemDataMap {
if uint16(itemData.EquipType) != constant.EquipTypeConst.EQUIP_WEAPON {
continue
}
if (itemId >= 10000 && itemId <= 10008) ||

View File

@@ -190,7 +190,7 @@ func (t *TickManager) onTickMinute(now int64) {
return
}
// TODO 3.0.0REL版本中 发送某些无效家具 可能会导致客户端背包家具界面卡死
if itemDataConfig.ItemEnumType == constant.ItemTypeConst.ITEM_FURNITURE {
if uint16(itemDataConfig.Type) == constant.ItemTypeConst.ITEM_FURNITURE {
continue
}
num := random.GetRandomInt32(1, 9)

View File

@@ -1142,11 +1142,3 @@ func (s *Scene) GetEntity(entityId uint32) *Entity {
func (s *Scene) GetEntityByObjectId(objectId int64) *Entity {
return s.objectIdEntityMap[objectId]
}
func (s *Scene) GetEntityIdList() []uint32 {
entityIdList := make([]uint32, 0)
for k := range s.entityMap {
entityIdList = append(entityIdList, k)
}
return entityIdList
}

View File

@@ -4,7 +4,7 @@ import (
"time"
"hk4e/common/constant"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/pkg/logger"
)
@@ -19,20 +19,13 @@ type Avatar struct {
CurrHP float64 `bson:"currHP"` // 当前生命值
CurrEnergy float64 `bson:"currEnergy"` // 当前元素能量值
FetterList []uint32 `bson:"fetterList"` // 资料解锁条目
SkillLevelMap map[uint32]uint32 `bson:"skillLevelMap"` // 技能等级
SkillExtraChargeMap map[uint32]uint32 `bson:"skillExtraChargeMap"`
ProudSkillBonusMap map[uint32]uint32 `bson:"proudSkillBonusMap"`
SkillDepotId uint32 `bson:"skillDepotId"`
CoreProudSkillLevel uint8 `bson:"coreProudSkillLevel"` // 已解锁命之座层数
TalentIdList []uint32 `bson:"talentIdList"` // 已解锁命之座技能列表
ProudSkillList []uint32 `bson:"proudSkillList"` // 被动技能列表
FlyCloak uint32 `bson:"flyCloak"` // 当前风之翼
Costume uint32 `bson:"costume"` // 当前衣装
BornTime int64 `bson:"bornTime"` // 获得时间
FetterLevel uint8 `bson:"fetterLevel"` // 好感度等级
FetterExp uint32 `bson:"fetterExp"` // 好感度经验
NameCardRewardId uint32 `bson:"nameCardRewardId"`
NameCardId uint32 `bson:"nameCardId"`
SkillLevelMap map[uint32]uint32 `bson:"skillLevelMap"` // 技能等级数据
SkillDepotId uint32 `bson:"skillDepotId"` // 技能库id
FlyCloak uint32 `bson:"flyCloak"` // 当前风之翼
Costume uint32 `bson:"costume"` // 当前衣装
BornTime int64 `bson:"bornTime"` // 获得时间
FetterLevel uint8 `bson:"fetterLevel"` // 好感度等级
FetterExp uint32 `bson:"fetterExp"` // 好感度经验
Guid uint64 `bson:"-"`
EquipGuidList map[uint64]uint64 `bson:"-"`
EquipWeapon *Weapon `bson:"-"`
@@ -48,7 +41,7 @@ func (p *Player) InitAllAvatar() {
}
func (p *Player) InitAvatar(avatar *Avatar) {
avatarDataConfig, ok := gdc.CONF.AvatarDataMap[int32(avatar.AvatarId)]
avatarDataConfig, ok := gdconf.CONF.AvatarDataMap[int32(avatar.AvatarId)]
if !ok {
logger.Error("avatarDataConfig error, avatarId: %v", avatar.AvatarId)
return
@@ -90,13 +83,13 @@ func (p *Player) GetAvatarIdByGuid(guid uint64) uint32 {
}
func (p *Player) AddAvatar(avatarId uint32) {
avatarDataConfig, ok := gdc.CONF.AvatarDataMap[int32(avatarId)]
if !ok {
logger.Error("avatarDataConfig error, avatarId: %v", avatarId)
avatarDataConfig, exist := gdconf.CONF.AvatarDataMap[int32(avatarId)]
if !exist {
logger.Error("avatar data config is nil, avatarId: %v", avatarId)
return
}
skillDepotId := int32(0)
// 主角要单独设置
// 主角可以切换属性 技能库要单独设置 这里默认给风元素的技能库
if avatarId == 10000005 {
skillDepotId = 504
} else if avatarId == 10000007 {
@@ -104,9 +97,9 @@ func (p *Player) AddAvatar(avatarId uint32) {
} else {
skillDepotId = avatarDataConfig.SkillDepotId
}
avatarSkillDepotDataConfig, ok := gdc.CONF.AvatarSkillDepotDataMap[skillDepotId]
if !ok {
logger.Error("avatarSkillDepotDataConfig error, skillDepotId: %v", skillDepotId)
avatarSkillDepotDataConfig, exist := gdconf.CONF.AvatarSkillDepotDataMap[skillDepotId]
if !exist {
logger.Error("avatar skill depot data config is nil, skillDepotId: %v", skillDepotId)
return
}
avatar := &Avatar{
@@ -119,46 +112,27 @@ func (p *Player) AddAvatar(avatarId uint32) {
SatiationPenalty: 0,
CurrHP: 0,
CurrEnergy: 0,
FetterList: nil,
FetterList: make([]uint32, 0),
SkillLevelMap: make(map[uint32]uint32),
SkillExtraChargeMap: make(map[uint32]uint32),
ProudSkillBonusMap: nil,
SkillDepotId: uint32(avatarSkillDepotDataConfig.Id),
CoreProudSkillLevel: 0,
TalentIdList: make([]uint32, 0),
ProudSkillList: make([]uint32, 0),
SkillDepotId: uint32(skillDepotId),
FlyCloak: 140001,
Costume: 0,
BornTime: time.Now().Unix(),
FetterLevel: 1,
FetterExp: 0,
NameCardRewardId: 0,
NameCardId: 0,
Guid: 0,
EquipGuidList: nil,
EquipWeapon: nil,
EquipReliquaryList: nil,
FightPropMap: nil,
ExtraAbilityEmbryos: nil,
ExtraAbilityEmbryos: make(map[string]bool),
}
if avatarSkillDepotDataConfig.EnergySkill > 0 {
avatar.SkillLevelMap[uint32(avatarSkillDepotDataConfig.EnergySkill)] = 1
}
// 元素爆发1级
avatar.SkillLevelMap[uint32(avatarSkillDepotDataConfig.EnergySkill)] = 1
for _, skillId := range avatarSkillDepotDataConfig.Skills {
if skillId > 0 {
avatar.SkillLevelMap[uint32(skillId)] = 1
}
}
for _, openData := range avatarSkillDepotDataConfig.InherentProudSkillOpens {
if openData.ProudSkillGroupId == 0 {
continue
}
if openData.NeedAvatarPromoteLevel <= int32(avatar.Promote) {
proudSkillId := (openData.ProudSkillGroupId * 100) + 1
// TODO if GameData.getProudSkillDataMap().containsKey(proudSkillId) java
avatar.ProudSkillList = append(avatar.ProudSkillList, uint32(proudSkillId))
}
// 小技能1级
avatar.SkillLevelMap[uint32(skillId)] = 1
}
avatar.CurrHP = avatarDataConfig.GetBaseHpByLevel(avatar.Level)
@@ -167,17 +141,33 @@ func (p *Player) AddAvatar(avatarId uint32) {
}
func (p *Player) SetCurrEnergy(avatar *Avatar, value float64, max bool) {
avatarDataConfig := gdc.CONF.AvatarDataMap[int32(avatar.AvatarId)]
avatarSkillDepotDataConfig := gdc.CONF.AvatarSkillDepotDataMap[avatarDataConfig.SkillDepotId]
if avatarSkillDepotDataConfig == nil || avatarSkillDepotDataConfig.EnergySkillData == nil {
var avatarSkillDataConfig *gdconf.AvatarSkillData = nil
if avatar.AvatarId == 10000005 || avatar.AvatarId == 10000007 {
avatarSkillDepotDataConfig, exist := gdconf.CONF.AvatarSkillDepotDataMap[int32(avatar.SkillDepotId)]
if !exist {
return
}
avatarSkillDataConfig, exist = gdconf.CONF.AvatarSkillDataMap[avatarSkillDepotDataConfig.EnergySkill]
if !exist {
return
}
} else {
avatarSkillDataConfig = gdconf.CONF.GetAvatarEnergySkillConfig(avatar.AvatarId)
}
if avatarSkillDataConfig == nil {
logger.Error("get avatar energy skill is nil, avatarId: %v", avatar.AvatarId)
return
}
element := avatarSkillDepotDataConfig.ElementType
avatar.FightPropMap[uint32(element.MaxEnergyProp)] = float32(avatarSkillDepotDataConfig.EnergySkillData.CostElemVal)
elementType := constant.ElementTypeConst.VALUE_MAP[uint16(avatarSkillDataConfig.CostElemType)]
if elementType == nil {
logger.Error("get element type const is nil, value: %v", avatarSkillDataConfig.CostElemType)
return
}
avatar.FightPropMap[uint32(elementType.MaxEnergyProp)] = float32(avatarSkillDataConfig.CostElemVal)
if max {
avatar.FightPropMap[uint32(element.CurrEnergyProp)] = float32(avatarSkillDepotDataConfig.EnergySkillData.CostElemVal)
avatar.FightPropMap[uint32(elementType.CurrEnergyProp)] = float32(avatarSkillDataConfig.CostElemVal)
} else {
avatar.FightPropMap[uint32(element.CurrEnergyProp)] = float32(value)
avatar.FightPropMap[uint32(elementType.CurrEnergyProp)] = float32(value)
}
}

View File

@@ -1,73 +0,0 @@
package model
import (
"hk4e/pkg/logger"
"hk4e/protocol/proto"
)
// 泛型通用转发器
type InvokeEntryType interface {
proto.CombatInvokeEntry | proto.AbilityInvokeEntry
}
type InvokeHandler[T InvokeEntryType] struct {
EntryListForwardAll []*T
EntryListForwardAllExceptCur []*T
EntryListForwardHost []*T
EntryListForwardServer []*T
}
func NewInvokeHandler[T InvokeEntryType]() (r *InvokeHandler[T]) {
r = new(InvokeHandler[T])
r.InitInvokeHandler()
return r
}
func (i *InvokeHandler[T]) InitInvokeHandler() {
i.EntryListForwardAll = make([]*T, 0)
i.EntryListForwardAllExceptCur = make([]*T, 0)
i.EntryListForwardHost = make([]*T, 0)
i.EntryListForwardServer = make([]*T, 0)
}
func (i *InvokeHandler[T]) AddEntry(forward proto.ForwardType, entry *T) {
switch forward {
case proto.ForwardType_FORWARD_TYPE_TO_ALL:
i.EntryListForwardAll = append(i.EntryListForwardAll, entry)
case proto.ForwardType_FORWARD_TYPE_TO_ALL_EXCEPT_CUR:
fallthrough
case proto.ForwardType_FORWARD_TYPE_TO_ALL_EXIST_EXCEPT_CUR:
i.EntryListForwardAllExceptCur = append(i.EntryListForwardAllExceptCur, entry)
case proto.ForwardType_FORWARD_TYPE_TO_HOST:
i.EntryListForwardHost = append(i.EntryListForwardHost, entry)
case proto.ForwardType_FORWARD_TYPE_ONLY_SERVER:
i.EntryListForwardServer = append(i.EntryListForwardServer, entry)
// logger.Error("forward server entry: %v", entry)
default:
logger.Error("forward type: %v, entry: %v", forward, entry)
}
}
func (i *InvokeHandler[T]) AllLen() int {
return len(i.EntryListForwardAll)
}
func (i *InvokeHandler[T]) AllExceptCurLen() int {
return len(i.EntryListForwardAllExceptCur)
}
func (i *InvokeHandler[T]) HostLen() int {
return len(i.EntryListForwardHost)
}
func (i *InvokeHandler[T]) ServerLen() int {
return len(i.EntryListForwardServer)
}
func (i *InvokeHandler[T]) Clear() {
i.EntryListForwardAll = make([]*T, 0)
i.EntryListForwardAllExceptCur = make([]*T, 0)
i.EntryListForwardHost = make([]*T, 0)
i.EntryListForwardServer = make([]*T, 0)
}

View File

@@ -1,6 +1,7 @@
package model
import (
"hk4e/pkg/logger"
"hk4e/protocol/proto"
"go.mongodb.org/mongo-driver/bson/primitive"
@@ -96,14 +97,69 @@ func (p *Player) InitAll() {
p.InitAllReliquary()
}
func (p *Player) InitAllReliquary() {
for reliquaryId, reliquary := range p.ReliquaryMap {
reliquary.Guid = p.GetNextGameObjectGuid()
p.ReliquaryMap[reliquaryId] = reliquary
if reliquary.AvatarId != 0 {
avatar := p.AvatarMap[reliquary.AvatarId]
avatar.EquipGuidList[reliquary.Guid] = reliquary.Guid
avatar.EquipReliquaryList = append(avatar.EquipReliquaryList, reliquary)
}
// 多人世界网络同步包转发器
type InvokeEntryType interface {
proto.CombatInvokeEntry | proto.AbilityInvokeEntry
}
type InvokeHandler[T InvokeEntryType] struct {
EntryListForwardAll []*T
EntryListForwardAllExceptCur []*T
EntryListForwardHost []*T
EntryListForwardServer []*T
}
func NewInvokeHandler[T InvokeEntryType]() (r *InvokeHandler[T]) {
r = new(InvokeHandler[T])
r.InitInvokeHandler()
return r
}
func (i *InvokeHandler[T]) InitInvokeHandler() {
i.EntryListForwardAll = make([]*T, 0)
i.EntryListForwardAllExceptCur = make([]*T, 0)
i.EntryListForwardHost = make([]*T, 0)
i.EntryListForwardServer = make([]*T, 0)
}
func (i *InvokeHandler[T]) AddEntry(forward proto.ForwardType, entry *T) {
switch forward {
case proto.ForwardType_FORWARD_TYPE_TO_ALL:
i.EntryListForwardAll = append(i.EntryListForwardAll, entry)
case proto.ForwardType_FORWARD_TYPE_TO_ALL_EXCEPT_CUR:
fallthrough
case proto.ForwardType_FORWARD_TYPE_TO_ALL_EXIST_EXCEPT_CUR:
i.EntryListForwardAllExceptCur = append(i.EntryListForwardAllExceptCur, entry)
case proto.ForwardType_FORWARD_TYPE_TO_HOST:
i.EntryListForwardHost = append(i.EntryListForwardHost, entry)
case proto.ForwardType_FORWARD_TYPE_ONLY_SERVER:
i.EntryListForwardServer = append(i.EntryListForwardServer, entry)
// logger.Error("forward server entry: %v", entry)
default:
logger.Error("forward type: %v, entry: %v", forward, entry)
}
}
func (i *InvokeHandler[T]) AllLen() int {
return len(i.EntryListForwardAll)
}
func (i *InvokeHandler[T]) AllExceptCurLen() int {
return len(i.EntryListForwardAllExceptCur)
}
func (i *InvokeHandler[T]) HostLen() int {
return len(i.EntryListForwardHost)
}
func (i *InvokeHandler[T]) ServerLen() int {
return len(i.EntryListForwardServer)
}
func (i *InvokeHandler[T]) Clear() {
i.EntryListForwardAll = make([]*T, 0)
i.EntryListForwardAllExceptCur = make([]*T, 0)
i.EntryListForwardHost = make([]*T, 0)
i.EntryListForwardServer = make([]*T, 0)
}

View File

@@ -1,16 +1,58 @@
package model
import (
"hk4e/gdconf"
"hk4e/pkg/logger"
)
type Reliquary struct {
ReliquaryId uint64 `bson:"reliquaryId"` // 圣遗物的唯一id
ItemId uint32 `bson:"itemId"` // 圣遗物的道具id
Level uint8 `bson:"level"` // 等级
Exp uint32 `bson:"exp"` // 当前经验值
TotalExp uint32 `bson:"totalExp"` // 升级所需总经验值
Promote uint8 `bson:"promote"` // 突破等阶
Lock bool `bson:"lock"` // 锁定状态
AffixIdList []uint32 `bson:"affixIdList"` // 词缀
Refinement uint8 `bson:"refinement"` // 精炼等阶
MainPropId uint32 `bson:"mainPropId"` // 主词条id
AvatarId uint32 `bson:"avatarId"` // 装备角色id
Guid uint64 `bson:"-"`
}
func (p *Player) InitReliquary(reliquary *Reliquary) {
reliquary.Guid = p.GetNextGameObjectGuid()
p.ReliquaryMap[reliquary.ReliquaryId] = reliquary
if reliquary.AvatarId != 0 {
avatar := p.AvatarMap[reliquary.AvatarId]
avatar.EquipGuidList[reliquary.Guid] = reliquary.Guid
avatar.EquipReliquaryList = append(avatar.EquipReliquaryList, reliquary)
}
}
func (p *Player) InitAllReliquary() {
for _, reliquary := range p.ReliquaryMap {
p.InitReliquary(reliquary)
}
}
func (p *Player) AddReliquary(itemId uint32, reliquaryId uint64, mainPropId uint32) {
reliquary := &Reliquary{
ReliquaryId: reliquaryId,
ItemId: itemId,
Level: 1,
Exp: 0,
Promote: 0,
Lock: false,
AffixIdList: make([]uint32, 0),
MainPropId: mainPropId,
AvatarId: 0,
Guid: 0,
}
itemDataConfig, exist := gdconf.CONF.ItemDataMap[int32(itemId)]
if !exist {
logger.Error("reliquary config is nil, itemId: %v", itemId)
return
}
_ = itemDataConfig
p.InitReliquary(reliquary)
p.ReliquaryMap[reliquaryId] = reliquary
}

View File

@@ -2,7 +2,8 @@ package model
import (
"hk4e/common/constant"
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/pkg/logger"
)
type Team struct {
@@ -55,16 +56,22 @@ func NewTeamInfo() (r *TeamInfo) {
func (t *TeamInfo) UpdateTeam() {
activeTeam := t.GetActiveTeam()
// 队伍元素共鸣
// TODO 队伍元素共鸣
t.TeamResonances = make(map[uint16]bool)
t.TeamResonancesConfig = make(map[int32]bool)
teamElementTypeCountMap := make(map[uint16]uint8)
avatarSkillDepotDataMapConfig := gdc.CONF.AvatarSkillDepotDataMap
for _, avatarId := range activeTeam.GetAvatarIdList() {
skillData := avatarSkillDepotDataMapConfig[int32(avatarId)]
if skillData != nil {
teamElementTypeCountMap[skillData.ElementType.Value] += 1
avatarSkillDataConfig := gdconf.CONF.GetAvatarEnergySkillConfig(avatarId)
if avatarSkillDataConfig == nil {
logger.Error("get avatar energy skill is nil, avatarId: %v", avatarId)
continue
}
elementType := constant.ElementTypeConst.VALUE_MAP[uint16(avatarSkillDataConfig.CostElemType)]
if elementType == nil {
logger.Error("get element type const is nil, value: %v", avatarSkillDataConfig.CostElemType)
continue
}
teamElementTypeCountMap[elementType.Value] += 1
}
for k, v := range teamElementTypeCountMap {
if v >= 2 {

View File

@@ -1,7 +1,7 @@
package model
import (
gdc "hk4e/gs/config"
"hk4e/gdconf"
"hk4e/pkg/logger"
)
@@ -10,12 +10,10 @@ type Weapon struct {
ItemId uint32 `bson:"itemId"` // 武器的道具id
Level uint8 `bson:"level"` // 等级
Exp uint32 `bson:"exp"` // 当前经验值
TotalExp uint32 `bson:"totalExp"` // 升级所需总经验值
Promote uint8 `bson:"promote"` // 突破等阶
Lock bool `bson:"lock"` // 锁定状态
AffixIdList []uint32 `bson:"affixIdList"` // 词缀
Refinement uint8 `bson:"refinement"` // 精炼等阶
MainPropId uint32 `bson:"mainPropId"` // 主词条id
AvatarId uint32 `bson:"avatarId"` // 装备角色id
Guid uint64 `bson:"-"`
}
@@ -29,7 +27,6 @@ func (p *Player) InitWeapon(weapon *Weapon) {
avatar.EquipGuidList[weapon.Guid] = weapon.Guid
avatar.EquipWeapon = weapon
}
return
}
func (p *Player) InitAllWeapon() {
@@ -56,25 +53,19 @@ func (p *Player) AddWeapon(itemId uint32, weaponId uint64) {
ItemId: itemId,
Level: 1,
Exp: 0,
TotalExp: 0,
Promote: 0,
Lock: false,
AffixIdList: make([]uint32, 0),
Refinement: 0,
MainPropId: 0,
Guid: 0,
}
itemDataConfig, ok := gdc.CONF.ItemDataMap[int32(itemId)]
if !ok {
logger.Error("config is nil, itemId: %v", itemId)
itemDataConfig, exist := gdconf.CONF.ItemDataMap[int32(itemId)]
if !exist {
logger.Error("weapon config is nil, itemId: %v", itemId)
return
}
if itemDataConfig.SkillAffix != nil {
for _, skillAffix := range itemDataConfig.SkillAffix {
if skillAffix > 0 {
weapon.AffixIdList = append(weapon.AffixIdList, uint32(skillAffix))
}
}
for _, skillAffix := range itemDataConfig.SkillAffix {
weapon.AffixIdList = append(weapon.AffixIdList, uint32(skillAffix))
}
p.InitWeapon(weapon)
p.WeaponMap[weaponId] = weapon