Files
GaCy-GO/internal/gameserver/currency_wars_investment.go
T

123 lines
4.0 KiB
Go

package gameserver
import (
"encoding/json"
"fmt"
"gac-hkrpg-go/internal/common"
pb "gac-hkrpg-go/protocol/proto"
"google.golang.org/protobuf/proto"
"math"
)
func cwSelectInvestment(catalog *common.CurrencyWarsCatalog, run *pb.MPIMAEMCEFH, id uint32) (*pb.GridFightSyncUpdateResultScNotify, error) {
pending := run.FMIGOKIDKJL
if pending == nil || pending.GetIBCHMBNIPLK() == nil {
return nil, fmt.Errorf("CW investment not pending")
}
offered := false
for _, v := range pending.GetIBCHMBNIPLK().CEBFFDFMKGK {
offered = offered || v.AugmentId == id
}
if !offered || id == 0 {
return nil, fmt.Errorf("CW investment not offered")
}
raw, err := common.ReadResourceFile("resources/CurrencyWarsInvestmentChoices.json")
if err != nil {
return nil, err
}
var resource struct {
Format uint32 `json:"format_version"`
Client string `json:"target_client_version"`
Assembly string `json:"target_assembly_sha256"`
Choices []struct {
ID uint32 `json:"augment_id"`
GoldDelta int64 `json:"gold_delta"`
Info []byte `json:"augment_info_wire"`
} `json:"choices"`
}
if err = json.Unmarshal(raw, &resource); err != nil {
return nil, err
}
if resource.Format != 1 || resource.Client != catalog.ClientVersion || resource.Assembly != catalog.Provenance.GameAssemblySHA256 {
return nil, fmt.Errorf("CW investment resource revision differs")
}
player, _, _ := cwComponents(run)
if player == nil {
return nil, fmt.Errorf("CW player missing")
}
var augments *pb.KGFNICBCMOA
for _, c := range run.NAGDJGMMCBE {
if v := c.GetLLDBOIANGDN(); v != nil {
augments = v
}
}
if augments == nil {
return nil, fmt.Errorf("CW investment container missing")
}
for _, v := range augments.SyncAugmentInfo {
if v.AugmentId == id {
return nil, fmt.Errorf("CW investment already owned")
}
}
var info *pb.PPGEBEBPMJC
var delta int64
for _, choice := range resource.Choices {
if choice.ID == id {
if info != nil {
return nil, fmt.Errorf("CW investment outcome duplicated")
}
info = new(pb.PPGEBEBPMJC)
if err = proto.Unmarshal(choice.Info, info); err != nil {
return nil, err
}
delta = choice.GoldDelta
}
}
if info == nil || info.AugmentId != id {
augCatalog, augErr := common.LoadCurrencyWarsAugments(catalog)
if augErr == nil {
if aug, ok := augCatalog.Augment(id); ok {
info = &pb.PPGEBEBPMJC{AugmentId: id}
for _, g := range aug.Grants {
if g.Kind == "gold" {
delta += int64(g.Count)
}
}
}
}
}
if info == nil || info.AugmentId != id {
return nil, fmt.Errorf("CW investment effect not captured")
}
if delta < 0 {
cost := uint64(-(delta + 1)) + 1
if cost > uint64(player.Gold) {
return nil, fmt.Errorf("CW investment gold insufficient")
}
player.Gold -= uint32(cost)
} else {
total := uint64(player.Gold) + uint64(delta)
if total > math.MaxUint32 {
total = math.MaxUint32
}
player.Gold = uint32(total)
}
if pending.QueuePosition == math.MaxUint32 {
return nil, fmt.Errorf("CW pending queue exhausted")
}
next := &pb.CHCHAJIANIM{QueuePosition: pending.QueuePosition + 1, FGLIODAJFML: &pb.CHCHAJIANIM_LGNPHHBGKFH{LGNPHHBGKFH: &pb.HJPDALHDJHC{}}}
augments.SyncAugmentInfo = append(augments.SyncAugmentInfo, info)
run.FMIGOKIDKJL = next
notify := cwNotify(&pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_EIKHFBCKIFA{EIKHFBCKIFA: &pb.OMINPDAIBLP{MCPIKEHDMND: info}}})
notify.GCPNIHHBGGD[0].GridUpdateSrc = pb.JJDFGMMMCMI_JJDFGMMMCMI_EJLJOJFECPM
if delta != 0 {
gold := cwNotify(cwGoldSync(player.Gold)).GCPNIHHBGGD[0]
gold.OOEOCGLLHFO = []uint32{id}
gold.GridUpdateSrc = pb.JJDFGMMMCMI_JJDFGMMMCMI_ANMFPKDFICD
notify.GCPNIHHBGGD = append([]*pb.ABPLALCHNFA{gold}, notify.GCPNIHHBGGD...)
}
notify.GCPNIHHBGGD = append(notify.GCPNIHHBGGD, cwNotify(cwFinish(pending.QueuePosition), cwUnlock()).GCPNIHHBGGD...)
notify.GCPNIHHBGGD = append(notify.GCPNIHHBGGD, cwNotify(&pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_JOMFJHOCHJP{JOMFJHOCHJP: player.GAJGBBFELEL}}, &pb.KFNCAIHIHCM{MNLCHEJKDHO: &pb.KFNCAIHIHCM_FMIGOKIDKJL{FMIGOKIDKJL: next}}).GCPNIHHBGGD...)
return notify, nil
}