|
|
@@ -1,9 +1,7 @@
|
|
|
package health
|
|
|
|
|
|
import (
|
|
|
-
|
|
|
- // "log"
|
|
|
- // "strconv"
|
|
|
+ "strconv"
|
|
|
"strings"
|
|
|
"time"
|
|
|
|
|
|
@@ -23,18 +21,16 @@ import (
|
|
|
|
|
|
// Здоровье -- контроль здоровья танка
|
|
|
type Здоровье struct {
|
|
|
- ИСражениеПроцесс // FIXME:
|
|
|
- fnCancel func()
|
|
|
- temp *health_time.HealthTime // Изменяемое здоровье танка
|
|
|
- full *health_time.HealthTime // Полное здоровье танка
|
|
|
- isRepair ISafeBool // Необходимость восстановления
|
|
|
- repairTime *repair_time.RepairTime // Время до восстановления
|
|
|
+ ИСражениеПроцесс // FIXME:
|
|
|
+ здоровьеСейчас *health_time.HealthTime // Изменяемое здоровье танка
|
|
|
+ здоровьеПолное *health_time.HealthTime // Полное здоровье танка
|
|
|
+ еслиНадо ISafeBool // Необходимость восстановления
|
|
|
+ отсчётАптечка *repair_time.RepairTime // Время до восстановления
|
|
|
isEnd ISafeBool // Ссылка на признак конца сражения
|
|
|
- login string // Для поиска контрольных строк
|
|
|
+ логин string // Для поиска контрольных строк
|
|
|
chTick chan int // Канал для ровной отправки тиков
|
|
|
// deltaOld int // Старая дельта потери здоровья
|
|
|
// countLow int
|
|
|
- ctxBattle ILocalCtx // Контекст сражения
|
|
|
}
|
|
|
|
|
|
// НовЗдоровье -- возвращает новый *Health
|
|
|
@@ -43,14 +39,12 @@ func НовЗдоровье(проц ИСражениеПроцесс) *Здор
|
|
|
логин := проц.Бот().Имя()
|
|
|
сам := &Здоровье{
|
|
|
ИСражениеПроцесс: проц,
|
|
|
- fnCancel: проц.Отменить,
|
|
|
- ctxBattle: проц.Бот().КонтБот(),
|
|
|
- temp: health_time.NewHealthTime(),
|
|
|
- full: health_time.NewHealthTime(),
|
|
|
- isRepair: NewSafeBool(),
|
|
|
- repairTime: repair_time.NewRepairTime(),
|
|
|
+ здоровьеСейчас: health_time.NewHealthTime(),
|
|
|
+ здоровьеПолное: health_time.NewHealthTime(),
|
|
|
+ еслиНадо: NewSafeBool(),
|
|
|
+ отсчётАптечка: repair_time.NewRepairTime(),
|
|
|
isEnd: проц.ЕслиКонец(),
|
|
|
- login: логин,
|
|
|
+ логин: логин,
|
|
|
chTick: make(chan int, 2),
|
|
|
}
|
|
|
go сам.makeTik()
|
|
|
@@ -61,33 +55,35 @@ func НовЗдоровье(проц ИСражениеПроцесс) *Здор
|
|
|
// Отправляет тики с заданным равным интервалом
|
|
|
func (сам *Здоровье) makeTik() {
|
|
|
defer func() {
|
|
|
- сам.fnCancel()
|
|
|
close(сам.chTick)
|
|
|
- // log._rintf("Health.makeTick(): сражение завершёно\n")
|
|
|
+ сам.Отменить()
|
|
|
}()
|
|
|
- count := 0
|
|
|
- repairTime := 0
|
|
|
+ лимитАптечка := 0 // Предел времени ожидания
|
|
|
+ отсчётАптечка := 0
|
|
|
for {
|
|
|
select {
|
|
|
- case <-сам.ctxBattle.Ctx().Done():
|
|
|
+ case <-сам.Контекст().Done():
|
|
|
return
|
|
|
default:
|
|
|
if сам.ЕслиУбит() {
|
|
|
return
|
|
|
}
|
|
|
- if сам.repairTime.Get() == repairTime {
|
|
|
- count++
|
|
|
+ if сам.отсчётАптечка.Получ() == отсчётАптечка {
|
|
|
+ лимитАптечка++
|
|
|
} else {
|
|
|
- repairTime = сам.repairTime.Get()
|
|
|
- count = 0
|
|
|
+ отсчётАптечка = сам.отсчётАптечка.Получ()
|
|
|
+ лимитАптечка = 0
|
|
|
+ }
|
|
|
+ if сам.отсчётАптечка.IsReady() {
|
|
|
+ лимитАптечка = 0
|
|
|
}
|
|
|
- if count > 90 {
|
|
|
+ if лимитАптечка > 90 {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
сам.chTick <- 1
|
|
|
time.Sleep(time.Second * 1)
|
|
|
- сам.repairTime.Dec()
|
|
|
+ сам.отсчётАптечка.Dec()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -95,45 +91,36 @@ func (сам *Здоровье) makeTik() {
|
|
|
func (сам *Здоровье) run() {
|
|
|
for {
|
|
|
select {
|
|
|
- case <-сам.ctxBattle.Ctx().Done():
|
|
|
+ case <-сам.Контекст().Done():
|
|
|
сам.isEnd.Set()
|
|
|
return
|
|
|
case <-сам.chTick:
|
|
|
- // if err := сам.findHealth(); err != nil { // Найти свой здоровье
|
|
|
- // // log._rintf("ERRO Health.run(): при попытке найти здоровье, err=\n\t%v\n", err)
|
|
|
- // }
|
|
|
- сам.findRepairTime()
|
|
|
- if сам.Выстрел().ЕслиБлок() {
|
|
|
- if сам.isRepair.Get() {
|
|
|
- go сам.repair()
|
|
|
- }
|
|
|
- continue
|
|
|
- }
|
|
|
- if сам.isRepair.Get() {
|
|
|
+ сам.здоровьеНайти()
|
|
|
+ сам.найтиВремяВосстановления()
|
|
|
+ if сам.еслиНадо.Get() {
|
|
|
go сам.repair()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// Full -- возвращает объект полного здоровья танка
|
|
|
-func (сам *Здоровье) Full() int {
|
|
|
- return сам.full.Get()
|
|
|
+// Полное -- возвращает объект полного здоровья танка
|
|
|
+func (сам *Здоровье) Полное() int {
|
|
|
+ return сам.здоровьеПолное.Get()
|
|
|
}
|
|
|
|
|
|
// ЕслиУбит -- возвращает признак мертвичины танка
|
|
|
func (сам *Здоровье) ЕслиУбит() bool {
|
|
|
if сам.isEnd.Get() {
|
|
|
- сам.fnCancel()
|
|
|
+ сам.Отменить()
|
|
|
return true
|
|
|
}
|
|
|
lstBattle := сам.СписПолучить()
|
|
|
for _, strOut := range lstBattle {
|
|
|
if strings.Contains(strOut, `>Ваш танк подбит.`) {
|
|
|
- // log._rintf("INFO Health.repair(): танк подбит\n")
|
|
|
- сам.temp.Set(0)
|
|
|
+ сам.здоровьеСейчас.Set(0)
|
|
|
сам.isEnd.Set()
|
|
|
- сам.fnCancel()
|
|
|
+ сам.Отменить()
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
|
@@ -141,16 +128,8 @@ func (сам *Здоровье) ЕслиУбит() bool {
|
|
|
}
|
|
|
|
|
|
// Ищет время восстановления ремки
|
|
|
-func (сам *Здоровье) findRepairTime() {
|
|
|
- defer func() {
|
|
|
- if сам.repairTime.IsReady() {
|
|
|
- return
|
|
|
- }
|
|
|
- // if сам.repairTime.IsChange() {
|
|
|
- // log._rintf("INFO Health.findRepair(): до ремки=%v\n", сам.repairTime.Get())
|
|
|
- // }
|
|
|
- }()
|
|
|
- if сам.repairTime.IsReady() {
|
|
|
+func (сам *Здоровье) найтиВремяВосстановления() {
|
|
|
+ if сам.отсчётАптечка.IsReady() {
|
|
|
return
|
|
|
}
|
|
|
var (
|
|
|
@@ -162,10 +141,7 @@ func (сам *Здоровье) findRepairTime() {
|
|
|
// <a href="pve?19-14.ILinkListener-currentControl-repairLink" class="simple-but blue"><span><span>12 секунд</span></span></a>
|
|
|
//
|
|
|
for ind, strOut = range lstBattle {
|
|
|
- if !strings.Contains(strOut, `ILinkListener-currentControl-repairLink`) {
|
|
|
- continue
|
|
|
- }
|
|
|
- if strings.Contains(strOut, ` секунд</span></span></a>`) {
|
|
|
+ if strings.Contains(strOut, `ILinkListener-currentControl-repairLink" class="simple-but blue"><span><span>`) {
|
|
|
еслиНайдено = true
|
|
|
break
|
|
|
}
|
|
|
@@ -177,17 +153,17 @@ func (сам *Здоровье) findRepairTime() {
|
|
|
// <a href="pve?19-14.ILinkListener-currentControl-repairLink" class="simple-but blue"><span><span>12 секунд</span></span></a>
|
|
|
lstTime := strings.Split(strOut, `ILinkListener-currentControl-repairLink" class="simple-but blue"><span><span>`)
|
|
|
if len(lstTime) < 2 {
|
|
|
- // log._rintf("ERRO Health.findRepair(): при попытке получить ссылку на ремонт, strOut=\n%v\n", strOut)
|
|
|
сам.isEnd.Set()
|
|
|
- сам.fnCancel()
|
|
|
+ сам.Отменить()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ strTime := lstTime[1]
|
|
|
+ strTime = strings.TrimSuffix(strTime, ` секунд</span></span></a>`)
|
|
|
+ if err := сам.отсчётАптечка.Уст(strTime); err != nil {
|
|
|
+ сам.isEnd.Set()
|
|
|
+ сам.Отменить()
|
|
|
return
|
|
|
}
|
|
|
- // strTime := lstTime[1]
|
|
|
- // lstTime = strings.Split(strTime, ` секунд</span></span></a>`)
|
|
|
- // strTime = lstTime[0]
|
|
|
- // if err := сам.repairTime.Set(strTime); err != nil {
|
|
|
- // log._rintf("ERRO Health.findRepair(): при установке времени восстановления ремки, err=\n\t%v\n", err)
|
|
|
- // }
|
|
|
}
|
|
|
|
|
|
// Восстанавливает здоровье (~)
|
|
|
@@ -219,7 +195,7 @@ func (сам *Здоровье) repair() {
|
|
|
if err != nil {
|
|
|
// log._rintf("ERRO Health.repair(): при выполнении GET-команды ремонта, err=\n\t%v\n", err)
|
|
|
сам.isEnd.Set()
|
|
|
- сам.fnCancel()
|
|
|
+ сам.Отменить()
|
|
|
return
|
|
|
}
|
|
|
сам.СтрОбновить(lstBattleOn)
|
|
|
@@ -227,117 +203,87 @@ func (сам *Здоровье) repair() {
|
|
|
}
|
|
|
|
|
|
// Ищет своё здоровье (~)
|
|
|
-// func (сам *Health) findHealth() error {
|
|
|
-// var (
|
|
|
-// ind int
|
|
|
-// strOut string
|
|
|
-// еслиНайдено bool
|
|
|
-// lstBattle = сам.СписПолучить()
|
|
|
-// )
|
|
|
-// if len(lstBattle) == 0 { // Принудительно обновим сражение
|
|
|
-// if err := сам.Сеть().Обновить(); err != nil {
|
|
|
-// сам.isEnd.Уст()
|
|
|
-// сам.fnCancel()
|
|
|
-// return fmt.Errorf("Health.findHealth(): после принудительного обновления lsBattleOn, err=\n\t%w", err)
|
|
|
-// }
|
|
|
-// }
|
|
|
-// for ind, strOut = range lstBattle {
|
|
|
-// if strings.Contains(strOut, `alt="`+сам.login+`"`) {
|
|
|
-// еслиНайдено = true
|
|
|
-// break
|
|
|
-// }
|
|
|
-// }
|
|
|
-// if !еслиНайдено { // Свой танк не найден
|
|
|
-// сам.isEnd.Уст()
|
|
|
-// сам.fnCancel()
|
|
|
-// return fmt.Errorf("Health.findHealth(): своё здоровье не найдено")
|
|
|
-// }
|
|
|
-// // Свой танк найден, ищем здоровье
|
|
|
-// ind += 11
|
|
|
-// strOut = lstBattle[ind]
|
|
|
-// lstHealth := strings.Split(strOut, `<div class="value-block lh1"><span><span>`)
|
|
|
-// strHealth := lstHealth[1]
|
|
|
-// lstHealth = strings.Split(strHealth, `</span></span></div>`)
|
|
|
-// strHealth = lstHealth[0]
|
|
|
-// iHealth, err := strconv.Atoi(strHealth)
|
|
|
-// if err != nil {
|
|
|
-// сам.isEnd.Уст()
|
|
|
-// сам.CancelBattle()
|
|
|
-// return fmt.Errorf("Health.findHealth(): здоровье(%v) не число, err=%w", strHealth, err)
|
|
|
-// }
|
|
|
-// сам.setHealth(iHealth)
|
|
|
-// return nil
|
|
|
-// }
|
|
|
-
|
|
|
-// setHealth -- устанавливает текущее здоровье
|
|
|
-// func (сам *Health) setHealth(val int) {
|
|
|
-// if val < 0 {
|
|
|
-// // log._rintf("WARN Health.setHealth(): кривое значение здоровья танка(%v)\n", val)
|
|
|
-// val = 0
|
|
|
-// }
|
|
|
-
|
|
|
-// if val > сам.full.Get() {
|
|
|
-// // log._rintf("WARN Health.setHealth(): кривое текущее здоровье, %v/%v\n", val, сам.full.Get())
|
|
|
-// сам.full.Set(val)
|
|
|
-// сам.temp.Set(val)
|
|
|
-// // сам.deltaOld = 0
|
|
|
-// сам.ВыстрелБлок().Сброс()
|
|
|
-// сам.isRepair.Сброс()
|
|
|
-// return
|
|
|
-// }
|
|
|
-
|
|
|
-// delta := сам.temp.Get() - val
|
|
|
-// // if delta > 0 { // Дельта будет больше нуля, если только
|
|
|
-// // if delta != сам.deltaOld {
|
|
|
-// // // log._rintf("INFO Health.setHealth(): потеря здоровья=%v/%v\n", -delta, val)
|
|
|
-// // сам.deltaOld = delta
|
|
|
-// // сам.temp.Set(val)
|
|
|
-// // }
|
|
|
-// // }
|
|
|
+func (сам *Здоровье) здоровьеНайти() {
|
|
|
+ var (
|
|
|
+ ind int
|
|
|
+ strOut string
|
|
|
+ еслиНайдено bool
|
|
|
+ lstBattle = сам.СписПолучить()
|
|
|
+ )
|
|
|
+ if len(lstBattle) == 0 { // Принудительно обновим сражение
|
|
|
+ сам.Обновить()
|
|
|
+ lstBattle = сам.СписПолучить()
|
|
|
+ }
|
|
|
+ // <div class="small bold green1 sh_b mb10 mt5">Половина коня</div>
|
|
|
+ for ind, strOut = range lstBattle {
|
|
|
+ if strings.Contains(strOut, `<div class="small bold green1 sh_b mb10 mt5">`+сам.логин+`"`) {
|
|
|
+ еслиНайдено = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !еслиНайдено { // Свой танк не найден
|
|
|
+ сам.isEnd.Set()
|
|
|
+ сам.Отменить()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // Свой танк найден, ищем здоровье
|
|
|
+ // <div class="value-block lh1"><span><span>500</span></span></div>
|
|
|
+ ind += 11
|
|
|
+ strOut = lstBattle[ind]
|
|
|
+ strHealth := strings.TrimPrefix(strOut, `<div class="value-block lh1"><span><span>`)
|
|
|
+ strHealth = strings.TrimSuffix(strHealth, `</span></span></div>`)
|
|
|
+ iHealth, err := strconv.Atoi(strHealth)
|
|
|
+ if err != nil {
|
|
|
+ сам.isEnd.Set()
|
|
|
+ сам.Отменить()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ сам.здоровьеУстановить(iHealth)
|
|
|
+}
|
|
|
|
|
|
-// switch {
|
|
|
-// case сам.isEnd.Получ():
|
|
|
-// сам.temp.Set(0)
|
|
|
-// сам.isEnd.Уст()
|
|
|
-// сам.CancelBattle()
|
|
|
-// return
|
|
|
-// case val == 0:
|
|
|
-// сам.temp.Set(0)
|
|
|
-// сам.isEnd.Уст()
|
|
|
-// сам.CancelBattle()
|
|
|
-// return
|
|
|
-// case val <= 500: // Запретить стрельбу
|
|
|
-// сам.ВыстрелБлок().Уст() // Установить запрет стрельбы пока слабое здоровье
|
|
|
-// сам.isRepair.Уст()
|
|
|
-// // log._rintf("WARN Health.setHealth(): низкий уровень здоровья(%v)\n", val)
|
|
|
-// сам.Манёвр()
|
|
|
-// case val > 500: // Разрешить стрельбы
|
|
|
-// сам.ВыстрелБлок().Сброс()
|
|
|
-// сам.isRepair.Сброс()
|
|
|
-// if delta > сам.full.Get()*4/10 { // Проверить на критичность падения здоровья на 40%
|
|
|
-// // log._rintf("WARN Health.setHealth(): большая разовая потеря здоровья(%v)\n", delta)
|
|
|
-// сам.Манёвр()
|
|
|
-// сам.isRepair.Уст()
|
|
|
-// return
|
|
|
-// }
|
|
|
-// }
|
|
|
+// здоровьеУстановить -- устанавливает текущее здоровье
|
|
|
+func (сам *Здоровье) здоровьеУстановить(здоровье int) {
|
|
|
+ if здоровье < 0 {
|
|
|
+ // log._rintf("WARN Health.здоровьеУстановить(): кривое значение здоровья танка(%v)\n", val)
|
|
|
+ здоровье = 0
|
|
|
+ }
|
|
|
+ дельта := сам.здоровьеСейчас.Get() - здоровье
|
|
|
+ if дельта < 0 { // Такое может быть, если было лечение
|
|
|
+ дельта = 0
|
|
|
+ }
|
|
|
+ if здоровье >= сам.здоровьеПолное.Get() {
|
|
|
+ // log._rintf("WARN Health.здоровьеУстановить(): кривое текущее здоровье, %v/%v\n", val, сам.full.Get())
|
|
|
+ сам.здоровьеПолное.Set(здоровье)
|
|
|
+ сам.здоровьеСейчас.Set(здоровье)
|
|
|
+ // сам.deltaOld = 0
|
|
|
+ сам.Выстрел().БлокСброс()
|
|
|
+ сам.еслиНадо.Reset()
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
-// isMask := сам.ВыстрелБлок().Получ()
|
|
|
-// switch isMask {
|
|
|
-// case true:
|
|
|
-// // сам.countLow++
|
|
|
-// // if сам.countLow >= 200 {
|
|
|
-// // сам.isEnd.Уст()
|
|
|
-// // сам.CancelBattle()
|
|
|
-// // return
|
|
|
-// // }
|
|
|
-// default:
|
|
|
-// // сам.countLow = 0
|
|
|
-// }
|
|
|
-// if val == сам.full.Get() {
|
|
|
-// сам.temp.Set(val)
|
|
|
-// сам.isRepair.Сброс()
|
|
|
-// сам.ВыстрелБлок().Сброс()
|
|
|
-// // сам.countLow = 0
|
|
|
-// }
|
|
|
-// }
|
|
|
+ switch {
|
|
|
+ case сам.isEnd.Get(): // Конец сражения
|
|
|
+ сам.здоровьеСейчас.Set(0)
|
|
|
+ сам.isEnd.Set()
|
|
|
+ сам.Отменить()
|
|
|
+ return
|
|
|
+ case здоровье <= 0: // Убит
|
|
|
+ сам.здоровьеСейчас.Set(0)
|
|
|
+ сам.isEnd.Set()
|
|
|
+ сам.Отменить()
|
|
|
+ return
|
|
|
+ case здоровье <= 500: // Запретить стрельбу
|
|
|
+ сам.Выстрел().БлокУст() // Установить запрет стрельбы пока слабое здоровье
|
|
|
+ сам.еслиНадо.Set()
|
|
|
+ сам.Манёвр().УстНадо()
|
|
|
+ case здоровье > 500: // Разрешить стрельбу
|
|
|
+ сам.Выстрел().БлокСброс()
|
|
|
+ сам.еслиНадо.Reset()
|
|
|
+ if дельта > сам.здоровьеПолное.Get()*4/10 { // Проверить на критичность падения здоровья на 40%
|
|
|
+ // log._rintf("WARN Health.здоровьеУстановить(): большая разовая потеря здоровья(%v)\n", delta)
|
|
|
+ сам.Манёвр().УстНадо()
|
|
|
+ сам.еслиНадо.Set()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|