mirror of Walter-Sparrow / lunar-tear
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add weapon awakening functionality

+157 -5
+44
server/internal/masterdata/weapon.go
··· 94 94 SortOrder int32 `json:"SortOrder"` 95 95 } 96 96 97 + type WeaponAwakenRow struct { 98 + WeaponId int32 `json:"WeaponId"` 99 + WeaponAwakenEffectGroupId int32 `json:"WeaponAwakenEffectGroupId"` 100 + WeaponAwakenMaterialGroupId int32 `json:"WeaponAwakenMaterialGroupId"` 101 + ConsumeGold int32 `json:"ConsumeGold"` 102 + LevelLimitUp int32 `json:"LevelLimitUp"` 103 + } 104 + 105 + type WeaponAwakenEffectGroupRow struct { 106 + WeaponAwakenEffectGroupId int32 `json:"WeaponAwakenEffectGroupId"` 107 + WeaponAwakenEffectType int32 `json:"WeaponAwakenEffectType"` 108 + WeaponAwakenEffectId int32 `json:"WeaponAwakenEffectId"` 109 + } 110 + 111 + type WeaponAwakenMaterialGroupRow struct { 112 + WeaponAwakenMaterialGroupId int32 `json:"WeaponAwakenMaterialGroupId"` 113 + MaterialId int32 `json:"MaterialId"` 114 + Count int32 `json:"Count"` 115 + SortOrder int32 `json:"SortOrder"` 116 + } 117 + 97 118 type weaponRarityEnhanceRow struct { 98 119 RarityType int32 `json:"RarityType"` 99 120 BaseEnhancementObtainedExp int32 `json:"BaseEnhancementObtainedExp"` ··· 137 158 LimitBreakCostByMaterialByEnhanceId map[int32]NumericalFunc 138 159 BaseExpByEnhanceId map[int32]int32 139 160 ReleaseConditionsByGroupId map[int32][]WeaponStoryReleaseConditionRow 161 + 162 + AwakenByWeaponId map[int32]WeaponAwakenRow 163 + AwakenMaterialsByGroupId map[int32][]WeaponAwakenMaterialGroupRow 140 164 } 141 165 142 166 func LoadWeaponCatalog(matCatalog *MaterialCatalog) (*WeaponCatalog, error) { ··· 199 223 return nil, fmt.Errorf("load weapon story release condition table: %w", err) 200 224 } 201 225 226 + awakenRows, err := utils.ReadJSON[WeaponAwakenRow]("EntityMWeaponAwakenTable.json") 227 + if err != nil { 228 + return nil, fmt.Errorf("load weapon awaken table: %w", err) 229 + } 230 + awakenMatRows, err := utils.ReadJSON[WeaponAwakenMaterialGroupRow]("EntityMWeaponAwakenMaterialGroupTable.json") 231 + if err != nil { 232 + return nil, fmt.Errorf("load weapon awaken material group table: %w", err) 233 + } 234 + 202 235 catalog := &WeaponCatalog{ 203 236 Weapons: make(map[int32]WeaponMasterRow, len(weapons)), 204 237 Materials: matCatalog.ByType[model.MaterialTypeWeaponEnhancement], ··· 225 258 LimitBreakCostByMaterialByEnhanceId: make(map[int32]NumericalFunc, len(enhanceRows)), 226 259 BaseExpByEnhanceId: make(map[int32]int32, len(enhanceRows)), 227 260 ReleaseConditionsByGroupId: make(map[int32][]WeaponStoryReleaseConditionRow), 261 + 262 + AwakenByWeaponId: make(map[int32]WeaponAwakenRow, len(awakenRows)), 263 + AwakenMaterialsByGroupId: make(map[int32][]WeaponAwakenMaterialGroupRow), 228 264 } 229 265 230 266 for _, w := range weapons { ··· 351 387 for _, c := range releaseConditions { 352 388 catalog.ReleaseConditionsByGroupId[c.WeaponStoryReleaseConditionGroupId] = append( 353 389 catalog.ReleaseConditionsByGroupId[c.WeaponStoryReleaseConditionGroupId], c) 390 + } 391 + 392 + for _, row := range awakenRows { 393 + catalog.AwakenByWeaponId[row.WeaponId] = row 394 + } 395 + for _, row := range awakenMatRows { 396 + catalog.AwakenMaterialsByGroupId[row.WeaponAwakenMaterialGroupId] = append( 397 + catalog.AwakenMaterialsByGroupId[row.WeaponAwakenMaterialGroupId], row) 354 398 } 355 399 356 400 // Rarity-based enhancement fallback: for weapons with WeaponSpecificEnhanceId == 0,
+8
server/internal/model/status.go
··· 21 21 CostumeAwakenEffectTypeAbility CostumeAwakenEffectType = 2 22 22 CostumeAwakenEffectTypeItemAcquire CostumeAwakenEffectType = 3 23 23 ) 24 + 25 + type WeaponAwakenEffectType int32 26 + 27 + const ( 28 + WeaponAwakenEffectTypeUnknown WeaponAwakenEffectType = 0 29 + WeaponAwakenEffectTypeStatusUp WeaponAwakenEffectType = 1 30 + WeaponAwakenEffectTypeAbility WeaponAwakenEffectType = 2 31 + )
+78 -4
server/internal/service/weapon.go
··· 18 18 "IUserWeapon", 19 19 "IUserWeaponSkill", 20 20 "IUserWeaponAbility", 21 + "IUserWeaponAwaken", 21 22 "IUserMaterial", 22 23 "IUserConsumableItem", 23 24 } ··· 26 27 "IUserWeapon", 27 28 "IUserWeaponSkill", 28 29 "IUserWeaponAbility", 30 + "IUserWeaponAwaken", 29 31 "IUserMaterial", 30 32 "IUserConsumableItem", 31 33 "IUserWeaponNote", 34 + } 35 + 36 + var weaponAwakenDiffTables = []string{ 37 + "IUserWeapon", 38 + "IUserWeaponAwaken", 39 + "IUserMaterial", 40 + "IUserConsumableItem", 32 41 } 33 42 34 43 type WeaponServiceServer struct { ··· 176 185 tracker := userdata.NewDeleteTracker(). 177 186 Track("IUserWeapon", oldUser, userdata.SortedWeaponRecords, []string{"userId", "userWeaponUuid"}). 178 187 Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}). 179 - Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"}) 188 + Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"}). 189 + Track("IUserWeaponAwaken", oldUser, userdata.SortedWeaponAwakenRecords, []string{"userId", "userWeaponUuid"}) 180 190 181 191 snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) { 182 192 totalGold := int32(0) ··· 206 216 delete(user.Weapons, uuid) 207 217 delete(user.WeaponSkills, uuid) 208 218 delete(user.WeaponAbilities, uuid) 219 + delete(user.WeaponAwakens, uuid) 209 220 } 210 221 211 222 if totalGold > 0 { ··· 217 228 return nil, fmt.Errorf("weapon sell: %w", err) 218 229 } 219 230 220 - sellDiffTables := []string{"IUserWeapon", "IUserWeaponSkill", "IUserWeaponAbility", "IUserConsumableItem"} 231 + sellDiffTables := []string{"IUserWeapon", "IUserWeaponSkill", "IUserWeaponAbility", "IUserWeaponAwaken", "IUserConsumableItem"} 221 232 tables := userdata.SelectTables(userdata.FullClientTableMap(snapshot), sellDiffTables) 222 233 diff := tracker.Apply(snapshot, tables) 223 234 ··· 583 594 tracker := userdata.NewDeleteTracker(). 584 595 Track("IUserWeapon", oldUser, userdata.SortedWeaponRecords, []string{"userId", "userWeaponUuid"}). 585 596 Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}). 586 - Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"}) 597 + Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"}). 598 + Track("IUserWeaponAwaken", oldUser, userdata.SortedWeaponAwakenRecords, []string{"userId", "userWeaponUuid"}) 587 599 588 600 snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) { 589 601 weapon, ok := user.Weapons[req.UserWeaponUuid] ··· 626 638 delete(user.Weapons, uuid) 627 639 delete(user.WeaponSkills, uuid) 628 640 delete(user.WeaponAbilities, uuid) 641 + delete(user.WeaponAwakens, uuid) 629 642 consumedCount++ 630 643 } 631 644 ··· 668 681 tracker := userdata.NewDeleteTracker(). 669 682 Track("IUserWeapon", oldUser, userdata.SortedWeaponRecords, []string{"userId", "userWeaponUuid"}). 670 683 Track("IUserWeaponSkill", oldUser, userdata.SortedWeaponSkillRecords, []string{"userId", "userWeaponUuid", "slotNumber"}). 671 - Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"}) 684 + Track("IUserWeaponAbility", oldUser, userdata.SortedWeaponAbilityRecords, []string{"userId", "userWeaponUuid", "slotNumber"}). 685 + Track("IUserWeaponAwaken", oldUser, userdata.SortedWeaponAwakenRecords, []string{"userId", "userWeaponUuid"}) 672 686 673 687 var changedStoryIds []int32 674 688 snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) { ··· 714 728 delete(user.Weapons, uuid) 715 729 delete(user.WeaponSkills, uuid) 716 730 delete(user.WeaponAbilities, uuid) 731 + delete(user.WeaponAwakens, uuid) 717 732 consumedCount++ 718 733 } 719 734 ··· 795 810 } 796 811 return nil 797 812 } 813 + 814 + func (s *WeaponServiceServer) Awaken(ctx context.Context, req *pb.WeaponAwakenRequest) (*pb.WeaponAwakenResponse, error) { 815 + log.Printf("[WeaponService] Awaken: uuid=%s", req.UserWeaponUuid) 816 + 817 + userId := currentUserId(ctx, s.users, s.sessions) 818 + nowMillis := gametime.NowMillis() 819 + 820 + snapshot, err := s.users.UpdateUser(userId, func(user *store.UserState) { 821 + weapon, ok := user.Weapons[req.UserWeaponUuid] 822 + if !ok { 823 + log.Printf("[WeaponService] Awaken: weapon uuid=%s not found", req.UserWeaponUuid) 824 + return 825 + } 826 + 827 + awakenRow, ok := s.catalog.AwakenByWeaponId[weapon.WeaponId] 828 + if !ok { 829 + log.Printf("[WeaponService] Awaken: no awaken data for weaponId=%d", weapon.WeaponId) 830 + return 831 + } 832 + 833 + if _, already := user.WeaponAwakens[req.UserWeaponUuid]; already { 834 + log.Printf("[WeaponService] Awaken: weapon uuid=%s already awakened", req.UserWeaponUuid) 835 + return 836 + } 837 + 838 + mats := s.catalog.AwakenMaterialsByGroupId[awakenRow.WeaponAwakenMaterialGroupId] 839 + for _, mat := range mats { 840 + cur := user.Materials[mat.MaterialId] 841 + cost := mat.Count 842 + if cur < cost { 843 + log.Printf("[WeaponService] Awaken: insufficient material id=%d have=%d need=%d", mat.MaterialId, cur, cost) 844 + cost = cur 845 + } 846 + user.Materials[mat.MaterialId] = cur - cost 847 + } 848 + 849 + if awakenRow.ConsumeGold > 0 { 850 + user.ConsumableItems[s.config.ConsumableItemIdForGold] -= awakenRow.ConsumeGold 851 + log.Printf("[WeaponService] Awaken: gold cost=%d", awakenRow.ConsumeGold) 852 + } 853 + 854 + user.WeaponAwakens[req.UserWeaponUuid] = store.WeaponAwakenState{ 855 + UserWeaponUuid: req.UserWeaponUuid, 856 + LatestVersion: nowMillis, 857 + } 858 + 859 + weapon.LatestVersion = nowMillis 860 + user.Weapons[req.UserWeaponUuid] = weapon 861 + log.Printf("[WeaponService] Awaken: weaponId=%d awakened", weapon.WeaponId) 862 + }) 863 + if err != nil { 864 + return nil, fmt.Errorf("weapon awaken: %w", err) 865 + } 866 + 867 + tables := userdata.FullClientTableMap(snapshot) 868 + diff := userdata.BuildDiffFromTables(userdata.SelectTables(tables, weaponAwakenDiffTables)) 869 + 870 + return &pb.WeaponAwakenResponse{DiffUserData: diff}, nil 871 + }
+9
server/internal/store/types.go
··· 83 83 CostumeActiveSkills map[string]CostumeActiveSkillState 84 84 WeaponSkills map[string][]WeaponSkillState // key: userWeaponUuid 85 85 WeaponAbilities map[string][]WeaponAbilityState // key: userWeaponUuid 86 + WeaponAwakens map[string]WeaponAwakenState // key: userWeaponUuid 86 87 DeckTypeNotes map[model.DeckType]DeckTypeNoteState 87 88 WeaponNotes map[int32]WeaponNoteState 88 89 DeckSubWeapons map[string][]string ··· 204 205 } 205 206 if u.WeaponAbilities == nil { 206 207 u.WeaponAbilities = make(map[string][]WeaponAbilityState) 208 + } 209 + if u.WeaponAwakens == nil { 210 + u.WeaponAwakens = make(map[string]WeaponAwakenState) 207 211 } 208 212 if u.DeckTypeNotes == nil { 209 213 u.DeckTypeNotes = make(map[model.DeckType]DeckTypeNoteState) ··· 460 464 UserWeaponUuid string 461 465 SlotNumber int32 462 466 Level int32 467 + } 468 + 469 + type WeaponAwakenState struct { 470 + UserWeaponUuid string 471 + LatestVersion int64 463 472 } 464 473 465 474 type DeckTypeNoteState struct {
+18 -1
server/internal/userdata/proj_inventory.go
··· 101 101 s, _ := encodeJSONMaps(sortedCageOrnamentRewardRecords(user)...) 102 102 return s 103 103 }) 104 + register("IUserWeaponAwaken", func(user store.UserState) string { 105 + s, _ := encodeJSONMaps(SortedWeaponAwakenRecords(user)...) 106 + return s 107 + }) 104 108 registerStatic( 105 109 "IUserCostumeLevelBonusReleaseStatus", 106 110 "IUserCostumeLotteryEffect", 107 111 "IUserCostumeLotteryEffectAbility", 108 112 "IUserCostumeLotteryEffectStatusUp", 109 113 "IUserCostumeLotteryEffectPending", 110 - "IUserWeaponAwaken", 111 114 "IUserPartsPresetTag", 112 115 "IUserPartsStatusSub", 113 116 ) ··· 528 531 "latestVersion": int64(0), 529 532 }) 530 533 } 534 + } 535 + return records 536 + } 537 + 538 + func SortedWeaponAwakenRecords(user store.UserState) []map[string]any { 539 + keys := sortedStringKeys(user.WeaponAwakens) 540 + records := make([]map[string]any, 0, len(keys)) 541 + for _, key := range keys { 542 + row := user.WeaponAwakens[key] 543 + records = append(records, map[string]any{ 544 + "userId": user.UserId, 545 + "userWeaponUuid": row.UserWeaponUuid, 546 + "latestVersion": row.LatestVersion, 547 + }) 531 548 } 532 549 return records 533 550 }