package manevr
import (
"context"
"fmt"
// "log"
"strings"
"time"
"github.com/sirupsen/logrus"
"wartank/server/serv_bots/warbot/angar/division/divwar/divwaron/health/repairtime"
"wartank/server/serv_bots/warbot/angar/division/divwar/divwaron/manevr/ismanevr"
// "wartank/internal/components/sound"
"wartank/pkg/components/safebool"
"wartank/pkg/types"
)
/*
Пытается маневрировать после выстрела
*/
// Manevr -- маневрирует после выстрела
type Manevr struct {
types.IDivWarOn // FIXME:
isEnd *safebool.SafeBool
ctxEnd context.Context
isManevr *ismanevr.IsManevr // Возможность выполнить манёвр
manevrTime *repairtime.RepairTime // Время до востановления манёвра
chTick chan int // Тики для поиска маневра
}
// NewManevr -- возвращает новый *Manevr
func NewManevr(divwar types.IDivWarOn, isDivWar *safebool.SafeBool) (*Manevr, error) {
{ // Предусловия
if divwar == nil {
return nil, fmt.Errorf("NewManevr(): battle is nil")
}
}
if isDivWar == nil {
return nil, fmt.Errorf("NewManevr(): isBattle is nil")
}
sf := &Manevr{
IDivWarOn: divwar,
ctxEnd: divwar.Ctx(),
isEnd: isDivWar,
isManevr: ismanevr.NewIsManevr(),
manevrTime: repairtime.NewRepairTime(),
chTick: make(chan int, 1),
}
_ = sf.manevrTime.Set("0") // При запуске боя есть возможность маневрировать
go sf.makeTick()
go sf.run()
return sf, nil
}
// Генерирует тик для уменьшения времени ожидания восстановления возможности манёвра
func (sf *Manevr) makeTick() {
defer func() {
close(sf.chTick)
// log._rintf("Manevr.makeTick(): сражение завершено\n")
}()
for {
select {
case <-sf.ctxEnd.Done():
return
default:
if sf.manevrTime.Get() == 0 {
sf.chTick <- 1
}
sf.manevrTime.Dec()
time.Sleep(time.Second * 1)
}
}
}
// Рабочий цикл поиска маневра (~)
func (sf *Manevr) run() {
for range sf.chTick {
if !sf.isManevr.Get() {
continue
}
sf.findManevrTime()
}
}
// Ищет время для манёвра
func (sf *Manevr) findManevrTime() {
var (
isFind bool
ind int
lstBattleOn = sf.GetLst()
strOut string
)
for ind, strOut = range lstBattleOn {
// 5 секунд
if strings.Contains(strOut, `-currentControl-maneuverLink`) {
isFind = true
break
}
}
if !isFind { // Или манёвр успел восстановиться, или конец сражения
if strings.Contains(strOut, `Маневр`) {
_ = sf.manevrTime.Set("0")
time.Sleep(time.Second * 1)
return
}
if sf.isEnd.Get() {
time.Sleep(time.Second * 1)
return
}
logrus.WithField("strOut", strOut).Warn("Manevr.findManevrTime(): ошибка в поиске времени манёвра")
time.Sleep(time.Second * 1)
return
}
{ // Найти время манёвра
lstTime := strings.Split(strOut, `ILinkListener-currentControl-maneuverLink" class="simple-but blue">`)
if len(lstTime) != 2 {
logrus.WithField("ind", ind).
WithField("lstBattleOn[-1]", lstBattleOn[ind-1]).
WithField("lstBattleOn[ind]", strOut).
WithField("lstBattleOn[+1]", lstBattleOn[ind+1]).
Errorf("Manevr.findManevrTime(): нет двух полей во времени ожидания")
sf.isManevr.Reset()
time.Sleep(time.Second * 1)
return
}
strTime := lstTime[1]
lstTime = strings.Split(strTime, ` секунд`)
strTime = lstTime[0]
if err := sf.manevrTime.Set(strTime); err != nil {
logrus.WithError(err).Error("Manevr.findManevrTime(): при обновлении времени ожидания манёвра")
sf.isManevr.Reset()
time.Sleep(time.Second * 1)
return
}
}
sf.isManevr.Set()
logrus.WithField("время", sf.manevrTime.Get()).Info("Manevr.findManevrTime(): до манёвра")
}
// Manevr -- принудительный манёвр по требованию
func (sf *Manevr) Manevr() {
var (
isFind = false
lstBattleOn = sf.GetLst()
strOut = ""
)
if !sf.isManevr.Get() {
time.Sleep(time.Second * 1)
return
}
for _, strOut = range lstBattleOn {
// Маневр
if strings.Contains(strOut, `Маневр`) {
isFind = true
break
}
}
if !isFind { // Либо ждём восстановления манёвра, либо сражение закончилось
sf.isManevr.Reset()
time.Sleep(time.Second * 1)
return
}
{ // Попытка манёвра
lstLink := strings.Split(strOut, `Маневр`)
strLink = "http://wartank.ru/" + lstLink[0]
lstBattleOn, err := sf.Net().Get(strLink)
if err != nil {
logrus.WithError(err).Error("Manevr.Manevr(): при выполнении GET-команды маневра")
sf.isManevr.Reset()
time.Sleep(time.Second * 1)
return
}
if err = sf.Update(lstBattleOn); err != nil {
logrus.WithError(err).Error("Manevr.Manevr(): при обновлении lstBattle")
sf.isManevr.Reset()
time.Sleep(time.Second * 1)
return
}
// sound.Manevr()
}
}
// IsReady -- возвращает готовность манёвра
func (sf *Manevr) IsReady() bool {
return sf.manevrTime.IsReady()
}