|
|
@@ -1,358 +0,0 @@
|
|
|
-package health
|
|
|
-
|
|
|
-import (
|
|
|
- "context"
|
|
|
- "fmt"
|
|
|
-
|
|
|
- // "log"
|
|
|
- // "strconv"
|
|
|
- "strings"
|
|
|
- "time"
|
|
|
-
|
|
|
- . "wartank/app/lev0/types"
|
|
|
- "wartank/app/lev2/arena_division/div_war/div_war_on/health/health_time"
|
|
|
- "wartank/app/lev2/arena_division/div_war/div_war_on/health/repair_time"
|
|
|
- // "wartank/internal/components/sound"
|
|
|
- "wartank/kernel"
|
|
|
- . "wartank/kernel/kernel_types"
|
|
|
-)
|
|
|
-
|
|
|
-/*
|
|
|
- Контролирует состояние здоровья танка
|
|
|
-*/
|
|
|
-
|
|
|
-// Health -- контроль здоровья танка
|
|
|
-type Health struct {
|
|
|
- ИДивизияВойнаДействие // FIXME:
|
|
|
- fnCancel func()
|
|
|
- temp *health_time.HealthTime // Изменяемое здоровье танка
|
|
|
- full *health_time.HealthTime // Полное здоровье танка
|
|
|
- isRepair ИБезопБул // Необходимость восстановления
|
|
|
- repairTime *repair_time.RepairTime // Время до восстановления
|
|
|
- isEnd ИБезопБул // Ссылка на признак конца сражения
|
|
|
- login string // Для поиска контрольных строк
|
|
|
- chTick chan int // Канал для ровной отправки тиков
|
|
|
- // deltaOld int // Старая дельта потери здоровья
|
|
|
- // countLow int
|
|
|
- ctxBattle context.Context // Контекст сражения
|
|
|
-}
|
|
|
-
|
|
|
-// NewHealth -- возвращает новый *Health
|
|
|
-func NewHealth(дивВойна ИДивизияВойнаДействие, isEnd ИБезопБул, login string) (*Health, error) {
|
|
|
- { // Предусловия
|
|
|
- if дивВойна == nil {
|
|
|
- return nil, fmt.Errorf("NewHealth(): дивВойна is nil")
|
|
|
- }
|
|
|
- if isEnd == nil {
|
|
|
- return nil, fmt.Errorf("NewHealth(): isEnd is nil")
|
|
|
- }
|
|
|
- if login == "" {
|
|
|
- return nil, fmt.Errorf("NewHealth(): login is empty")
|
|
|
- }
|
|
|
- }
|
|
|
- сам := &Health{
|
|
|
- ИДивизияВойнаДействие: дивВойна,
|
|
|
- fnCancel: дивВойна.CancelBattle,
|
|
|
- ctxBattle: дивВойна.Ctx(),
|
|
|
- temp: health_time.NewHealthTime(),
|
|
|
- full: health_time.NewHealthTime(),
|
|
|
- isRepair: kernel.НовБезопБул(),
|
|
|
- repairTime: repair_time.NewRepairTime(),
|
|
|
- isEnd: дивВойна.ЕслиКонец(),
|
|
|
- login: login,
|
|
|
- chTick: make(chan int, 2),
|
|
|
- }
|
|
|
- go сам.makeTik()
|
|
|
- go сам.run()
|
|
|
- return сам, nil
|
|
|
-}
|
|
|
-
|
|
|
-// Отправляет тики с заданным равным интервалом
|
|
|
-func (сам *Health) makeTik() {
|
|
|
- defer func() {
|
|
|
- сам.CancelBattle()
|
|
|
- close(сам.chTick)
|
|
|
- // log._rintf("Health.makeTick(): сражение завершёно\n")
|
|
|
- }()
|
|
|
- count := 0
|
|
|
- repairTime := 0
|
|
|
- for {
|
|
|
- select {
|
|
|
- case <-сам.ctxBattle.Done():
|
|
|
- return
|
|
|
- default:
|
|
|
- if сам.IsDeath() {
|
|
|
- return
|
|
|
- }
|
|
|
- if сам.repairTime.Get() == repairTime {
|
|
|
- count++
|
|
|
- } else {
|
|
|
- repairTime = сам.repairTime.Get()
|
|
|
- count = 0
|
|
|
- }
|
|
|
- if count > 90 {
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
- сам.chTick <- 1
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
- сам.repairTime.Dec()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Главный цикл обработки здоровья в сражении
|
|
|
-func (сам *Health) run() {
|
|
|
- for {
|
|
|
- select {
|
|
|
- case <-сам.ctxBattle.Done():
|
|
|
- сам.isEnd.Уст()
|
|
|
- return
|
|
|
- case <-сам.chTick:
|
|
|
- // if err := сам.findHealth(); err != nil { // Найти свой здоровье
|
|
|
- // // log._rintf("ERRO Health.run(): при попытке найти здоровье, err=\n\t%v\n", err)
|
|
|
- // }
|
|
|
- сам.findRepairTime()
|
|
|
- if сам.ВыстрелБлок().Получ() {
|
|
|
- if сам.isRepair.Получ() {
|
|
|
- go сам.repair()
|
|
|
- }
|
|
|
- continue
|
|
|
- }
|
|
|
- if сам.isRepair.Получ() {
|
|
|
- go сам.repair()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Full -- возвращает объект полного здоровья танка
|
|
|
-func (сам *Health) Full() int {
|
|
|
- return сам.full.Get()
|
|
|
-}
|
|
|
-
|
|
|
-// IsDeath -- возвращает признак мертвичины танка
|
|
|
-func (сам *Health) IsDeath() bool {
|
|
|
- if сам.isEnd.Получ() {
|
|
|
- сам.fnCancel()
|
|
|
- return true
|
|
|
- }
|
|
|
- lstBattle := сам.СписПолучить()
|
|
|
- for _, strOut := range lstBattle {
|
|
|
- if strings.Contains(strOut, `>Ваш танк подбит.`) {
|
|
|
- // log._rintf("INFO Health.repair(): танк подбит\n")
|
|
|
- сам.temp.Set(0)
|
|
|
- сам.isEnd.Уст()
|
|
|
- сам.CancelBattle()
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
- return сам.isEnd.Получ()
|
|
|
-}
|
|
|
-
|
|
|
-// Ищет время восстановления ремки
|
|
|
-func (сам *Health) findRepairTime() {
|
|
|
- defer func() {
|
|
|
- if сам.repairTime.IsReady() {
|
|
|
- return
|
|
|
- }
|
|
|
- // if сам.repairTime.IsChange() {
|
|
|
- // log._rintf("INFO Health.findRepair(): до ремки=%v\n", сам.repairTime.Get())
|
|
|
- // }
|
|
|
- }()
|
|
|
- if сам.repairTime.IsReady() {
|
|
|
- return
|
|
|
- }
|
|
|
- var (
|
|
|
- strOut string
|
|
|
- lstBattle = сам.СписПолучить()
|
|
|
- еслиНайдено bool
|
|
|
- ind int
|
|
|
- )
|
|
|
- // <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>`) {
|
|
|
- еслиНайдено = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if !еслиНайдено {
|
|
|
- return
|
|
|
- }
|
|
|
- strOut = lstBattle[ind]
|
|
|
- // <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.Уст()
|
|
|
- сам.CancelBattle()
|
|
|
- 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)
|
|
|
- // }
|
|
|
-}
|
|
|
-
|
|
|
-// Восстанавливает здоровье (~)
|
|
|
-func (сам *Health) repair() {
|
|
|
- var (
|
|
|
- strOut string
|
|
|
- lstBattleOn = сам.СписПолучить()
|
|
|
- еслиНайденоRepair bool
|
|
|
- ind int
|
|
|
- )
|
|
|
- // <span>Ремкомплект</span>
|
|
|
- // <a href="pve?19-14.ILinkListener-currentControl-repairLink" class="simple-but blue"><span><span>Ремкомплект</span></span></a>
|
|
|
- for ind, strOut = range lstBattleOn {
|
|
|
- if strings.Contains(strOut, `<span>Ремкомплект</span>`) {
|
|
|
- еслиНайденоRepair = true
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if !еслиНайденоRepair {
|
|
|
- return
|
|
|
- }
|
|
|
- strOut = lstBattleOn[ind]
|
|
|
- // <a href="pve?6-26.ILinkListener-currentControl-repairLink" class="simple-but blue"><span><span>Ремкомплект</span></span></a>
|
|
|
- lstLink := strings.Split(strOut, `<a href="`)
|
|
|
- strLink := lstLink[1]
|
|
|
- lstLink = strings.Split(strLink, `" class="simple-but blue"><span><span>Ремкомплект</span></span></a>`)
|
|
|
- strLink = "https://wartank.ru/" + lstLink[0]
|
|
|
- lstBattleOn, err := сам.Сеть().Get(strLink)
|
|
|
- if err != nil {
|
|
|
- // log._rintf("ERRO Health.repair(): при выполнении GET-команды ремонта, err=\n\t%v\n", err)
|
|
|
- сам.isEnd.Уст()
|
|
|
- сам.CancelBattle()
|
|
|
- return
|
|
|
- }
|
|
|
- if err = сам.СтрОбновить(lstBattleOn); err != nil {
|
|
|
- // log._rintf("ERRO Health.repair(): при обновлении lstBattle, err=\n\t%v\n", err)
|
|
|
- сам.isEnd.Уст()
|
|
|
- сам.CancelBattle()
|
|
|
- return
|
|
|
- }
|
|
|
- // sound.Repair()
|
|
|
- // log._rintf("INFO Health.repair(): здоровье восстановлено\n")
|
|
|
-}
|
|
|
-
|
|
|
-// Ищет своё здоровье (~)
|
|
|
-// 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)
|
|
|
-// // }
|
|
|
-// // }
|
|
|
-
|
|
|
-// 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
|
|
|
-// }
|
|
|
-// }
|
|
|
-
|
|
|
-// 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
|
|
|
-// }
|
|
|
-// }
|