From 7800553e0925de7e12b13303cfedf329978ec198 Mon Sep 17 00:00:00 2001 From: 6000j Date: Sun, 27 Oct 2024 14:24:39 +1100 Subject: [PATCH 1/7] Poised to Bloom initial implementation --- .../lightcone/harmony/poisedtobloom/data.go | 71 +++++++++++++++++ .../harmony/poisedtobloom/poisedtobloom.go | 77 +++++++++++++++++++ pkg/key/lightcone.go | 1 + pkg/model/character.pb.go | 16 ++-- pkg/model/enemy.pb.go | 50 ++++++------ pkg/model/enum.pb.go | 6 +- pkg/model/result.pb.go | 26 +++---- pkg/model/sim.pb.go | 16 ++-- pkg/simulation/imports.go | 1 + .../lightcone/poised_to_bloom_test.go | 63 +++++++++++++++ tests/testcfg/testchar/bronya.go | 27 +++++++ tests/testcfg/testcone/dance_dance_dance.go | 15 ++++ tests/testcfg/testcone/poised_to_bloom.go | 15 ++++ 13 files changed, 327 insertions(+), 57 deletions(-) create mode 100644 internal/lightcone/harmony/poisedtobloom/data.go create mode 100644 internal/lightcone/harmony/poisedtobloom/poisedtobloom.go create mode 100644 tests/testcase/lightcone/poised_to_bloom_test.go create mode 100644 tests/testcfg/testchar/bronya.go create mode 100644 tests/testcfg/testcone/dance_dance_dance.go create mode 100644 tests/testcfg/testcone/poised_to_bloom.go diff --git a/internal/lightcone/harmony/poisedtobloom/data.go b/internal/lightcone/harmony/poisedtobloom/data.go new file mode 100644 index 00000000..3ef078a0 --- /dev/null +++ b/internal/lightcone/harmony/poisedtobloom/data.go @@ -0,0 +1,71 @@ +// Code generated by "weapstat"; DO NOT EDIT. + +package poisedtobloom + +import "github.com/simimpact/srsim/pkg/engine/equip/lightcone" + +var promotions = []lightcone.PromotionData{ + { + MaxLevel: 20, + HPBase: 43.20, + HPAdd: 6.48, + ATKBase: 19.20, + ATKAdd: 2.88, + DEFBase: 18, + DEFAdd: 2.70, + }, + { + MaxLevel: 30, + HPBase: 95.04, + HPAdd: 6.48, + ATKBase: 42.24, + ATKAdd: 2.88, + DEFBase: 39.60, + DEFAdd: 2.70, + }, + { + MaxLevel: 40, + HPBase: 164.16, + HPAdd: 6.48, + ATKBase: 72.96, + ATKAdd: 2.88, + DEFBase: 68.40, + DEFAdd: 2.70, + }, + { + MaxLevel: 50, + HPBase: 233.28, + HPAdd: 6.48, + ATKBase: 103.68, + ATKAdd: 2.88, + DEFBase: 97.20, + DEFAdd: 2.70, + }, + { + MaxLevel: 60, + HPBase: 302.40, + HPAdd: 6.48, + ATKBase: 134.40, + ATKAdd: 2.88, + DEFBase: 126, + DEFAdd: 2.70, + }, + { + MaxLevel: 70, + HPBase: 371.52, + HPAdd: 6.48, + ATKBase: 165.12, + ATKAdd: 2.88, + DEFBase: 154.80, + DEFAdd: 2.70, + }, + { + MaxLevel: 80, + HPBase: 440.64, + HPAdd: 6.48, + ATKBase: 195.84, + ATKAdd: 2.88, + DEFBase: 183.60, + DEFAdd: 2.70, + }, +} \ No newline at end of file diff --git a/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go new file mode 100644 index 00000000..1e731f97 --- /dev/null +++ b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go @@ -0,0 +1,77 @@ +package poisedtobloom + +import ( + "github.com/simimpact/srsim/pkg/engine" + "github.com/simimpact/srsim/pkg/engine/equip/lightcone" + "github.com/simimpact/srsim/pkg/engine/event" + "github.com/simimpact/srsim/pkg/engine/info" + "github.com/simimpact/srsim/pkg/engine/modifier" + "github.com/simimpact/srsim/pkg/engine/prop" + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +const ( + poised key.Modifier = "poised-to-bloom" + poisedCritDmg key.Modifier = "poised-to-bloom-crit-dmg" +) + +// Lose Not, Forget Not +// Increases the wearer's ATK by 16/20/24/28/32%. Upon entering battle, +// if two or more characters follow the same Path, +// then these characters' CRIT DMG increases by 16/20/24/28/32%. +// Abilities of the same type cannot stack. + +func init() { + lightcone.Register(key.PoisedToBloom, lightcone.Config{ + CreatePassive: Create, + Rarity: 4, + Path: model.Path_HARMONY, + Promotions: promotions, + }) + + modifier.Register(poised, modifier.Config{}) + + modifier.Register(poisedCritDmg, modifier.Config{ + Stacking: modifier.Replace, + }) +} + +func Create(engine engine.Engine, owner key.TargetID, lc info.LightCone) { + atkAmt := 0.12 + 0.04*float64(lc.Imposition) + critDmgAmt := 0.12 + 0.04*float64(lc.Imposition) + + engine.AddModifier(owner, info.Modifier{ + Name: poised, + Source: owner, + Stats: info.PropMap{prop.ATKPercent: atkAmt}, + }) + + engine.Events().BattleStart.Subscribe(func(event event.BattleStart) { + // This is probably slow, but I can't think of other good ways to iterate + // and store paths that don't involve allocating memory + // that might not be used, which I suspect would be slower + // It's still only called once per iteration though, so it should + // be fine. + + // Iterating over all the characters + for _, charA := range engine.Characters() { + charAInfo, _ := engine.CharacterInfo(charA) + // Checking for pairs with them + for _, charB := range engine.Characters() { + charBInfo, _ := engine.CharacterInfo(charB) + // If there's a pair, we apply the crit dmg buff to charA + // we could also apply it to charB, but with no way to remove + // them from the future iterations, that would actually be slower + if charB != charA && charAInfo.Path == charBInfo.Path { + engine.AddModifier(charA, info.Modifier{ + Name: poisedCritDmg, + Source: owner, + Stats: info.PropMap{prop.CritDMG: critDmgAmt}, + }) + break + } + } + } + }) +} diff --git a/pkg/key/lightcone.go b/pkg/key/lightcone.go index c0aa3ceb..1e4ac448 100644 --- a/pkg/key/lightcone.go +++ b/pkg/key/lightcone.go @@ -73,6 +73,7 @@ const ( MemoriesofthePast LightCone = "memories_of_the_past" DanceDanceDance LightCone = "dance_dance_dance" PlanetaryRendezvous LightCone = "planetary_rendezvous" + PoisedToBloom LightCone = "poised_to_bloom" ) // Preservation diff --git a/pkg/model/character.pb.go b/pkg/model/character.pb.go index b12e7a47..66d8c4de 100644 --- a/pkg/model/character.pb.go +++ b/pkg/model/character.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/character.proto package model @@ -470,7 +470,7 @@ func file_pb_model_character_proto_rawDescGZIP() []byte { } var file_pb_model_character_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_pb_model_character_proto_goTypes = []any{ +var file_pb_model_character_proto_goTypes = []interface{}{ (*Character)(nil), // 0: model.Character (*Abilities)(nil), // 1: model.Abilities (*LightCone)(nil), // 2: model.LightCone @@ -499,7 +499,7 @@ func file_pb_model_character_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_character_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Character); i { case 0: return &v.state @@ -511,7 +511,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Abilities); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LightCone); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Relic); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[4].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RelicStat); i { case 0: return &v.state diff --git a/pkg/model/enemy.pb.go b/pkg/model/enemy.pb.go index 67fd596b..c2f4ac6b 100644 --- a/pkg/model/enemy.pb.go +++ b/pkg/model/enemy.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/enemy.proto package model import ( + _struct "github.com/golang/protobuf/ptypes/struct" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" ) @@ -81,14 +81,14 @@ type Enemy struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` - Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` - DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` - DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` - Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` - BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` - Parameters *structpb.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` + Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` + DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` + DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` + Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` + BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` + Parameters *_struct.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` } func (x *Enemy) Reset() { @@ -172,7 +172,7 @@ func (x *Enemy) GetBaseStats() *BaseStats { return nil } -func (x *Enemy) GetParameters() *structpb.Struct { +func (x *Enemy) GetParameters() *_struct.Struct { if x != nil { return x.Parameters } @@ -478,15 +478,15 @@ func file_pb_model_enemy_proto_rawDescGZIP() []byte { var file_pb_model_enemy_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_pb_model_enemy_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_enemy_proto_goTypes = []any{ - (EnemyRank)(0), // 0: model.EnemyRank - (*Enemy)(nil), // 1: model.Enemy - (*DebuffRES)(nil), // 2: model.DebuffRES - (*DamageRES)(nil), // 3: model.DamageRES - (*BaseStats)(nil), // 4: model.BaseStats - (DamageType)(0), // 5: model.DamageType - (*structpb.Struct)(nil), // 6: google.protobuf.Struct - (BehaviorFlag)(0), // 7: model.BehaviorFlag +var file_pb_model_enemy_proto_goTypes = []interface{}{ + (EnemyRank)(0), // 0: model.EnemyRank + (*Enemy)(nil), // 1: model.Enemy + (*DebuffRES)(nil), // 2: model.DebuffRES + (*DamageRES)(nil), // 3: model.DamageRES + (*BaseStats)(nil), // 4: model.BaseStats + (DamageType)(0), // 5: model.DamageType + (*_struct.Struct)(nil), // 6: google.protobuf.Struct + (BehaviorFlag)(0), // 7: model.BehaviorFlag } var file_pb_model_enemy_proto_depIdxs = []int32{ 5, // 0: model.Enemy.weaknesses:type_name -> model.DamageType @@ -511,7 +511,7 @@ func file_pb_model_enemy_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Enemy); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DebuffRES); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DamageRES); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BaseStats); i { case 0: return &v.state diff --git a/pkg/model/enum.pb.go b/pkg/model/enum.pb.go index c40271be..b6f735c0 100644 --- a/pkg/model/enum.pb.go +++ b/pkg/model/enum.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/enum.proto package model @@ -1218,7 +1218,7 @@ func file_pb_model_enum_proto_rawDescGZIP() []byte { } var file_pb_model_enum_proto_enumTypes = make([]protoimpl.EnumInfo, 13) -var file_pb_model_enum_proto_goTypes = []any{ +var file_pb_model_enum_proto_goTypes = []interface{}{ (Property)(0), // 0: model.Property (BehaviorFlag)(0), // 1: model.BehaviorFlag (StatusType)(0), // 2: model.StatusType diff --git a/pkg/model/result.pb.go b/pkg/model/result.pb.go index 1e2a9f3b..d6f837d4 100644 --- a/pkg/model/result.pb.go +++ b/pkg/model/result.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/result.proto package model @@ -651,7 +651,7 @@ func file_pb_model_result_proto_rawDescGZIP() []byte { } var file_pb_model_result_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_pb_model_result_proto_goTypes = []any{ +var file_pb_model_result_proto_goTypes = []interface{}{ (*Version)(nil), // 0: model.Version (*SimResult)(nil), // 1: model.SimResult (*Statistics)(nil), // 2: model.Statistics @@ -684,7 +684,7 @@ func file_pb_model_result_proto_init() { } file_pb_model_sim_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_result_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Version); i { case 0: return &v.state @@ -696,7 +696,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SimResult); i { case 0: return &v.state @@ -708,7 +708,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Statistics); i { case 0: return &v.state @@ -720,7 +720,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*IterationResult); i { case 0: return &v.state @@ -732,7 +732,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[4].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OverviewStats); i { case 0: return &v.state @@ -744,7 +744,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[5].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DescriptiveStats); i { case 0: return &v.state @@ -757,10 +757,10 @@ func file_pb_model_result_proto_init() { } } } - file_pb_model_result_proto_msgTypes[1].OneofWrappers = []any{} - file_pb_model_result_proto_msgTypes[2].OneofWrappers = []any{} - file_pb_model_result_proto_msgTypes[4].OneofWrappers = []any{} - file_pb_model_result_proto_msgTypes[5].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[1].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[5].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/model/sim.pb.go b/pkg/model/sim.pb.go index fc1b74ec..a8b849f1 100644 --- a/pkg/model/sim.pb.go +++ b/pkg/model/sim.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/sim.proto package model @@ -320,7 +320,7 @@ func file_pb_model_sim_proto_rawDescGZIP() []byte { } var file_pb_model_sim_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_sim_proto_goTypes = []any{ +var file_pb_model_sim_proto_goTypes = []interface{}{ (*SimConfig)(nil), // 0: model.SimConfig (*SimulatorSettings)(nil), // 1: model.SimulatorSettings (*Wave)(nil), // 2: model.Wave @@ -349,7 +349,7 @@ func file_pb_model_sim_proto_init() { file_pb_model_enemy_proto_init() file_pb_model_character_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_sim_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SimConfig); i { case 0: return &v.state @@ -361,7 +361,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SimulatorSettings); i { case 0: return &v.state @@ -373,7 +373,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Wave); i { case 0: return &v.state @@ -385,7 +385,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Engage); i { case 0: return &v.state @@ -398,7 +398,7 @@ func file_pb_model_sim_proto_init() { } } } - file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []any{ + file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []interface{}{ (*SimConfig_Gcsl)(nil), } type x struct{} diff --git a/pkg/simulation/imports.go b/pkg/simulation/imports.go index dd758b1c..78124c71 100644 --- a/pkg/simulation/imports.go +++ b/pkg/simulation/imports.go @@ -71,6 +71,7 @@ import ( _ "github.com/simimpact/srsim/internal/lightcone/harmony/memoriesofthepast" _ "github.com/simimpact/srsim/internal/lightcone/harmony/meshingcogs" _ "github.com/simimpact/srsim/internal/lightcone/harmony/planetaryrendezvous" + _ "github.com/simimpact/srsim/internal/lightcone/harmony/poisedtobloom" _ "github.com/simimpact/srsim/internal/lightcone/hunt/adversarial" _ "github.com/simimpact/srsim/internal/lightcone/hunt/arrows" _ "github.com/simimpact/srsim/internal/lightcone/hunt/cruisinginthestellarsea" diff --git a/tests/testcase/lightcone/poised_to_bloom_test.go b/tests/testcase/lightcone/poised_to_bloom_test.go new file mode 100644 index 00000000..976fefbb --- /dev/null +++ b/tests/testcase/lightcone/poised_to_bloom_test.go @@ -0,0 +1,63 @@ +package lightcone + +import ( + "testing" + + "github.com/simimpact/srsim/pkg/engine/prop" + "github.com/simimpact/srsim/tests/testcfg/testchar" + "github.com/simimpact/srsim/tests/testcfg/testcone" + "github.com/simimpact/srsim/tests/teststub" + "github.com/stretchr/testify/suite" +) + +type PTBTest struct { + teststub.Stub +} + +func TestPTBTest(t *testing.T) { + suite.Run(t, new(PTBTest)) +} + +// Testing that PTB indeed does add the correct ATK amount +func (t *PTBTest) Test_AtkAdd() { + bronyaModel := testchar.Bronya() + bronyaModel.LightCone = testcone.PoisedToBloom() + t.Characters.ResetCharacters() + bronya := t.Characters.AddCharacter(bronyaModel) + t.StartSimulation() + // She should have no other atk buffs from anywhere + bronya.Equal(prop.ATKPercent, 0.16) +} + +// Testing that PTB adds crit damage to only characters who share a path with another character in the party +func (t *PTBTest) Test_CritDMG() { + bronyaModel := testchar.Bronya() + bronyaModel.LightCone = testcone.PoisedToBloom() + t.Characters.ResetCharacters() + bronya := t.Characters.AddCharacter(bronyaModel) + dan1 := t.Characters.AddCharacter(testchar.DanHung()) + dan2 := t.Characters.AddCharacter(testchar.DanHung()) + t.StartSimulation() + // 0.50 from base crit damage + 0.16 from poised buff + dan1.Equal(prop.CritDMG, 0.66) + dan2.Equal(prop.CritDMG, 0.66) + // Just the 0.50 base crit damage + bronya.Equal(prop.CritDMG, 0.50) +} + +// Testing that PTB adds crit damage to only characters who share a path with another character in the party +func (t *PTBTest) Test_No_Stacking() { + // I'm a bit concerned about using the same character twice, but hopefully all should be good? + bronyaModel1 := testchar.Bronya() + bronyaModel1.LightCone = testcone.PoisedToBloom() + bronyaModel2 := testchar.Bronya() + bronyaModel2.LightCone = testcone.PoisedToBloom() + t.Characters.ResetCharacters() + bronya1 := t.Characters.AddCharacter(bronyaModel1) + bronya2 := t.Characters.AddCharacter(bronyaModel2) + + t.StartSimulation() + // 0.50 from base crit damage + 0.16 from poised buff + bronya1.Equal(prop.CritDMG, 0.66) + bronya2.Equal(prop.CritDMG, 0.66) +} diff --git a/tests/testcfg/testchar/bronya.go b/tests/testcfg/testchar/bronya.go new file mode 100644 index 00000000..0ff847f4 --- /dev/null +++ b/tests/testcfg/testchar/bronya.go @@ -0,0 +1,27 @@ +package testchar + +import ( + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" + "github.com/simimpact/srsim/tests/testcfg/testcone" +) + +func Bronya() *model.Character { + return &model.Character{ + Key: key.Bronya.String(), + Level: 80, + MaxLevel: 80, + Eidols: 0, + Traces: nil, + Abilities: &model.Abilities{ + Attack: 1, + Skill: 1, + Ult: 1, + Talent: 1, + }, + LightCone: testcone.DanceDanceDance(), + Relics: nil, + StartHp: 0, + StartEnergy: 0, + } +} diff --git a/tests/testcfg/testcone/dance_dance_dance.go b/tests/testcfg/testcone/dance_dance_dance.go new file mode 100644 index 00000000..a6dfc238 --- /dev/null +++ b/tests/testcfg/testcone/dance_dance_dance.go @@ -0,0 +1,15 @@ +package testcone + +import ( + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +func DanceDanceDance() *model.LightCone { + return &model.LightCone{ + Key: key.DanceDanceDance.String(), + Level: 80, + MaxLevel: 80, + Imposition: 1, + } +} diff --git a/tests/testcfg/testcone/poised_to_bloom.go b/tests/testcfg/testcone/poised_to_bloom.go new file mode 100644 index 00000000..bf331ced --- /dev/null +++ b/tests/testcfg/testcone/poised_to_bloom.go @@ -0,0 +1,15 @@ +package testcone + +import ( + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +func PoisedToBloom() *model.LightCone { + return &model.LightCone{ + Key: key.PoisedToBloom.String(), + Level: 80, + MaxLevel: 80, + Imposition: 1, + } +} From 6645c0353bf27a0ad9ea2ecd47390131d149827d Mon Sep 17 00:00:00 2001 From: 6000j Date: Sun, 27 Oct 2024 15:47:15 +1100 Subject: [PATCH 2/7] corrected stacking type --- internal/lightcone/harmony/poisedtobloom/poisedtobloom.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go index 1e731f97..9566a994 100644 --- a/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go +++ b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go @@ -33,7 +33,7 @@ func init() { modifier.Register(poised, modifier.Config{}) modifier.Register(poisedCritDmg, modifier.Config{ - Stacking: modifier.Replace, + Stacking: modifier.Unique, }) } From b75fb0196a7a01808544c429b195b65e8b1f14da Mon Sep 17 00:00:00 2001 From: 6000j Date: Sun, 27 Oct 2024 20:53:49 +1100 Subject: [PATCH 3/7] reverting unneeded changes to generated files due to mismatched protoc versions --- pkg/model/character.pb.go | 16 ++++++------- pkg/model/enemy.pb.go | 50 +++++++++++++++++++-------------------- pkg/model/enum.pb.go | 6 ++--- pkg/model/result.pb.go | 26 ++++++++++---------- pkg/model/sim.pb.go | 16 ++++++------- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/pkg/model/character.pb.go b/pkg/model/character.pb.go index 66d8c4de..b12e7a47 100644 --- a/pkg/model/character.pb.go +++ b/pkg/model/character.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/character.proto package model @@ -470,7 +470,7 @@ func file_pb_model_character_proto_rawDescGZIP() []byte { } var file_pb_model_character_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_pb_model_character_proto_goTypes = []interface{}{ +var file_pb_model_character_proto_goTypes = []any{ (*Character)(nil), // 0: model.Character (*Abilities)(nil), // 1: model.Abilities (*LightCone)(nil), // 2: model.LightCone @@ -499,7 +499,7 @@ func file_pb_model_character_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_character_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Character); i { case 0: return &v.state @@ -511,7 +511,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*Abilities); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*LightCone); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*Relic); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*RelicStat); i { case 0: return &v.state diff --git a/pkg/model/enemy.pb.go b/pkg/model/enemy.pb.go index c2f4ac6b..67fd596b 100644 --- a/pkg/model/enemy.pb.go +++ b/pkg/model/enemy.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/enemy.proto package model import ( - _struct "github.com/golang/protobuf/ptypes/struct" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" ) @@ -81,14 +81,14 @@ type Enemy struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` - Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` - DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` - DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` - Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` - BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` - Parameters *_struct.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` + Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` + DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` + DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` + Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` + BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` + Parameters *structpb.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` } func (x *Enemy) Reset() { @@ -172,7 +172,7 @@ func (x *Enemy) GetBaseStats() *BaseStats { return nil } -func (x *Enemy) GetParameters() *_struct.Struct { +func (x *Enemy) GetParameters() *structpb.Struct { if x != nil { return x.Parameters } @@ -478,15 +478,15 @@ func file_pb_model_enemy_proto_rawDescGZIP() []byte { var file_pb_model_enemy_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_pb_model_enemy_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_enemy_proto_goTypes = []interface{}{ - (EnemyRank)(0), // 0: model.EnemyRank - (*Enemy)(nil), // 1: model.Enemy - (*DebuffRES)(nil), // 2: model.DebuffRES - (*DamageRES)(nil), // 3: model.DamageRES - (*BaseStats)(nil), // 4: model.BaseStats - (DamageType)(0), // 5: model.DamageType - (*_struct.Struct)(nil), // 6: google.protobuf.Struct - (BehaviorFlag)(0), // 7: model.BehaviorFlag +var file_pb_model_enemy_proto_goTypes = []any{ + (EnemyRank)(0), // 0: model.EnemyRank + (*Enemy)(nil), // 1: model.Enemy + (*DebuffRES)(nil), // 2: model.DebuffRES + (*DamageRES)(nil), // 3: model.DamageRES + (*BaseStats)(nil), // 4: model.BaseStats + (DamageType)(0), // 5: model.DamageType + (*structpb.Struct)(nil), // 6: google.protobuf.Struct + (BehaviorFlag)(0), // 7: model.BehaviorFlag } var file_pb_model_enemy_proto_depIdxs = []int32{ 5, // 0: model.Enemy.weaknesses:type_name -> model.DamageType @@ -511,7 +511,7 @@ func file_pb_model_enemy_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Enemy); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*DebuffRES); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*DamageRES); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*BaseStats); i { case 0: return &v.state diff --git a/pkg/model/enum.pb.go b/pkg/model/enum.pb.go index b6f735c0..c40271be 100644 --- a/pkg/model/enum.pb.go +++ b/pkg/model/enum.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/enum.proto package model @@ -1218,7 +1218,7 @@ func file_pb_model_enum_proto_rawDescGZIP() []byte { } var file_pb_model_enum_proto_enumTypes = make([]protoimpl.EnumInfo, 13) -var file_pb_model_enum_proto_goTypes = []interface{}{ +var file_pb_model_enum_proto_goTypes = []any{ (Property)(0), // 0: model.Property (BehaviorFlag)(0), // 1: model.BehaviorFlag (StatusType)(0), // 2: model.StatusType diff --git a/pkg/model/result.pb.go b/pkg/model/result.pb.go index d6f837d4..1e2a9f3b 100644 --- a/pkg/model/result.pb.go +++ b/pkg/model/result.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/result.proto package model @@ -651,7 +651,7 @@ func file_pb_model_result_proto_rawDescGZIP() []byte { } var file_pb_model_result_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_pb_model_result_proto_goTypes = []interface{}{ +var file_pb_model_result_proto_goTypes = []any{ (*Version)(nil), // 0: model.Version (*SimResult)(nil), // 1: model.SimResult (*Statistics)(nil), // 2: model.Statistics @@ -684,7 +684,7 @@ func file_pb_model_result_proto_init() { } file_pb_model_sim_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_result_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Version); i { case 0: return &v.state @@ -696,7 +696,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*SimResult); i { case 0: return &v.state @@ -708,7 +708,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*Statistics); i { case 0: return &v.state @@ -720,7 +720,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*IterationResult); i { case 0: return &v.state @@ -732,7 +732,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*OverviewStats); i { case 0: return &v.state @@ -744,7 +744,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*DescriptiveStats); i { case 0: return &v.state @@ -757,10 +757,10 @@ func file_pb_model_result_proto_init() { } } } - file_pb_model_result_proto_msgTypes[1].OneofWrappers = []interface{}{} - file_pb_model_result_proto_msgTypes[2].OneofWrappers = []interface{}{} - file_pb_model_result_proto_msgTypes[4].OneofWrappers = []interface{}{} - file_pb_model_result_proto_msgTypes[5].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[1].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[2].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[4].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[5].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/model/sim.pb.go b/pkg/model/sim.pb.go index a8b849f1..fc1b74ec 100644 --- a/pkg/model/sim.pb.go +++ b/pkg/model/sim.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/sim.proto package model @@ -320,7 +320,7 @@ func file_pb_model_sim_proto_rawDescGZIP() []byte { } var file_pb_model_sim_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_sim_proto_goTypes = []interface{}{ +var file_pb_model_sim_proto_goTypes = []any{ (*SimConfig)(nil), // 0: model.SimConfig (*SimulatorSettings)(nil), // 1: model.SimulatorSettings (*Wave)(nil), // 2: model.Wave @@ -349,7 +349,7 @@ func file_pb_model_sim_proto_init() { file_pb_model_enemy_proto_init() file_pb_model_character_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_sim_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*SimConfig); i { case 0: return &v.state @@ -361,7 +361,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*SimulatorSettings); i { case 0: return &v.state @@ -373,7 +373,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*Wave); i { case 0: return &v.state @@ -385,7 +385,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*Engage); i { case 0: return &v.state @@ -398,7 +398,7 @@ func file_pb_model_sim_proto_init() { } } } - file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []interface{}{ + file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []any{ (*SimConfig_Gcsl)(nil), } type x struct{} From 6bb074a403ffadc81f4746a7e70ed2665b1862d6 Mon Sep 17 00:00:00 2001 From: srl <906239+srliao@users.noreply.github.com> Date: Sun, 27 Oct 2024 12:21:40 -0400 Subject: [PATCH 4/7] fix tests failing due to not waiting for sim to finish (#320) * fix tests failing due to not waiting for sim to finish * move wait to tear down --- tests/teststub/stub.go | 53 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/tests/teststub/stub.go b/tests/teststub/stub.go index 5f837f0e..4a0dffdd 100644 --- a/tests/teststub/stub.go +++ b/tests/teststub/stub.go @@ -1,6 +1,7 @@ package teststub import ( + "context" "encoding/json" "fmt" "time" @@ -45,6 +46,9 @@ type Stub struct { // Assert wraps common assertion methods for convenience Assert assertion + + // Context to check if simulation run is completed + ctx context.Context } func (s *Stub) SetupTest() { @@ -71,13 +75,24 @@ func (s *Stub) TearDownTest() { fmt.Println("Test Finished") logging.InitLoggers() s.cfgEval = nil - select { - case <-s.eventPipe: - s.haltSignaller <- struct{}{} - default: + // hacky way to drain the sim and make sure it finishes first + for { + select { + case <-s.ctx.Done(): // wait for sim to finish + switch s.ctx.Err() { + case context.Canceled: + // finished ok; we can close down + close(s.haltSignaller) + return + default: + // sim did not end without error + panic(s.ctx.Err()) + } + case <-s.eventPipe: + case s.haltSignaller <- struct{}{}: + fmt.Println("forcing continue at end of test") + } } - close(s.eventPipe) - close(s.haltSignaller) } // StartSimulation handles the setup for starting the asynchronous sim run. @@ -99,12 +114,15 @@ func (s *Stub) StartSimulation() { s.simulator.Turn = s.Turn } s.Characters.attributes = s.simulator.Attr + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*2) + s.ctx = ctx go func() { itres, err := s.simulator.Run() + defer cancel() if err != nil { s.FailNow("Simulation run error", err) } - fmt.Println(itres) + fmt.Printf("test simulation run finished with damage %v\n", itres.TotalDamageDealt) }() // start sim logic, fast-forward sim to BattleStart state, so we can initialize the remaining helper stuff s.Expect(battlestart.ExpectFor()) @@ -118,6 +136,27 @@ func (s *Stub) StartSimulation() { } } +func (s *Stub) WaitForSimulationFinished() error { + // this is hacky as hell but we need to spam continue to let sim finish + // and we do this by consuming all events and spamming continue + for { + select { + case <-s.ctx.Done(): + // check if timed out + switch s.ctx.Err() { + case context.Canceled: + return nil + default: + return s.ctx.Err() + } + case e := <-s.eventPipe: + fmt.Printf("there are more events at end of test: %v\n", e) + case s.haltSignaller <- struct{}{}: + fmt.Println("forcing continue at end of test") + } + } +} + // Expect handles all sorts of checks against events. Refer to eventchecker.EventChecker for more details. func (s *Stub) Expect(checkers ...eventchecker.EventChecker) { for { From a189a4b5c404971cb7142f260aff790dfe630e86 Mon Sep 17 00:00:00 2001 From: 6000j Date: Sun, 27 Oct 2024 14:24:39 +1100 Subject: [PATCH 5/7] Poised to Bloom initial implementation --- .../lightcone/harmony/poisedtobloom/data.go | 71 +++++++++++++++++ .../harmony/poisedtobloom/poisedtobloom.go | 77 +++++++++++++++++++ pkg/key/lightcone.go | 1 + pkg/model/character.pb.go | 16 ++-- pkg/model/enemy.pb.go | 50 ++++++------ pkg/model/enum.pb.go | 6 +- pkg/model/result.pb.go | 26 +++---- pkg/model/sim.pb.go | 16 ++-- pkg/simulation/imports.go | 1 + .../lightcone/poised_to_bloom_test.go | 63 +++++++++++++++ tests/testcfg/testchar/bronya.go | 27 +++++++ tests/testcfg/testcone/dance_dance_dance.go | 15 ++++ tests/testcfg/testcone/poised_to_bloom.go | 15 ++++ 13 files changed, 327 insertions(+), 57 deletions(-) create mode 100644 internal/lightcone/harmony/poisedtobloom/data.go create mode 100644 internal/lightcone/harmony/poisedtobloom/poisedtobloom.go create mode 100644 tests/testcase/lightcone/poised_to_bloom_test.go create mode 100644 tests/testcfg/testchar/bronya.go create mode 100644 tests/testcfg/testcone/dance_dance_dance.go create mode 100644 tests/testcfg/testcone/poised_to_bloom.go diff --git a/internal/lightcone/harmony/poisedtobloom/data.go b/internal/lightcone/harmony/poisedtobloom/data.go new file mode 100644 index 00000000..3ef078a0 --- /dev/null +++ b/internal/lightcone/harmony/poisedtobloom/data.go @@ -0,0 +1,71 @@ +// Code generated by "weapstat"; DO NOT EDIT. + +package poisedtobloom + +import "github.com/simimpact/srsim/pkg/engine/equip/lightcone" + +var promotions = []lightcone.PromotionData{ + { + MaxLevel: 20, + HPBase: 43.20, + HPAdd: 6.48, + ATKBase: 19.20, + ATKAdd: 2.88, + DEFBase: 18, + DEFAdd: 2.70, + }, + { + MaxLevel: 30, + HPBase: 95.04, + HPAdd: 6.48, + ATKBase: 42.24, + ATKAdd: 2.88, + DEFBase: 39.60, + DEFAdd: 2.70, + }, + { + MaxLevel: 40, + HPBase: 164.16, + HPAdd: 6.48, + ATKBase: 72.96, + ATKAdd: 2.88, + DEFBase: 68.40, + DEFAdd: 2.70, + }, + { + MaxLevel: 50, + HPBase: 233.28, + HPAdd: 6.48, + ATKBase: 103.68, + ATKAdd: 2.88, + DEFBase: 97.20, + DEFAdd: 2.70, + }, + { + MaxLevel: 60, + HPBase: 302.40, + HPAdd: 6.48, + ATKBase: 134.40, + ATKAdd: 2.88, + DEFBase: 126, + DEFAdd: 2.70, + }, + { + MaxLevel: 70, + HPBase: 371.52, + HPAdd: 6.48, + ATKBase: 165.12, + ATKAdd: 2.88, + DEFBase: 154.80, + DEFAdd: 2.70, + }, + { + MaxLevel: 80, + HPBase: 440.64, + HPAdd: 6.48, + ATKBase: 195.84, + ATKAdd: 2.88, + DEFBase: 183.60, + DEFAdd: 2.70, + }, +} \ No newline at end of file diff --git a/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go new file mode 100644 index 00000000..1e731f97 --- /dev/null +++ b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go @@ -0,0 +1,77 @@ +package poisedtobloom + +import ( + "github.com/simimpact/srsim/pkg/engine" + "github.com/simimpact/srsim/pkg/engine/equip/lightcone" + "github.com/simimpact/srsim/pkg/engine/event" + "github.com/simimpact/srsim/pkg/engine/info" + "github.com/simimpact/srsim/pkg/engine/modifier" + "github.com/simimpact/srsim/pkg/engine/prop" + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +const ( + poised key.Modifier = "poised-to-bloom" + poisedCritDmg key.Modifier = "poised-to-bloom-crit-dmg" +) + +// Lose Not, Forget Not +// Increases the wearer's ATK by 16/20/24/28/32%. Upon entering battle, +// if two or more characters follow the same Path, +// then these characters' CRIT DMG increases by 16/20/24/28/32%. +// Abilities of the same type cannot stack. + +func init() { + lightcone.Register(key.PoisedToBloom, lightcone.Config{ + CreatePassive: Create, + Rarity: 4, + Path: model.Path_HARMONY, + Promotions: promotions, + }) + + modifier.Register(poised, modifier.Config{}) + + modifier.Register(poisedCritDmg, modifier.Config{ + Stacking: modifier.Replace, + }) +} + +func Create(engine engine.Engine, owner key.TargetID, lc info.LightCone) { + atkAmt := 0.12 + 0.04*float64(lc.Imposition) + critDmgAmt := 0.12 + 0.04*float64(lc.Imposition) + + engine.AddModifier(owner, info.Modifier{ + Name: poised, + Source: owner, + Stats: info.PropMap{prop.ATKPercent: atkAmt}, + }) + + engine.Events().BattleStart.Subscribe(func(event event.BattleStart) { + // This is probably slow, but I can't think of other good ways to iterate + // and store paths that don't involve allocating memory + // that might not be used, which I suspect would be slower + // It's still only called once per iteration though, so it should + // be fine. + + // Iterating over all the characters + for _, charA := range engine.Characters() { + charAInfo, _ := engine.CharacterInfo(charA) + // Checking for pairs with them + for _, charB := range engine.Characters() { + charBInfo, _ := engine.CharacterInfo(charB) + // If there's a pair, we apply the crit dmg buff to charA + // we could also apply it to charB, but with no way to remove + // them from the future iterations, that would actually be slower + if charB != charA && charAInfo.Path == charBInfo.Path { + engine.AddModifier(charA, info.Modifier{ + Name: poisedCritDmg, + Source: owner, + Stats: info.PropMap{prop.CritDMG: critDmgAmt}, + }) + break + } + } + } + }) +} diff --git a/pkg/key/lightcone.go b/pkg/key/lightcone.go index c0aa3ceb..1e4ac448 100644 --- a/pkg/key/lightcone.go +++ b/pkg/key/lightcone.go @@ -73,6 +73,7 @@ const ( MemoriesofthePast LightCone = "memories_of_the_past" DanceDanceDance LightCone = "dance_dance_dance" PlanetaryRendezvous LightCone = "planetary_rendezvous" + PoisedToBloom LightCone = "poised_to_bloom" ) // Preservation diff --git a/pkg/model/character.pb.go b/pkg/model/character.pb.go index b12e7a47..66d8c4de 100644 --- a/pkg/model/character.pb.go +++ b/pkg/model/character.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/character.proto package model @@ -470,7 +470,7 @@ func file_pb_model_character_proto_rawDescGZIP() []byte { } var file_pb_model_character_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_pb_model_character_proto_goTypes = []any{ +var file_pb_model_character_proto_goTypes = []interface{}{ (*Character)(nil), // 0: model.Character (*Abilities)(nil), // 1: model.Abilities (*LightCone)(nil), // 2: model.LightCone @@ -499,7 +499,7 @@ func file_pb_model_character_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_character_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Character); i { case 0: return &v.state @@ -511,7 +511,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Abilities); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*LightCone); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Relic); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[4].Exporter = func(v any, i int) any { + file_pb_model_character_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*RelicStat); i { case 0: return &v.state diff --git a/pkg/model/enemy.pb.go b/pkg/model/enemy.pb.go index 67fd596b..c2f4ac6b 100644 --- a/pkg/model/enemy.pb.go +++ b/pkg/model/enemy.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/enemy.proto package model import ( + _struct "github.com/golang/protobuf/ptypes/struct" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" - structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" ) @@ -81,14 +81,14 @@ type Enemy struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` - Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` - DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` - DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` - Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` - BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` - Parameters *structpb.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` + Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` + DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` + DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` + Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` + BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` + Parameters *_struct.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` } func (x *Enemy) Reset() { @@ -172,7 +172,7 @@ func (x *Enemy) GetBaseStats() *BaseStats { return nil } -func (x *Enemy) GetParameters() *structpb.Struct { +func (x *Enemy) GetParameters() *_struct.Struct { if x != nil { return x.Parameters } @@ -478,15 +478,15 @@ func file_pb_model_enemy_proto_rawDescGZIP() []byte { var file_pb_model_enemy_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_pb_model_enemy_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_enemy_proto_goTypes = []any{ - (EnemyRank)(0), // 0: model.EnemyRank - (*Enemy)(nil), // 1: model.Enemy - (*DebuffRES)(nil), // 2: model.DebuffRES - (*DamageRES)(nil), // 3: model.DamageRES - (*BaseStats)(nil), // 4: model.BaseStats - (DamageType)(0), // 5: model.DamageType - (*structpb.Struct)(nil), // 6: google.protobuf.Struct - (BehaviorFlag)(0), // 7: model.BehaviorFlag +var file_pb_model_enemy_proto_goTypes = []interface{}{ + (EnemyRank)(0), // 0: model.EnemyRank + (*Enemy)(nil), // 1: model.Enemy + (*DebuffRES)(nil), // 2: model.DebuffRES + (*DamageRES)(nil), // 3: model.DamageRES + (*BaseStats)(nil), // 4: model.BaseStats + (DamageType)(0), // 5: model.DamageType + (*_struct.Struct)(nil), // 6: google.protobuf.Struct + (BehaviorFlag)(0), // 7: model.BehaviorFlag } var file_pb_model_enemy_proto_depIdxs = []int32{ 5, // 0: model.Enemy.weaknesses:type_name -> model.DamageType @@ -511,7 +511,7 @@ func file_pb_model_enemy_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Enemy); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DebuffRES); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DamageRES); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BaseStats); i { case 0: return &v.state diff --git a/pkg/model/enum.pb.go b/pkg/model/enum.pb.go index c40271be..b6f735c0 100644 --- a/pkg/model/enum.pb.go +++ b/pkg/model/enum.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/enum.proto package model @@ -1218,7 +1218,7 @@ func file_pb_model_enum_proto_rawDescGZIP() []byte { } var file_pb_model_enum_proto_enumTypes = make([]protoimpl.EnumInfo, 13) -var file_pb_model_enum_proto_goTypes = []any{ +var file_pb_model_enum_proto_goTypes = []interface{}{ (Property)(0), // 0: model.Property (BehaviorFlag)(0), // 1: model.BehaviorFlag (StatusType)(0), // 2: model.StatusType diff --git a/pkg/model/result.pb.go b/pkg/model/result.pb.go index 1e2a9f3b..d6f837d4 100644 --- a/pkg/model/result.pb.go +++ b/pkg/model/result.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/result.proto package model @@ -651,7 +651,7 @@ func file_pb_model_result_proto_rawDescGZIP() []byte { } var file_pb_model_result_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_pb_model_result_proto_goTypes = []any{ +var file_pb_model_result_proto_goTypes = []interface{}{ (*Version)(nil), // 0: model.Version (*SimResult)(nil), // 1: model.SimResult (*Statistics)(nil), // 2: model.Statistics @@ -684,7 +684,7 @@ func file_pb_model_result_proto_init() { } file_pb_model_sim_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_result_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Version); i { case 0: return &v.state @@ -696,7 +696,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SimResult); i { case 0: return &v.state @@ -708,7 +708,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Statistics); i { case 0: return &v.state @@ -720,7 +720,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*IterationResult); i { case 0: return &v.state @@ -732,7 +732,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[4].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*OverviewStats); i { case 0: return &v.state @@ -744,7 +744,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[5].Exporter = func(v any, i int) any { + file_pb_model_result_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DescriptiveStats); i { case 0: return &v.state @@ -757,10 +757,10 @@ func file_pb_model_result_proto_init() { } } } - file_pb_model_result_proto_msgTypes[1].OneofWrappers = []any{} - file_pb_model_result_proto_msgTypes[2].OneofWrappers = []any{} - file_pb_model_result_proto_msgTypes[4].OneofWrappers = []any{} - file_pb_model_result_proto_msgTypes[5].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[1].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[4].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[5].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/model/sim.pb.go b/pkg/model/sim.pb.go index fc1b74ec..a8b849f1 100644 --- a/pkg/model/sim.pb.go +++ b/pkg/model/sim.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.34.2 -// protoc v5.28.1 +// protoc-gen-go v1.30.0 +// protoc v3.21.12 // source: pb/model/sim.proto package model @@ -320,7 +320,7 @@ func file_pb_model_sim_proto_rawDescGZIP() []byte { } var file_pb_model_sim_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_sim_proto_goTypes = []any{ +var file_pb_model_sim_proto_goTypes = []interface{}{ (*SimConfig)(nil), // 0: model.SimConfig (*SimulatorSettings)(nil), // 1: model.SimulatorSettings (*Wave)(nil), // 2: model.Wave @@ -349,7 +349,7 @@ func file_pb_model_sim_proto_init() { file_pb_model_enemy_proto_init() file_pb_model_character_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_sim_proto_msgTypes[0].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SimConfig); i { case 0: return &v.state @@ -361,7 +361,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[1].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SimulatorSettings); i { case 0: return &v.state @@ -373,7 +373,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[2].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Wave); i { case 0: return &v.state @@ -385,7 +385,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[3].Exporter = func(v any, i int) any { + file_pb_model_sim_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Engage); i { case 0: return &v.state @@ -398,7 +398,7 @@ func file_pb_model_sim_proto_init() { } } } - file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []any{ + file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []interface{}{ (*SimConfig_Gcsl)(nil), } type x struct{} diff --git a/pkg/simulation/imports.go b/pkg/simulation/imports.go index dd758b1c..78124c71 100644 --- a/pkg/simulation/imports.go +++ b/pkg/simulation/imports.go @@ -71,6 +71,7 @@ import ( _ "github.com/simimpact/srsim/internal/lightcone/harmony/memoriesofthepast" _ "github.com/simimpact/srsim/internal/lightcone/harmony/meshingcogs" _ "github.com/simimpact/srsim/internal/lightcone/harmony/planetaryrendezvous" + _ "github.com/simimpact/srsim/internal/lightcone/harmony/poisedtobloom" _ "github.com/simimpact/srsim/internal/lightcone/hunt/adversarial" _ "github.com/simimpact/srsim/internal/lightcone/hunt/arrows" _ "github.com/simimpact/srsim/internal/lightcone/hunt/cruisinginthestellarsea" diff --git a/tests/testcase/lightcone/poised_to_bloom_test.go b/tests/testcase/lightcone/poised_to_bloom_test.go new file mode 100644 index 00000000..976fefbb --- /dev/null +++ b/tests/testcase/lightcone/poised_to_bloom_test.go @@ -0,0 +1,63 @@ +package lightcone + +import ( + "testing" + + "github.com/simimpact/srsim/pkg/engine/prop" + "github.com/simimpact/srsim/tests/testcfg/testchar" + "github.com/simimpact/srsim/tests/testcfg/testcone" + "github.com/simimpact/srsim/tests/teststub" + "github.com/stretchr/testify/suite" +) + +type PTBTest struct { + teststub.Stub +} + +func TestPTBTest(t *testing.T) { + suite.Run(t, new(PTBTest)) +} + +// Testing that PTB indeed does add the correct ATK amount +func (t *PTBTest) Test_AtkAdd() { + bronyaModel := testchar.Bronya() + bronyaModel.LightCone = testcone.PoisedToBloom() + t.Characters.ResetCharacters() + bronya := t.Characters.AddCharacter(bronyaModel) + t.StartSimulation() + // She should have no other atk buffs from anywhere + bronya.Equal(prop.ATKPercent, 0.16) +} + +// Testing that PTB adds crit damage to only characters who share a path with another character in the party +func (t *PTBTest) Test_CritDMG() { + bronyaModel := testchar.Bronya() + bronyaModel.LightCone = testcone.PoisedToBloom() + t.Characters.ResetCharacters() + bronya := t.Characters.AddCharacter(bronyaModel) + dan1 := t.Characters.AddCharacter(testchar.DanHung()) + dan2 := t.Characters.AddCharacter(testchar.DanHung()) + t.StartSimulation() + // 0.50 from base crit damage + 0.16 from poised buff + dan1.Equal(prop.CritDMG, 0.66) + dan2.Equal(prop.CritDMG, 0.66) + // Just the 0.50 base crit damage + bronya.Equal(prop.CritDMG, 0.50) +} + +// Testing that PTB adds crit damage to only characters who share a path with another character in the party +func (t *PTBTest) Test_No_Stacking() { + // I'm a bit concerned about using the same character twice, but hopefully all should be good? + bronyaModel1 := testchar.Bronya() + bronyaModel1.LightCone = testcone.PoisedToBloom() + bronyaModel2 := testchar.Bronya() + bronyaModel2.LightCone = testcone.PoisedToBloom() + t.Characters.ResetCharacters() + bronya1 := t.Characters.AddCharacter(bronyaModel1) + bronya2 := t.Characters.AddCharacter(bronyaModel2) + + t.StartSimulation() + // 0.50 from base crit damage + 0.16 from poised buff + bronya1.Equal(prop.CritDMG, 0.66) + bronya2.Equal(prop.CritDMG, 0.66) +} diff --git a/tests/testcfg/testchar/bronya.go b/tests/testcfg/testchar/bronya.go new file mode 100644 index 00000000..0ff847f4 --- /dev/null +++ b/tests/testcfg/testchar/bronya.go @@ -0,0 +1,27 @@ +package testchar + +import ( + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" + "github.com/simimpact/srsim/tests/testcfg/testcone" +) + +func Bronya() *model.Character { + return &model.Character{ + Key: key.Bronya.String(), + Level: 80, + MaxLevel: 80, + Eidols: 0, + Traces: nil, + Abilities: &model.Abilities{ + Attack: 1, + Skill: 1, + Ult: 1, + Talent: 1, + }, + LightCone: testcone.DanceDanceDance(), + Relics: nil, + StartHp: 0, + StartEnergy: 0, + } +} diff --git a/tests/testcfg/testcone/dance_dance_dance.go b/tests/testcfg/testcone/dance_dance_dance.go new file mode 100644 index 00000000..a6dfc238 --- /dev/null +++ b/tests/testcfg/testcone/dance_dance_dance.go @@ -0,0 +1,15 @@ +package testcone + +import ( + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +func DanceDanceDance() *model.LightCone { + return &model.LightCone{ + Key: key.DanceDanceDance.String(), + Level: 80, + MaxLevel: 80, + Imposition: 1, + } +} diff --git a/tests/testcfg/testcone/poised_to_bloom.go b/tests/testcfg/testcone/poised_to_bloom.go new file mode 100644 index 00000000..bf331ced --- /dev/null +++ b/tests/testcfg/testcone/poised_to_bloom.go @@ -0,0 +1,15 @@ +package testcone + +import ( + "github.com/simimpact/srsim/pkg/key" + "github.com/simimpact/srsim/pkg/model" +) + +func PoisedToBloom() *model.LightCone { + return &model.LightCone{ + Key: key.PoisedToBloom.String(), + Level: 80, + MaxLevel: 80, + Imposition: 1, + } +} From 3c9347a4c513b97067848c1c4d3055030f486933 Mon Sep 17 00:00:00 2001 From: 6000j Date: Sun, 27 Oct 2024 15:47:15 +1100 Subject: [PATCH 6/7] corrected stacking type --- internal/lightcone/harmony/poisedtobloom/poisedtobloom.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go index 1e731f97..9566a994 100644 --- a/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go +++ b/internal/lightcone/harmony/poisedtobloom/poisedtobloom.go @@ -33,7 +33,7 @@ func init() { modifier.Register(poised, modifier.Config{}) modifier.Register(poisedCritDmg, modifier.Config{ - Stacking: modifier.Replace, + Stacking: modifier.Unique, }) } From 58fe80c43bf6f969e3d3fd332df22c909e1ca709 Mon Sep 17 00:00:00 2001 From: 6000j Date: Sun, 27 Oct 2024 20:53:49 +1100 Subject: [PATCH 7/7] reverting unneeded changes to generated files due to mismatched protoc versions --- pkg/model/character.pb.go | 16 ++++++------- pkg/model/enemy.pb.go | 50 +++++++++++++++++++-------------------- pkg/model/enum.pb.go | 6 ++--- pkg/model/result.pb.go | 26 ++++++++++---------- pkg/model/sim.pb.go | 16 ++++++------- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/pkg/model/character.pb.go b/pkg/model/character.pb.go index 66d8c4de..b12e7a47 100644 --- a/pkg/model/character.pb.go +++ b/pkg/model/character.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/character.proto package model @@ -470,7 +470,7 @@ func file_pb_model_character_proto_rawDescGZIP() []byte { } var file_pb_model_character_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_pb_model_character_proto_goTypes = []interface{}{ +var file_pb_model_character_proto_goTypes = []any{ (*Character)(nil), // 0: model.Character (*Abilities)(nil), // 1: model.Abilities (*LightCone)(nil), // 2: model.LightCone @@ -499,7 +499,7 @@ func file_pb_model_character_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_character_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Character); i { case 0: return &v.state @@ -511,7 +511,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*Abilities); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*LightCone); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*Relic); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_character_proto_init() { return nil } } - file_pb_model_character_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_character_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*RelicStat); i { case 0: return &v.state diff --git a/pkg/model/enemy.pb.go b/pkg/model/enemy.pb.go index c2f4ac6b..67fd596b 100644 --- a/pkg/model/enemy.pb.go +++ b/pkg/model/enemy.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/enemy.proto package model import ( - _struct "github.com/golang/protobuf/ptypes/struct" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" reflect "reflect" sync "sync" ) @@ -81,14 +81,14 @@ type Enemy struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` - Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` - DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` - DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` - Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` - BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` - Parameters *_struct.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` + Weaknesses []DamageType `protobuf:"varint,3,rep,packed,name=weaknesses,proto3,enum=model.DamageType" json:"weaknesses,omitempty"` + DebuffRes []*DebuffRES `protobuf:"bytes,4,rep,name=debuff_res,json=debuffRes,proto3" json:"debuff_res,omitempty"` + DamageRes []*DamageRES `protobuf:"bytes,5,rep,name=damage_res,json=damageRes,proto3" json:"damage_res,omitempty"` + Rank EnemyRank `protobuf:"varint,6,opt,name=rank,proto3,enum=model.EnemyRank" json:"rank,omitempty"` + BaseStats *BaseStats `protobuf:"bytes,7,opt,name=base_stats,json=baseStats,proto3" json:"base_stats,omitempty"` + Parameters *structpb.Struct `protobuf:"bytes,10,opt,name=parameters,proto3" json:"parameters,omitempty"` } func (x *Enemy) Reset() { @@ -172,7 +172,7 @@ func (x *Enemy) GetBaseStats() *BaseStats { return nil } -func (x *Enemy) GetParameters() *_struct.Struct { +func (x *Enemy) GetParameters() *structpb.Struct { if x != nil { return x.Parameters } @@ -478,15 +478,15 @@ func file_pb_model_enemy_proto_rawDescGZIP() []byte { var file_pb_model_enemy_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_pb_model_enemy_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_enemy_proto_goTypes = []interface{}{ - (EnemyRank)(0), // 0: model.EnemyRank - (*Enemy)(nil), // 1: model.Enemy - (*DebuffRES)(nil), // 2: model.DebuffRES - (*DamageRES)(nil), // 3: model.DamageRES - (*BaseStats)(nil), // 4: model.BaseStats - (DamageType)(0), // 5: model.DamageType - (*_struct.Struct)(nil), // 6: google.protobuf.Struct - (BehaviorFlag)(0), // 7: model.BehaviorFlag +var file_pb_model_enemy_proto_goTypes = []any{ + (EnemyRank)(0), // 0: model.EnemyRank + (*Enemy)(nil), // 1: model.Enemy + (*DebuffRES)(nil), // 2: model.DebuffRES + (*DamageRES)(nil), // 3: model.DamageRES + (*BaseStats)(nil), // 4: model.BaseStats + (DamageType)(0), // 5: model.DamageType + (*structpb.Struct)(nil), // 6: google.protobuf.Struct + (BehaviorFlag)(0), // 7: model.BehaviorFlag } var file_pb_model_enemy_proto_depIdxs = []int32{ 5, // 0: model.Enemy.weaknesses:type_name -> model.DamageType @@ -511,7 +511,7 @@ func file_pb_model_enemy_proto_init() { } file_pb_model_enum_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Enemy); i { case 0: return &v.state @@ -523,7 +523,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*DebuffRES); i { case 0: return &v.state @@ -535,7 +535,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*DamageRES); i { case 0: return &v.state @@ -547,7 +547,7 @@ func file_pb_model_enemy_proto_init() { return nil } } - file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_enemy_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*BaseStats); i { case 0: return &v.state diff --git a/pkg/model/enum.pb.go b/pkg/model/enum.pb.go index b6f735c0..c40271be 100644 --- a/pkg/model/enum.pb.go +++ b/pkg/model/enum.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/enum.proto package model @@ -1218,7 +1218,7 @@ func file_pb_model_enum_proto_rawDescGZIP() []byte { } var file_pb_model_enum_proto_enumTypes = make([]protoimpl.EnumInfo, 13) -var file_pb_model_enum_proto_goTypes = []interface{}{ +var file_pb_model_enum_proto_goTypes = []any{ (Property)(0), // 0: model.Property (BehaviorFlag)(0), // 1: model.BehaviorFlag (StatusType)(0), // 2: model.StatusType diff --git a/pkg/model/result.pb.go b/pkg/model/result.pb.go index d6f837d4..1e2a9f3b 100644 --- a/pkg/model/result.pb.go +++ b/pkg/model/result.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/result.proto package model @@ -651,7 +651,7 @@ func file_pb_model_result_proto_rawDescGZIP() []byte { } var file_pb_model_result_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_pb_model_result_proto_goTypes = []interface{}{ +var file_pb_model_result_proto_goTypes = []any{ (*Version)(nil), // 0: model.Version (*SimResult)(nil), // 1: model.SimResult (*Statistics)(nil), // 2: model.Statistics @@ -684,7 +684,7 @@ func file_pb_model_result_proto_init() { } file_pb_model_sim_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_result_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*Version); i { case 0: return &v.state @@ -696,7 +696,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*SimResult); i { case 0: return &v.state @@ -708,7 +708,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*Statistics); i { case 0: return &v.state @@ -720,7 +720,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*IterationResult); i { case 0: return &v.state @@ -732,7 +732,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[4].Exporter = func(v any, i int) any { switch v := v.(*OverviewStats); i { case 0: return &v.state @@ -744,7 +744,7 @@ func file_pb_model_result_proto_init() { return nil } } - file_pb_model_result_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_result_proto_msgTypes[5].Exporter = func(v any, i int) any { switch v := v.(*DescriptiveStats); i { case 0: return &v.state @@ -757,10 +757,10 @@ func file_pb_model_result_proto_init() { } } } - file_pb_model_result_proto_msgTypes[1].OneofWrappers = []interface{}{} - file_pb_model_result_proto_msgTypes[2].OneofWrappers = []interface{}{} - file_pb_model_result_proto_msgTypes[4].OneofWrappers = []interface{}{} - file_pb_model_result_proto_msgTypes[5].OneofWrappers = []interface{}{} + file_pb_model_result_proto_msgTypes[1].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[2].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[4].OneofWrappers = []any{} + file_pb_model_result_proto_msgTypes[5].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/pkg/model/sim.pb.go b/pkg/model/sim.pb.go index a8b849f1..fc1b74ec 100644 --- a/pkg/model/sim.pb.go +++ b/pkg/model/sim.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.21.12 +// protoc-gen-go v1.34.2 +// protoc v5.28.1 // source: pb/model/sim.proto package model @@ -320,7 +320,7 @@ func file_pb_model_sim_proto_rawDescGZIP() []byte { } var file_pb_model_sim_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pb_model_sim_proto_goTypes = []interface{}{ +var file_pb_model_sim_proto_goTypes = []any{ (*SimConfig)(nil), // 0: model.SimConfig (*SimulatorSettings)(nil), // 1: model.SimulatorSettings (*Wave)(nil), // 2: model.Wave @@ -349,7 +349,7 @@ func file_pb_model_sim_proto_init() { file_pb_model_enemy_proto_init() file_pb_model_character_proto_init() if !protoimpl.UnsafeEnabled { - file_pb_model_sim_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*SimConfig); i { case 0: return &v.state @@ -361,7 +361,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*SimulatorSettings); i { case 0: return &v.state @@ -373,7 +373,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*Wave); i { case 0: return &v.state @@ -385,7 +385,7 @@ func file_pb_model_sim_proto_init() { return nil } } - file_pb_model_sim_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_pb_model_sim_proto_msgTypes[3].Exporter = func(v any, i int) any { switch v := v.(*Engage); i { case 0: return &v.state @@ -398,7 +398,7 @@ func file_pb_model_sim_proto_init() { } } } - file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []interface{}{ + file_pb_model_sim_proto_msgTypes[0].OneofWrappers = []any{ (*SimConfig_Gcsl)(nil), } type x struct{}