| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- package health
- import (
- // "log"
- // "strconv"
- "strings"
- "time"
- . "wartank/app/lev0/types"
- "wartank/app/lev1/health/health_time"
- "wartank/app/lev1/repair_time"
- // "wartank/internal/components/sound"
- . "gitp78su.ipnodns.ru/svi/kern"
- . "gitp78su.ipnodns.ru/svi/kern/kc/helpers"
- . "gitp78su.ipnodns.ru/svi/kern/krn/ktypes"
- )
- /*
- Контролирует состояние здоровья танка
- */
- // Здоровье -- контроль здоровья танка
- type Здоровье struct {
- ИСражениеПроцесс // FIXME:
- fnCancel func()
- temp *health_time.HealthTime // Изменяемое здоровье танка
- full *health_time.HealthTime // Полное здоровье танка
- isRepair ISafeBool // Необходимость восстановления
- repairTime *repair_time.RepairTime // Время до восстановления
- isEnd ISafeBool // Ссылка на признак конца сражения
- login string // Для поиска контрольных строк
- chTick chan int // Канал для ровной отправки тиков
- // deltaOld int // Старая дельта потери здоровья
- // countLow int
- ctxBattle ILocalCtx // Контекст сражения
- }
- // НовЗдоровье -- возвращает новый *Health
- func НовЗдоровье(проц ИСражениеПроцесс) *Здоровье {
- Hassert(проц != nil, "НовЗдоровье(): ИСражениеПроцесс == nil")
- логин := проц.Бот().Имя()
- сам := &Здоровье{
- ИСражениеПроцесс: проц,
- fnCancel: проц.Отменить,
- ctxBattle: проц.Бот().КонтБот(),
- temp: health_time.NewHealthTime(),
- full: health_time.NewHealthTime(),
- isRepair: NewSafeBool(),
- repairTime: repair_time.NewRepairTime(),
- isEnd: проц.ЕслиКонец(),
- login: логин,
- chTick: make(chan int, 2),
- }
- go сам.makeTik()
- go сам.run()
- return сам
- }
- // Отправляет тики с заданным равным интервалом
- func (сам *Здоровье) makeTik() {
- defer func() {
- сам.fnCancel()
- close(сам.chTick)
- // log._rintf("Health.makeTick(): сражение завершёно\n")
- }()
- count := 0
- repairTime := 0
- for {
- select {
- case <-сам.ctxBattle.Ctx().Done():
- return
- default:
- if сам.ЕслиУбит() {
- 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 (сам *Здоровье) run() {
- for {
- select {
- case <-сам.ctxBattle.Ctx().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() {
- go сам.repair()
- }
- }
- }
- }
- // Full -- возвращает объект полного здоровья танка
- func (сам *Здоровье) Full() int {
- return сам.full.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)
- сам.isEnd.Set()
- сам.fnCancel()
- return true
- }
- }
- return сам.isEnd.Get()
- }
- // Ищет время восстановления ремки
- func (сам *Здоровье) 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.Set()
- сам.fnCancel()
- 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 (сам *Здоровье) 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.Set()
- сам.fnCancel()
- return
- }
- if err = сам.СтрОбновить(lstBattleOn); err != nil {
- // log._rintf("ERRO Health.repair(): при обновлении lstBattle, err=\n\t%v\n", err)
- сам.isEnd.Set()
- сам.Отменить()
- 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
- // }
- // }
|