package game import ( "errors" "regexp" "strconv" ) type effect interface { apply(*LocalState) end(*LocalState) } type dynamicEffect struct { _apply func(*LocalState) _end func(*LocalState) } func (e *dynamicEffect) apply(s *LocalState) { e._apply(s) } func (e *dynamicEffect) end(s *LocalState) { e._end(s) } func newCombinedEffect(effects []effect) *dynamicEffect { return &dynamicEffect{ _apply: func(s *LocalState) { for _, e := range effects { e.apply(s) } }, _end: func(s *LocalState) { for _, e := range effects { e.end(s) } }, } } func newAdjustmentEffect(adjust func(Permanent, int), u *Unit, delta int) effect { apply := func(*LocalState) { adjust(u, delta) } end := func(*LocalState) { adjust(u, -delta) } return &dynamicEffect{apply, end} } func newMeleeModificationEffect(u *Unit, delta int) effect { return newAdjustmentEffect(adjustMelee, u, delta) } func newAttackModificationEffect(u *Unit, delta int) effect { return newAdjustmentEffect(adjustAttack, u, delta) } func newMovementModificationEffect(u *Unit, delta int) effect { return newAdjustmentEffect(adjustMovement, u, delta) } func newHealthModificationEffect(u *Unit, delta int) effect { return newAdjustmentEffect(adjustHealth, u, delta) } func newTmpEffect(p Permanent, effect string) effect { apply := func(*LocalState) { p.addTmpEffect(effect) } end := func(*LocalState) { p.removeTmpEffect(effect) } return &dynamicEffect{apply, end} } type xEffect struct { // amount of the effect x int // does the effect set or adjust the value set bool // raw effect description raw string } type ErrXEffectError struct { err error } func (e ErrXEffectError) Error() string { return e.err.Error() } var ErrXEffectFormat = ErrXEffectError{errors.New("invalid format")} var ( xEffectXSuffix = regexp.MustCompile(`^\S+ ([\+-]?)(\d+)`) xEffectXPrefix = regexp.MustCompile(`^([\+-]?)(\d+) \S+`) ) func parseXEffect(desc string) (e xEffect, err error) { if freeActionRegex.FindString(desc) != "" { return e, ErrXEffectFormat } e.raw = desc m := xEffectXSuffix.FindAllStringSubmatch(desc, -1) if len(m) == 0 { m = xEffectXPrefix.FindAllStringSubmatch(desc, -1) } if len(m) != 0 { e.set = m[0][1] == "" e.x, err = strconv.Atoi(m[0][1] + m[0][2]) if err != nil { return e, ErrXEffectError{err} } return e, nil } // Both regex did not match return e, ErrXEffectFormat }