diff --git a/pkg/engine/attribute/attribute.go b/pkg/engine/attribute/attribute.go index 42532eb3..4ed9182f 100644 --- a/pkg/engine/attribute/attribute.go +++ b/pkg/engine/attribute/attribute.go @@ -22,12 +22,14 @@ type Getter interface { FullEnergy(target key.TargetID) bool LastAttacker(target key.TargetID) key.TargetID SP() int + MaxSP() int } type Manager interface { Getter ModifySP(data info.ModifySP) error + ModifyMaxSP(data info.ModifySP) error AddTarget(target key.TargetID, base info.Attributes) error @@ -48,6 +50,7 @@ type Service struct { modEval modifier.Eval targets map[key.TargetID]*attrTarget sp int + maxsp int } func New(event *event.System, modEval modifier.Eval) Manager { @@ -56,6 +59,7 @@ func New(event *event.System, modEval modifier.Eval) Manager { modEval: modEval, targets: make(map[key.TargetID]*attrTarget, 10), sp: 3, + maxsp: 5, } } @@ -144,3 +148,7 @@ func (s *Service) LastAttacker(target key.TargetID) key.TargetID { func (s *Service) SP() int { return s.sp } + +func (s *Service) MaxSP() int { + return s.maxsp +} diff --git a/pkg/engine/attribute/event.go b/pkg/engine/attribute/event.go index 6b2135df..50ad138a 100644 --- a/pkg/engine/attribute/event.go +++ b/pkg/engine/attribute/event.go @@ -76,3 +76,15 @@ func (s *Service) emitSPChange(key key.Reason, source key.TargetID, prevSP, newS } return nil } + +func (s *Service) emitMaxSPChange(key key.Reason, source key.TargetID, prevMaxSP, newMaxSP int) error { + if prevMaxSP != newMaxSP { + s.event.MaxSPChange.Emit(event.MaxSPChange{ + Key: key, + Source: source, + OldMaxSP: prevMaxSP, + NewMaxSP: newMaxSP, + }) + } + return nil +} diff --git a/pkg/engine/attribute/modify.go b/pkg/engine/attribute/modify.go index 9809f42d..f9c39bf8 100644 --- a/pkg/engine/attribute/modify.go +++ b/pkg/engine/attribute/modify.go @@ -193,10 +193,23 @@ func (s *Service) ModifyEnergyFixed(data info.ModifyAttribute) error { func (s *Service) ModifySP(data info.ModifySP) error { old := s.sp s.sp += data.Amount - if s.sp > 5 { - s.sp = 5 + if s.sp > s.maxsp { + s.sp = s.maxsp } else if s.sp < 0 { s.sp = 0 } return s.emitSPChange(data.Key, data.Source, old, s.sp) } + +func (s *Service) ModifyMaxSP(data info.ModifySP) error { + old := s.sp + s.maxsp += data.Amount + if s.sp > s.maxsp { + s.ModifySP(info.ModifySP{ + Key: data.Key, + Source: data.Source, + Amount: s.maxsp - s.sp, + }) + } + return s.emitMaxSPChange(data.Key, data.Source, old, s.maxsp) +} diff --git a/pkg/engine/event/attribute.go b/pkg/engine/event/attribute.go index 3e75dde0..4e4ca716 100644 --- a/pkg/engine/event/attribute.go +++ b/pkg/engine/event/attribute.go @@ -65,3 +65,11 @@ type SPChange struct { OldSP int `json:"old_sp"` NewSP int `json:"new_sp"` } + +type MaxSPChangeEventHandler = handler.EventHandler[MaxSPChange] +type MaxSPChange struct { + Key key.Reason `json:"key"` + Source key.TargetID `json:"source"` + OldMaxSP int `json:"old_max_sp"` + NewMaxSP int `json:"new_max_sp"` +} diff --git a/pkg/engine/event/event.go b/pkg/engine/event/event.go index 4ee10350..79c350dc 100644 --- a/pkg/engine/event/event.go +++ b/pkg/engine/event/event.go @@ -48,6 +48,7 @@ type System struct { StanceBreak StanceBreakEventHandler StanceReset StanceResetEventHandler SPChange SPChangeEventHandler + MaxSPChange MaxSPChangeEventHandler BreakExtend BreakExtendEventHandler diff --git a/pkg/engine/info/attribute.go b/pkg/engine/info/attribute.go index 6fa66912..4092786b 100644 --- a/pkg/engine/info/attribute.go +++ b/pkg/engine/info/attribute.go @@ -59,7 +59,7 @@ type ModifySP struct { // The source of this modification Source key.TargetID `json:"source"` - // The amount of SP to be added or removed + // The amount of SP or maximum SP to be added or removed Amount int `json:"amount"` } diff --git a/pkg/simulation/attribute.go b/pkg/simulation/attribute.go index f9206843..15505d02 100644 --- a/pkg/simulation/attribute.go +++ b/pkg/simulation/attribute.go @@ -35,10 +35,18 @@ func (sim *Simulation) ModifySP(data info.ModifySP) error { return sim.Attr.ModifySP(data) } +func (sim *Simulation) ModifyMaxSP(data info.ModifySP) error { + return sim.Attr.ModifyMaxSP(data) +} + func (sim *Simulation) SP() int { return sim.Attr.SP() } +func (sim *Simulation) MaxSP() int { + return sim.Attr.MaxSP() +} + func (sim *Simulation) Stats(target key.TargetID) *info.Stats { return sim.Attr.Stats(target) } diff --git a/tests/mock/mock_attribute.go b/tests/mock/mock_attribute.go index 18e58d20..65764b9c 100644 --- a/tests/mock/mock_attribute.go +++ b/tests/mock/mock_attribute.go @@ -147,6 +147,20 @@ func (mr *MockAttributeMockRecorder) MaxEnergy(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxEnergy", reflect.TypeOf((*MockAttribute)(nil).MaxEnergy), arg0) } +// MaxSP mocks base method. +func (m *MockAttribute) MaxSP() int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MaxSP") + ret0, _ := ret[0].(int) + return ret0 +} + +// MaxSP indicates an expected call of MaxSP. +func (mr *MockAttributeMockRecorder) MaxSP() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MaxSP", reflect.TypeOf((*MockAttribute)(nil).MaxSP)) +} + // MaxStance mocks base method. func (m *MockAttribute) MaxStance(arg0 key.TargetID) float64 { m.ctrl.T.Helper() @@ -217,6 +231,20 @@ func (mr *MockAttributeMockRecorder) ModifyHPByRatio(arg0, arg1 interface{}) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyHPByRatio", reflect.TypeOf((*MockAttribute)(nil).ModifyHPByRatio), arg0, arg1) } +// ModifyMaxSP mocks base method. +func (m *MockAttribute) ModifyMaxSP(arg0 info.ModifySP) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ModifyMaxSP", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ModifyMaxSP indicates an expected call of ModifyMaxSP. +func (mr *MockAttributeMockRecorder) ModifyMaxSP(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyMaxSP", reflect.TypeOf((*MockAttribute)(nil).ModifyMaxSP), arg0) +} + // ModifySP mocks base method. func (m *MockAttribute) ModifySP(arg0 info.ModifySP) error { m.ctrl.T.Helper() diff --git a/ui/packages/types/src/event.ts b/ui/packages/types/src/event.ts index b74a7108..12750601 100755 --- a/ui/packages/types/src/event.ts +++ b/ui/packages/types/src/event.ts @@ -58,6 +58,22 @@ export interface SPChange { old_sp: number /* int */; new_sp: number /* int */; } +export type MaxSPChangeEventHandler = Handler; +export interface MaxSPChange { + key: string; + source: string; + old_max_sp: number /* int */; + new_max_sp: number /* int */; +} + +////////// +// source: break.go + +export type BreakExtendEventHandler = Handler; +export interface BreakExtend { + key: string; + target: string; +} ////////// // source: combat.go @@ -87,6 +103,7 @@ export interface HitStart { export type HitEndEventHandler = Handler; export interface HitEnd { key: string; + hit?: info.Hit; hit_index: number /* int */; attacker: string; defender: string; @@ -151,6 +168,11 @@ export interface ModifierRemoved { target: string; modifier: info.Modifier; } +export type ModifierDispelledEventHandler = Handler; +export interface ModifierDispelled { + target: string; + modifier: info.Modifier; +} export type ModifierExtendedDurationEventHandler = Handler; export interface ModifierExtendedDuration { target: string; @@ -298,7 +320,7 @@ export interface TurnTargetsAdded { export type TurnResetEventHandler = Handler; export interface TurnReset { reset_target: string; - gauge_cost: number /* float64 */; + gauge_cost: number /* int64 */; turn_order: TurnStatus[]; } export type GaugeChangeEventHandler = Handler; @@ -306,19 +328,19 @@ export interface GaugeChange { key: string; target: string; source: string; - old_gauge: number /* float64 */; - new_gauge: number /* float64 */; + old_gauge: number /* int64 */; + new_gauge: number /* int64 */; turn_order: TurnStatus[]; } export type CurrentGaugeCostChangeEventHandler = Handler; export interface CurrentGaugeCostChange { key: string; source: string; - old_cost: number /* float64 */; - new_cost: number /* float64 */; + old_cost: number /* int64 */; + new_cost: number /* int64 */; } export interface TurnStatus { id: string; - gauge: number /* float64 */; + gauge: number /* int64 */; av: number /* float64 */; } diff --git a/ui/packages/types/src/info.ts b/ui/packages/types/src/info.ts index 0fbe542e..c41dda4c 100755 --- a/ui/packages/types/src/info.ts +++ b/ui/packages/types/src/info.ts @@ -72,7 +72,7 @@ export interface ModifySP { */ source: string; /** - * The amount of SP to be added or removed + * The amount of SP or maximum SP to be added or removed */ amount: number /* int */; } @@ -210,12 +210,12 @@ export interface Hit { * The stats of the attacker of this hit. These stats are a snapshot of the target's state and * can be modified */ - attacker?: Stats; + attacker?: StatsEncoded; /** * The stats of the defender of this hit. These stats are a snapshot of the target's state and * can be modified */ - defender?: Stats; + defender?: StatsEncoded; /** * The type of attack (IE: dot, ult, insert, etc) */ @@ -351,7 +351,7 @@ export interface Modifier { */ duration: number /* int */; /** - * When duration is > 0, the turn a modifier is added on will not count torwards the duration. + * When duration is > 0, the turn a modifier is added on will not count towards the duration. * If this field is set to true, this will override that behavior and count the application turn * against the duration (if application happens before the check). */ @@ -388,6 +388,12 @@ export interface Modifier { * Any additional weaknesses that are applied to the target by this modifier. */ weakness: WeaknessMap; + /** + * CanDispel indicates whether the modifier can be removed through dispel effects. + * If true, the modifier can be targeted and removed by dispel abilities; if false (default), + * it is immune to dispel. + */ + can_dispel: boolean; } export interface Dispel { /**