|
|
@@ -22,33 +22,34 @@ import (
|
|
|
// Здоровье -- контроль здоровья танка
|
|
|
type Здоровье struct {
|
|
|
types.ИСражениеДействие
|
|
|
- время *healthtime.HealthTime // Изменяемое здоровье танка
|
|
|
- здоровПолн *healthtime.HealthTime // Полное здоровье танка
|
|
|
- еслиНадоЛечить *isrepair.IsRepair // Необходимость восстановления
|
|
|
- времяДоЛеч *repairtime.RepairTime // Время до восстановления
|
|
|
- логин string // Для поиска контрольных строк
|
|
|
- chTick chan int // Канал для ровной отправки тиков
|
|
|
- здоровСтароеДельта int // Старая дельта потери здоровья
|
|
|
+ время *healthtime.HealthTime // Изменяемое здоровье танка
|
|
|
+ здоровПолн *healthtime.HealthTime // Полное здоровье танка
|
|
|
+ здоровТекущ int // Старое доровье (до опроса)
|
|
|
+ еслиНадоЛечить *isrepair.IsRepair // Необходимость восстановления
|
|
|
+ времяДоЛеч *repairtime.RepairTime // Время до восстановления
|
|
|
+ логин string // Для поиска контрольных строк
|
|
|
+ канТик chan int // Канал для ровной отправки тиков
|
|
|
+ уронСтарый int // Дельта урона здоровью за прошлый шаг
|
|
|
}
|
|
|
|
|
|
// НовЗдоровье -- возвращает новый *Здоровье
|
|
|
-func НовЗдоровье(battle types.ИСражениеДействие, login string) (*Здоровье, error) {
|
|
|
+func НовЗдоровье(действие types.ИСражениеДействие, логин string) (*Здоровье, error) {
|
|
|
{ // Предусловия
|
|
|
- if battle == nil {
|
|
|
- return nil, fmt.Errorf("NewHealth(): battle is nil")
|
|
|
+ if действие == nil {
|
|
|
+ return nil, fmt.Errorf("НовЗдоровье(): действие==nil")
|
|
|
}
|
|
|
- if login == "" {
|
|
|
- return nil, fmt.Errorf("NewHealth(): login is empty")
|
|
|
+ if логин == "" {
|
|
|
+ return nil, fmt.Errorf("НовЗдоровье(): логин пустой")
|
|
|
}
|
|
|
}
|
|
|
sf := &Здоровье{
|
|
|
- ИСражениеДействие: battle,
|
|
|
+ ИСражениеДействие: действие,
|
|
|
время: healthtime.NewHealthTime(),
|
|
|
здоровПолн: healthtime.NewHealthTime(),
|
|
|
еслиНадоЛечить: isrepair.NewIsRepair(),
|
|
|
времяДоЛеч: repairtime.NewRepairTime(),
|
|
|
- логин: login,
|
|
|
- chTick: make(chan int, 2),
|
|
|
+ логин: логин,
|
|
|
+ канТик: make(chan int, 2),
|
|
|
}
|
|
|
go sf.makeTik()
|
|
|
go sf.пуск()
|
|
|
@@ -58,9 +59,9 @@ func НовЗдоровье(battle types.ИСражениеДействие, log
|
|
|
// Отправляе ттики с заданным равным интервалом
|
|
|
func (сам *Здоровье) makeTik() {
|
|
|
defer func() {
|
|
|
- close(сам.chTick)
|
|
|
- сам.ОтменитьДействие()
|
|
|
- // log._rintf("Health.makeTick(): сражение завершёно\n")
|
|
|
+ close(сам.канТик)
|
|
|
+ сам.Отменить()
|
|
|
+ // log._rintf("Здоровье.makeTick(): сражение завершёно\n")
|
|
|
}()
|
|
|
countLow := 0
|
|
|
for {
|
|
|
@@ -81,7 +82,7 @@ func (сам *Здоровье) makeTik() {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
- сам.chTick <- 1
|
|
|
+ сам.канТик <- 1
|
|
|
time.Sleep(time.Second * 1)
|
|
|
сам.времяДоЛеч.Dec()
|
|
|
}
|
|
|
@@ -89,17 +90,16 @@ func (сам *Здоровье) makeTik() {
|
|
|
|
|
|
// Главный цикл обработки здоровья в сражении
|
|
|
func (сам *Здоровье) пуск() {
|
|
|
- for range сам.chTick {
|
|
|
+ defer func() {
|
|
|
+ сам.Отменить()
|
|
|
+ }()
|
|
|
+ for range сам.канТик {
|
|
|
if err := сам.здоровьеНайти(); err != nil { // Найти свой здоровье
|
|
|
- log.Printf("Health.run(): при попытке найти здоровье, err=\n\t%v\n", err)
|
|
|
- сам.ОтменитьДействие()
|
|
|
+ log.Printf("Здоровье.run(): при попытке найти здоровье, err=\n\t%v\n", err)
|
|
|
return
|
|
|
}
|
|
|
сам.времЛечитьНайти()
|
|
|
- if сам.ВыстрелБлок().Get() {
|
|
|
- if !сам.еслиНадоЛечить.Get() {
|
|
|
- continue
|
|
|
- }
|
|
|
+ if сам.еслиНадоЛечить.Get() {
|
|
|
сам.лечить()
|
|
|
}
|
|
|
}
|
|
|
@@ -115,9 +115,8 @@ func (сам *Здоровье) ЕслиМёртвый() bool {
|
|
|
lstBattle := сам.СписПолучить()
|
|
|
for _, strOut := range lstBattle {
|
|
|
if strings.Contains(strOut, `>Ваш танк подбит.`) {
|
|
|
- // log._rintf("INFO Health.repair(): танк подбит\n")
|
|
|
- time.Sleep(time.Second * 10)
|
|
|
- сам.ОтменитьДействие()
|
|
|
+ // log._rintf("INFO Здоровье.repair(): танк подбит\n")
|
|
|
+ сам.Отменить()
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
|
@@ -125,21 +124,21 @@ func (сам *Здоровье) ЕслиМёртвый() bool {
|
|
|
}
|
|
|
|
|
|
// Ищет время восстановления ремки
|
|
|
-func (sf *Здоровье) времЛечитьНайти() {
|
|
|
+func (сам *Здоровье) времЛечитьНайти() {
|
|
|
defer func() {
|
|
|
- if sf.времяДоЛеч.ЕслиГотово() {
|
|
|
+ if сам.времяДоЛеч.ЕслиМожно() {
|
|
|
return
|
|
|
}
|
|
|
- if sf.времяДоЛеч.ЕслиИзменилось() {
|
|
|
- log.Printf("Health.findRepair(): до ремки=%v\n", sf.времяДоЛеч.Получ())
|
|
|
+ if сам.времяДоЛеч.ЕслиИзменилось() {
|
|
|
+ log.Printf("Здоровье.findRepair(): до ремки=%v\n", сам.времяДоЛеч.Получ())
|
|
|
}
|
|
|
}()
|
|
|
- if sf.времяДоЛеч.ЕслиГотово() {
|
|
|
+ if сам.времяДоЛеч.ЕслиМожно() {
|
|
|
return
|
|
|
}
|
|
|
var (
|
|
|
strOut string
|
|
|
- lstBattle = sf.СписПолучить()
|
|
|
+ lstBattle = сам.СписПолучить()
|
|
|
isFind bool
|
|
|
ind int
|
|
|
)
|
|
|
@@ -155,23 +154,22 @@ func (sf *Здоровье) времЛечитьНайти() {
|
|
|
}
|
|
|
}
|
|
|
if !isFind {
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
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)
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
+ // log._rintf("ERRO Здоровье.findRepair(): при попытке получить ссылку на ремонт, strOut=\n%v\n", strOut)
|
|
|
+ сам.Отменить()
|
|
|
return
|
|
|
}
|
|
|
strTime := lstTime[1]
|
|
|
lstTime = strings.Split(strTime, ` секунд</span></span></a>`)
|
|
|
strTime = lstTime[0]
|
|
|
- if err := sf.времяДоЛеч.Set(strTime); err != nil {
|
|
|
- // log._rintf("ERRO Health.findRepair(): при установке времени восстановления ремки, err=\n\t%v\n", err)
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
+ if err := сам.времяДоЛеч.Set(strTime); err != nil {
|
|
|
+ // log._rintf("ERRO Здоровье.findRepair(): при установке времени восстановления ремки, err=\n\t%v\n", err)
|
|
|
+ return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -202,18 +200,17 @@ func (сам *Здоровье) лечить() {
|
|
|
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)
|
|
|
- сам.ОтменитьДействие()
|
|
|
+ // log._rintf("ERRO Здоровье.repair(): при выполнении GET-команды ремонта, err=\n\t%v\n", err)
|
|
|
+ сам.Отменить()
|
|
|
return
|
|
|
}
|
|
|
if err = сам.СтрОбновить(lstBattleOn); err != nil {
|
|
|
- // log._rintf("ERRO Health.repair(): при обновлении lstBattle, err=\n\t%v\n", err)
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
+ // log._rintf("ERRO Здоровье.repair(): при обновлении lstBattle, err=\n\t%v\n", err)
|
|
|
return
|
|
|
}
|
|
|
// sound.Repair()
|
|
|
сам.уст(сам.здоровПолн.Get())
|
|
|
- // log._rintf("INFO Health.repair(): здоровье восстановлено\n")
|
|
|
+ // log._rintf("INFO Здоровье.repair(): здоровье восстановлено\n")
|
|
|
}
|
|
|
|
|
|
// Ищет своё здоровье (~)
|
|
|
@@ -226,8 +223,8 @@ func (сам *Здоровье) здоровьеНайти() error {
|
|
|
)
|
|
|
if len(lstBattle) == 0 { // Принудительно обновим сражение
|
|
|
if err := сам.Сеть().UpdateLst(); err != nil {
|
|
|
- сам.ОтменитьДействие()
|
|
|
- return fmt.Errorf("Health.findHealth(): пустой lsBattleOn, err=\n\t%w", err)
|
|
|
+ сам.Отменить()
|
|
|
+ return fmt.Errorf("Здоровье.здоровьеНайти(): пустой lstBattle, err=\n\t%w", err)
|
|
|
}
|
|
|
}
|
|
|
for ind, strOut = range lstBattle {
|
|
|
@@ -237,7 +234,7 @@ func (сам *Здоровье) здоровьеНайти() error {
|
|
|
}
|
|
|
}
|
|
|
if !isFind { // Свой танк не найден
|
|
|
- сам.ОтменитьДействие()
|
|
|
+ сам.Отменить()
|
|
|
return fmt.Errorf("Здоровье.здоровьеНайти(): своё здоровье не найдено")
|
|
|
}
|
|
|
// Свой танк найден, ищем здоровье
|
|
|
@@ -249,58 +246,53 @@ func (сам *Здоровье) здоровьеНайти() error {
|
|
|
strHealth = lstHealth[0]
|
|
|
iHealth, err := strconv.Atoi(strHealth)
|
|
|
if err != nil {
|
|
|
- сам.ОтменитьДействие()
|
|
|
- return fmt.Errorf("Health.findHealth(): здоровье(%v) не число, err=%w", strHealth, err)
|
|
|
+ сам.Отменить()
|
|
|
+ return fmt.Errorf("Здоровье.здоровьеНайти(): здоровье(%v) не число, err=%w", strHealth, err)
|
|
|
}
|
|
|
сам.уст(iHealth)
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
// уст -- устанавливает текущее здоровье
|
|
|
-func (sf *Здоровье) уст(val int) {
|
|
|
- if val < 0 {
|
|
|
- // log._rintf("WARN Health.setHealth(): кривое значение здоровья танка(%v)\n", val)
|
|
|
- val = 0
|
|
|
+func (сам *Здоровье) уст(знач int) {
|
|
|
+ if знач <= 0 {
|
|
|
+ // log._rintf("WARN Здоровье.уст(): кривое значение здоровья танка(%v)\n", val)
|
|
|
+ знач = 0
|
|
|
+ сам.Отменить()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- if val > sf.здоровПолн.Get() {
|
|
|
- // log._rintf("WARN Health.setHealth(): кривое текущее здоровье, %v/%v\n", val, sf.full.Get())
|
|
|
- sf.здоровПолн.Set(val)
|
|
|
- sf.время.Set(val)
|
|
|
- sf.здоровСтароеДельта = 0
|
|
|
- sf.ВыстрелБлок().Reset()
|
|
|
- sf.еслиНадоЛечить.Reset()
|
|
|
+ if знач > сам.здоровПолн.Get() {
|
|
|
+ // log._rintf("WARN Здоровье.уст(): кривое текущее здоровье, %v/%v\n", val, sf.full.Get())
|
|
|
+ сам.здоровПолн.Set(знач)
|
|
|
+ сам.ВыстрелБлок().Reset()
|
|
|
+ сам.еслиНадоЛечить.Reset()
|
|
|
+ сам.здоровТекущ = знач
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- delta := sf.время.Get() - val
|
|
|
- if delta > 0 { // Дельта будет больше нуля, если только
|
|
|
- if delta != sf.здоровСтароеДельта {
|
|
|
- // log._rintf("INFO Health.setHealth(): потеря здоровья=%v/%v\n", -delta, val)
|
|
|
- sf.здоровСтароеДельта = delta
|
|
|
- sf.время.Set(val)
|
|
|
+ дельта := сам.здоровТекущ - знач
|
|
|
+ if дельта > 0 { // Дельта будет больше нуля, если только было попадание в свой танк
|
|
|
+ if дельта != сам.уронСтарый {
|
|
|
+ // log._rintf("INFO Здоровье.уст(): потеря здоровья=%v/%v\n", -delta, val)
|
|
|
+ сам.уронСтарый = дельта
|
|
|
+ сам.здоровТекущ -= знач
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- switch {
|
|
|
- case val == 0:
|
|
|
- sf.время.Set(0)
|
|
|
- sf.ОтменитьДействие()
|
|
|
+ if знач <= 500 { // Запретить стрельбу
|
|
|
+ сам.ВыстрелБлок().Set() // Установить запрет стрельбы пока слабое здоровье
|
|
|
+ сам.еслиНадоЛечить.Set()
|
|
|
+ // log._rintf("WARN Здоровье.setHealth(): низкий уровень здоровья(%v)\n", val)
|
|
|
+ сам.МанёврНадоУст()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // Разрешить стрельбу
|
|
|
+ сам.ВыстрелБлок().Reset()
|
|
|
+ сам.еслиНадоЛечить.Reset()
|
|
|
+ if дельта > сам.здоровПолн.Get()*4/10 { // Проверить на критичность падения здоровья на 40%
|
|
|
+ // log._rintf("WARN Здоровье.setHealth(): большая разовая потеря здоровья(%v)\n", delta)
|
|
|
+ сам.МанёврНадоУст()
|
|
|
return
|
|
|
- case val <= 500: // Запретить стрельбу
|
|
|
- sf.ВыстрелБлок().Set() // Установить запрет стрельбы пока слабое здоровье
|
|
|
- sf.еслиНадоЛечить.Set()
|
|
|
- // log._rintf("WARN Health.setHealth(): низкий уровень здоровья(%v)\n", val)
|
|
|
- sf.МанёврНадоУст()
|
|
|
- case val > 500: // Разрешить стрельбы
|
|
|
- sf.ВыстрелБлок().Reset()
|
|
|
- sf.еслиНадоЛечить.Reset()
|
|
|
- if delta > sf.здоровПолн.Get()*4/10 { // Проверить на критичность падения здоровья на 40%
|
|
|
- // log._rintf("WARN Health.setHealth(): большая разовая потеря здоровья(%v)\n", delta)
|
|
|
- sf.еслиНадоЛечить.Set()
|
|
|
- sf.МанёврНадоУст()
|
|
|
- return
|
|
|
- }
|
|
|
}
|
|
|
}
|