Save endgame progress, team presets, technique support and camera controls
This commit is contained in:
1 parent
a681affdb3
commit
639cef7d19
52 files changed
+11940
-766
No files matched your search
@@ -81,6 +81,8 @@ type AvatarConfig struct {
|
||||
}
|
||||
|
||||
type JsonConfig struct {
|
||||
MapEntrances map[uint32]MapEntranceEntry `json:"-"`
|
||||
SceneAnchors map[uint32][]AnchorItem `json:"-"`
|
||||
// entryId -> "P<plane>_F<floor>" -> config
|
||||
LevelOutputConfigs map[uint32]map[string]*LevelOutputConfig `json:"levelOutputConfigs"`
|
||||
AvatarConfigs map[uint32]AvatarConfig `json:"avatarConfigs"`
|
||||
@@ -192,6 +194,7 @@ func GameRes() (*JsonConfig, error) {
|
||||
_ = Teleports() // ensure teleportDB is initialized
|
||||
|
||||
loadSupplementaryResources(gameRes)
|
||||
applySceneMetadata(gameRes)
|
||||
})
|
||||
return gameRes, gameResErr
|
||||
}
|
||||
@@ -266,6 +269,8 @@ func loadSupplementaryResources(res *JsonConfig) {
|
||||
}
|
||||
|
||||
planesByID := map[uint32]MazePlaneEntry{}
|
||||
res.MapEntrances = entrancesByEntry
|
||||
res.SceneAnchors = map[uint32][]AnchorItem{}
|
||||
if raw, err := readResourceFile("resources/MazePlane.json", "MazePlane.json"); err == nil {
|
||||
var list []MazePlaneEntry
|
||||
if json.Unmarshal(raw, &list) != nil {
|
||||
@@ -366,6 +371,7 @@ func loadSupplementaryResources(res *JsonConfig) {
|
||||
name: {
|
||||
IsEnteredSceneInfo: true,
|
||||
Scenes: groups,
|
||||
WorldID: planesByID[sc.PlaneID].WorldID,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -377,6 +383,7 @@ func loadSupplementaryResources(res *JsonConfig) {
|
||||
var aFile AnchorConfigFile
|
||||
if json.Unmarshal(raw, &aFile) == nil && len(aFile.AnchorConfig) > 0 {
|
||||
for _, item := range aFile.AnchorConfig {
|
||||
res.SceneAnchors[item.EntryID] = item.Anchor
|
||||
floorID := uint32(0)
|
||||
if ent, ok := entrancesByEntry[item.EntryID]; ok && ent.FloorID != 0 {
|
||||
floorID = ent.FloorID
|
||||
@@ -415,6 +422,72 @@ func loadSupplementaryResources(res *JsonConfig) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Supplementary scenes do not carry world metadata. Resolve it from the
|
||||
// installed entrance/plane tables, including entries supplied by Anchor.json.
|
||||
floorSavedValues := map[uint32]map[string]int32{}
|
||||
if raw, err := readResourceFile("resources/FloorSavedValuesConfig.json"); err == nil {
|
||||
var table struct {
|
||||
Floors []struct {
|
||||
FloorID uint32 `json:"FloorID"`
|
||||
Values []struct {
|
||||
Name string `json:"Name"`
|
||||
MaxValue int32 `json:"MaxValue"`
|
||||
} `json:"SavedValues"`
|
||||
} `json:"saved_values"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &table); err == nil {
|
||||
// Same unlocked scene defaults as PearlSR 005d2c12 scene_mgr.zig.
|
||||
for _, floor := range table.Floors {
|
||||
values := map[string]int32{}
|
||||
for _, value := range floor.Values {
|
||||
if value.Name != "" {
|
||||
values[value.Name] = value.MaxValue
|
||||
}
|
||||
}
|
||||
floorSavedValues[floor.FloorID] = values
|
||||
}
|
||||
} else {
|
||||
LogInfo("[SCENE] Invalid FloorSavedValuesConfig: %v", err)
|
||||
}
|
||||
}
|
||||
for entryID, configs := range res.LevelOutputConfigs {
|
||||
entrance, ok := entrancesByEntry[entryID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// Legacy dumps label every entrance in a plane with its first floor.
|
||||
// An entrance has an explicit floor in MapEntrance; do not derive it.
|
||||
if len(configs) == 1 {
|
||||
canonical := fmt.Sprintf("P%d_F%d", entrance.PlaneID, entrance.FloorID)
|
||||
for name, config := range configs {
|
||||
if name != canonical {
|
||||
delete(configs, name)
|
||||
configs[canonical] = config
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
plane, ok := planesByID[entrance.PlaneID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for name, config := range configs {
|
||||
config.WorldID = plane.WorldID
|
||||
var configPlane, configFloor uint32
|
||||
if n, _ := fmt.Sscanf(name, "P%d_F%d", &configPlane, &configFloor); n != 2 {
|
||||
continue
|
||||
}
|
||||
if config.SavedValues == nil {
|
||||
config.SavedValues = map[string]int32{}
|
||||
}
|
||||
for name, value := range floorSavedValues[configFloor] {
|
||||
if _, exists := config.SavedValues[name]; !exists {
|
||||
config.SavedValues[name] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Teleports lazily parses teleports.json ({floor_id: {teleport_id: info}}).
|
||||
|
||||
Reference in new issue
Block a user