|
@@ -19,20 +19,20 @@ import (
|
|
|
Контролирует состояние здоровья танка
|
|
Контролирует состояние здоровья танка
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-// Health -- контроль здоровья танка
|
|
|
|
|
-type Health struct {
|
|
|
|
|
- types.ИСражеиеДействие
|
|
|
|
|
- temp *healthtime.HealthTime // Изменяемое здоровье танка
|
|
|
|
|
- full *healthtime.HealthTime // Полное здоровье танка
|
|
|
|
|
- isRepair *isrepair.IsRepair // Необходимость восстановления
|
|
|
|
|
- repairTime *repairtime.RepairTime // Время до восстановления
|
|
|
|
|
- login string // Для поиска контрольных строк
|
|
|
|
|
- chTick chan int // Канал для ровной отправки тиков
|
|
|
|
|
- deltaOld int // Старая дельта потери здоровья
|
|
|
|
|
|
|
+// Здоровье -- контроль здоровья танка
|
|
|
|
|
+type Здоровье struct {
|
|
|
|
|
+ types.ИСражениеДействие
|
|
|
|
|
+ время *healthtime.HealthTime // Изменяемое здоровье танка
|
|
|
|
|
+ здоровПолн *healthtime.HealthTime // Полное здоровье танка
|
|
|
|
|
+ еслиНадоЛечить *isrepair.IsRepair // Необходимость восстановления
|
|
|
|
|
+ времяДоЛеч *repairtime.RepairTime // Время до восстановления
|
|
|
|
|
+ логин string // Для поиска контрольных строк
|
|
|
|
|
+ chTick chan int // Канал для ровной отправки тиков
|
|
|
|
|
+ здоровСтароеДельта int // Старая дельта потери здоровья
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// NewHealth -- возвращает новый *Health
|
|
|
|
|
-func NewHealth(battle types.ИСражеиеДействие, login string) (*Health, error) {
|
|
|
|
|
|
|
+// НовЗдоровье -- возвращает новый *Здоровье
|
|
|
|
|
+func НовЗдоровье(battle types.ИСражениеДействие, login string) (*Здоровье, error) {
|
|
|
{ // Предусловия
|
|
{ // Предусловия
|
|
|
if battle == nil {
|
|
if battle == nil {
|
|
|
return nil, fmt.Errorf("NewHealth(): battle is nil")
|
|
return nil, fmt.Errorf("NewHealth(): battle is nil")
|
|
@@ -41,37 +41,37 @@ func NewHealth(battle types.ИСражеиеДействие, login string) (*He
|
|
|
return nil, fmt.Errorf("NewHealth(): login is empty")
|
|
return nil, fmt.Errorf("NewHealth(): login is empty")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- sf := &Health{
|
|
|
|
|
- ИСражеиеДействие: battle,
|
|
|
|
|
- temp: healthtime.NewHealthTime(),
|
|
|
|
|
- full: healthtime.NewHealthTime(),
|
|
|
|
|
- isRepair: isrepair.NewIsRepair(),
|
|
|
|
|
- repairTime: repairtime.NewRepairTime(),
|
|
|
|
|
- login: login,
|
|
|
|
|
- chTick: make(chan int, 2),
|
|
|
|
|
|
|
+ sf := &Здоровье{
|
|
|
|
|
+ ИСражениеДействие: battle,
|
|
|
|
|
+ время: healthtime.NewHealthTime(),
|
|
|
|
|
+ здоровПолн: healthtime.NewHealthTime(),
|
|
|
|
|
+ еслиНадоЛечить: isrepair.NewIsRepair(),
|
|
|
|
|
+ времяДоЛеч: repairtime.NewRepairTime(),
|
|
|
|
|
+ логин: login,
|
|
|
|
|
+ chTick: make(chan int, 2),
|
|
|
}
|
|
}
|
|
|
go sf.makeTik()
|
|
go sf.makeTik()
|
|
|
- go sf.run()
|
|
|
|
|
|
|
+ go sf.пуск()
|
|
|
return sf, nil
|
|
return sf, nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Отправляе ттики с заданным равным интервалом
|
|
// Отправляе ттики с заданным равным интервалом
|
|
|
-func (sf *Health) makeTik() {
|
|
|
|
|
|
|
+func (сам *Здоровье) makeTik() {
|
|
|
defer func() {
|
|
defer func() {
|
|
|
- close(sf.chTick)
|
|
|
|
|
- sf.Отменить()
|
|
|
|
|
|
|
+ close(сам.chTick)
|
|
|
|
|
+ сам.ОтменитьДействие()
|
|
|
// log._rintf("Health.makeTick(): сражение завершёно\n")
|
|
// log._rintf("Health.makeTick(): сражение завершёно\n")
|
|
|
}()
|
|
}()
|
|
|
countLow := 0
|
|
countLow := 0
|
|
|
for {
|
|
for {
|
|
|
select {
|
|
select {
|
|
|
- case <-sf.Кнт().Done():
|
|
|
|
|
|
|
+ case <-сам.Кнт().Done():
|
|
|
return
|
|
return
|
|
|
default:
|
|
default:
|
|
|
- if sf.IsDeath() {
|
|
|
|
|
|
|
+ if сам.ЕслиМёртвый() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- switch sf.repairTime.Get() <= 0 {
|
|
|
|
|
|
|
+ switch сам.времяДоЛеч.Получ() <= 0 {
|
|
|
case true:
|
|
case true:
|
|
|
countLow++
|
|
countLow++
|
|
|
default:
|
|
default:
|
|
@@ -81,40 +81,43 @@ func (sf *Health) makeTik() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- sf.chTick <- 1
|
|
|
|
|
|
|
+ сам.chTick <- 1
|
|
|
time.Sleep(time.Second * 1)
|
|
time.Sleep(time.Second * 1)
|
|
|
- sf.repairTime.Dec()
|
|
|
|
|
|
|
+ сам.времяДоЛеч.Dec()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Главный цикл обработки здоровья в сражении
|
|
// Главный цикл обработки здоровья в сражении
|
|
|
-func (sf *Health) run() {
|
|
|
|
|
- for range sf.chTick {
|
|
|
|
|
- if err := sf.findHealth(); err != nil { // Найти свой здоровье
|
|
|
|
|
|
|
+func (сам *Здоровье) пуск() {
|
|
|
|
|
+ for range сам.chTick {
|
|
|
|
|
+ if err := сам.здоровьеНайти(); err != nil { // Найти свой здоровье
|
|
|
log.Printf("Health.run(): при попытке найти здоровье, err=\n\t%v\n", err)
|
|
log.Printf("Health.run(): при попытке найти здоровье, err=\n\t%v\n", err)
|
|
|
|
|
+ сам.ОтменитьДействие()
|
|
|
|
|
+ return
|
|
|
}
|
|
}
|
|
|
- sf.findRepairTime()
|
|
|
|
|
- if sf.ВыстрелБлок().Get() {
|
|
|
|
|
- if !sf.isRepair.Get() {
|
|
|
|
|
|
|
+ сам.времЛечитьНайти()
|
|
|
|
|
+ if сам.ВыстрелБлок().Get() {
|
|
|
|
|
+ if !сам.еслиНадоЛечить.Get() {
|
|
|
continue
|
|
continue
|
|
|
}
|
|
}
|
|
|
- sf.repair()
|
|
|
|
|
|
|
+ сам.лечить()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// Full -- возвращает объект полного здоровья танка
|
|
|
|
|
-func (sf *Health) Full() int {
|
|
|
|
|
- return sf.full.Get()
|
|
|
|
|
|
|
+// Полное -- возвращает объект полного здоровья танка
|
|
|
|
|
+func (сам *Здоровье) Полное() int {
|
|
|
|
|
+ return сам.здоровПолн.Get()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// IsDeath -- возвращает признак мертвичины танка
|
|
|
|
|
-func (sf *Health) IsDeath() bool {
|
|
|
|
|
- lstBattle := sf.СписПолучить()
|
|
|
|
|
|
|
+// ЕслиМёртвый -- возвращает признак мертвичины танка
|
|
|
|
|
+func (сам *Здоровье) ЕслиМёртвый() bool {
|
|
|
|
|
+ lstBattle := сам.СписПолучить()
|
|
|
for _, strOut := range lstBattle {
|
|
for _, strOut := range lstBattle {
|
|
|
if strings.Contains(strOut, `>Ваш танк подбит.`) {
|
|
if strings.Contains(strOut, `>Ваш танк подбит.`) {
|
|
|
// log._rintf("INFO Health.repair(): танк подбит\n")
|
|
// log._rintf("INFO Health.repair(): танк подбит\n")
|
|
|
- sf.temp.Set(0)
|
|
|
|
|
|
|
+ time.Sleep(time.Second * 10)
|
|
|
|
|
+ сам.ОтменитьДействие()
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -122,17 +125,16 @@ func (sf *Health) IsDeath() bool {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Ищет время восстановления ремки
|
|
// Ищет время восстановления ремки
|
|
|
-func (sf *Health) findRepairTime() {
|
|
|
|
|
|
|
+func (sf *Здоровье) времЛечитьНайти() {
|
|
|
defer func() {
|
|
defer func() {
|
|
|
- if sf.repairTime.IsReady() {
|
|
|
|
|
|
|
+ if sf.времяДоЛеч.ЕслиГотово() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- if sf.repairTime.IsChange() {
|
|
|
|
|
- log.Printf("Health.findRepair(): до ремки=%v\n", sf.repairTime.Get())
|
|
|
|
|
|
|
+ if sf.времяДоЛеч.ЕслиИзменилось() {
|
|
|
|
|
+ log.Printf("Health.findRepair(): до ремки=%v\n", sf.времяДоЛеч.Получ())
|
|
|
}
|
|
}
|
|
|
}()
|
|
}()
|
|
|
- if sf.repairTime.IsReady() {
|
|
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
|
|
|
|
+ if sf.времяДоЛеч.ЕслиГотово() {
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
var (
|
|
var (
|
|
@@ -167,17 +169,17 @@ func (sf *Health) findRepairTime() {
|
|
|
strTime := lstTime[1]
|
|
strTime := lstTime[1]
|
|
|
lstTime = strings.Split(strTime, ` секунд</span></span></a>`)
|
|
lstTime = strings.Split(strTime, ` секунд</span></span></a>`)
|
|
|
strTime = lstTime[0]
|
|
strTime = lstTime[0]
|
|
|
- if err := sf.repairTime.Set(strTime); err != nil {
|
|
|
|
|
|
|
+ if err := sf.времяДоЛеч.Set(strTime); err != nil {
|
|
|
// log._rintf("ERRO Health.findRepair(): при установке времени восстановления ремки, err=\n\t%v\n", err)
|
|
// log._rintf("ERRO Health.findRepair(): при установке времени восстановления ремки, err=\n\t%v\n", err)
|
|
|
time.Sleep(time.Second * 1)
|
|
time.Sleep(time.Second * 1)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Восстановливает здоровье (~)
|
|
// Восстановливает здоровье (~)
|
|
|
-func (sf *Health) repair() {
|
|
|
|
|
|
|
+func (сам *Здоровье) лечить() {
|
|
|
var (
|
|
var (
|
|
|
strOut string
|
|
strOut string
|
|
|
- lstBattleOn = sf.СписПолучить()
|
|
|
|
|
|
|
+ lstBattleOn = сам.СписПолучить()
|
|
|
isFindRepair bool
|
|
isFindRepair bool
|
|
|
ind int
|
|
ind int
|
|
|
)
|
|
)
|
|
@@ -190,7 +192,6 @@ func (sf *Health) repair() {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if !isFindRepair {
|
|
if !isFindRepair {
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
strOut = lstBattleOn[ind]
|
|
strOut = lstBattleOn[ind]
|
|
@@ -199,45 +200,45 @@ func (sf *Health) repair() {
|
|
|
strLink := lstLink[1]
|
|
strLink := lstLink[1]
|
|
|
lstLink = strings.Split(strLink, `" class="simple-but blue"><span><span>Ремкомплект</span></span></a>`)
|
|
lstLink = strings.Split(strLink, `" class="simple-but blue"><span><span>Ремкомплект</span></span></a>`)
|
|
|
strLink = "http://wartank.ru/" + lstLink[0]
|
|
strLink = "http://wartank.ru/" + lstLink[0]
|
|
|
- lstBattleOn, err := sf.Сеть().Get(strLink)
|
|
|
|
|
|
|
+ lstBattleOn, err := сам.Сеть().Get(strLink)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
// log._rintf("ERRO Health.repair(): при выполнении GET-команды ремонта, err=\n\t%v\n", err)
|
|
// log._rintf("ERRO Health.repair(): при выполнении GET-команды ремонта, err=\n\t%v\n", err)
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
|
|
|
|
+ сам.ОтменитьДействие()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
- if err = sf.СтрОбновить(lstBattleOn); err != nil {
|
|
|
|
|
|
|
+ if err = сам.СтрОбновить(lstBattleOn); err != nil {
|
|
|
// log._rintf("ERRO Health.repair(): при обновлении lstBattle, err=\n\t%v\n", err)
|
|
// log._rintf("ERRO Health.repair(): при обновлении lstBattle, err=\n\t%v\n", err)
|
|
|
time.Sleep(time.Second * 1)
|
|
time.Sleep(time.Second * 1)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
// sound.Repair()
|
|
// sound.Repair()
|
|
|
- sf.setHealth(sf.full.Get())
|
|
|
|
|
|
|
+ сам.уст(сам.здоровПолн.Get())
|
|
|
// log._rintf("INFO Health.repair(): здоровье восстановлено\n")
|
|
// log._rintf("INFO Health.repair(): здоровье восстановлено\n")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Ищет своё здоровье (~)
|
|
// Ищет своё здоровье (~)
|
|
|
-func (sf *Health) findHealth() error {
|
|
|
|
|
|
|
+func (сам *Здоровье) здоровьеНайти() error {
|
|
|
var (
|
|
var (
|
|
|
ind int
|
|
ind int
|
|
|
strOut string
|
|
strOut string
|
|
|
isFind bool
|
|
isFind bool
|
|
|
- lstBattle = sf.СписПолучить()
|
|
|
|
|
|
|
+ lstBattle = сам.СписПолучить()
|
|
|
)
|
|
)
|
|
|
if len(lstBattle) == 0 { // Принудительно обновим сражение
|
|
if len(lstBattle) == 0 { // Принудительно обновим сражение
|
|
|
- if err := sf.Сеть().UpdateLst(); err != nil {
|
|
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
|
|
|
|
+ if err := сам.Сеть().UpdateLst(); err != nil {
|
|
|
|
|
+ сам.ОтменитьДействие()
|
|
|
return fmt.Errorf("Health.findHealth(): пустой lsBattleOn, err=\n\t%w", err)
|
|
return fmt.Errorf("Health.findHealth(): пустой lsBattleOn, err=\n\t%w", err)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
for ind, strOut = range lstBattle {
|
|
for ind, strOut = range lstBattle {
|
|
|
- if strings.Contains(strOut, `alt="`+sf.login+`"`) {
|
|
|
|
|
|
|
+ if strings.Contains(strOut, `alt="`+сам.логин+`"`) {
|
|
|
isFind = true
|
|
isFind = true
|
|
|
break
|
|
break
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
if !isFind { // Свой танк не найден
|
|
if !isFind { // Свой танк не найден
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
|
|
- return fmt.Errorf("Health.findHealth(): своё здоровье не найдено")
|
|
|
|
|
|
|
+ сам.ОтменитьДействие()
|
|
|
|
|
+ return fmt.Errorf("Здоровье.здоровьеНайти(): своё здоровье не найдено")
|
|
|
}
|
|
}
|
|
|
// Свой танк найден, ищем здоровье
|
|
// Свой танк найден, ищем здоровье
|
|
|
ind += 11
|
|
ind += 11
|
|
@@ -248,56 +249,56 @@ func (sf *Health) findHealth() error {
|
|
|
strHealth = lstHealth[0]
|
|
strHealth = lstHealth[0]
|
|
|
iHealth, err := strconv.Atoi(strHealth)
|
|
iHealth, err := strconv.Atoi(strHealth)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- time.Sleep(time.Second * 1)
|
|
|
|
|
|
|
+ сам.ОтменитьДействие()
|
|
|
return fmt.Errorf("Health.findHealth(): здоровье(%v) не число, err=%w", strHealth, err)
|
|
return fmt.Errorf("Health.findHealth(): здоровье(%v) не число, err=%w", strHealth, err)
|
|
|
}
|
|
}
|
|
|
- sf.setHealth(iHealth)
|
|
|
|
|
|
|
+ сам.уст(iHealth)
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// setHealth -- устанавливает текущее здоровье
|
|
|
|
|
-func (sf *Health) setHealth(val int) {
|
|
|
|
|
|
|
+// уст -- устанавливает текущее здоровье
|
|
|
|
|
+func (sf *Здоровье) уст(val int) {
|
|
|
if val < 0 {
|
|
if val < 0 {
|
|
|
// log._rintf("WARN Health.setHealth(): кривое значение здоровья танка(%v)\n", val)
|
|
// log._rintf("WARN Health.setHealth(): кривое значение здоровья танка(%v)\n", val)
|
|
|
val = 0
|
|
val = 0
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if val > sf.full.Get() {
|
|
|
|
|
|
|
+ if val > sf.здоровПолн.Get() {
|
|
|
// log._rintf("WARN Health.setHealth(): кривое текущее здоровье, %v/%v\n", val, sf.full.Get())
|
|
// log._rintf("WARN Health.setHealth(): кривое текущее здоровье, %v/%v\n", val, sf.full.Get())
|
|
|
- sf.full.Set(val)
|
|
|
|
|
- sf.temp.Set(val)
|
|
|
|
|
- sf.deltaOld = 0
|
|
|
|
|
|
|
+ sf.здоровПолн.Set(val)
|
|
|
|
|
+ sf.время.Set(val)
|
|
|
|
|
+ sf.здоровСтароеДельта = 0
|
|
|
sf.ВыстрелБлок().Reset()
|
|
sf.ВыстрелБлок().Reset()
|
|
|
- sf.isRepair.Reset()
|
|
|
|
|
|
|
+ sf.еслиНадоЛечить.Reset()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- delta := sf.temp.Get() - val
|
|
|
|
|
|
|
+ delta := sf.время.Get() - val
|
|
|
if delta > 0 { // Дельта будет больше нуля, если только
|
|
if delta > 0 { // Дельта будет больше нуля, если только
|
|
|
- if delta != sf.deltaOld {
|
|
|
|
|
|
|
+ if delta != sf.здоровСтароеДельта {
|
|
|
// log._rintf("INFO Health.setHealth(): потеря здоровья=%v/%v\n", -delta, val)
|
|
// log._rintf("INFO Health.setHealth(): потеря здоровья=%v/%v\n", -delta, val)
|
|
|
- sf.deltaOld = delta
|
|
|
|
|
- sf.temp.Set(val)
|
|
|
|
|
|
|
+ sf.здоровСтароеДельта = delta
|
|
|
|
|
+ sf.время.Set(val)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
switch {
|
|
switch {
|
|
|
case val == 0:
|
|
case val == 0:
|
|
|
- sf.temp.Set(0)
|
|
|
|
|
- sf.Отменить()
|
|
|
|
|
|
|
+ sf.время.Set(0)
|
|
|
|
|
+ sf.ОтменитьДействие()
|
|
|
return
|
|
return
|
|
|
case val <= 500: // Запретить стрельбу
|
|
case val <= 500: // Запретить стрельбу
|
|
|
sf.ВыстрелБлок().Set() // Установить запрет стрельбы пока слабое здоровье
|
|
sf.ВыстрелБлок().Set() // Установить запрет стрельбы пока слабое здоровье
|
|
|
- sf.isRepair.Set()
|
|
|
|
|
|
|
+ sf.еслиНадоЛечить.Set()
|
|
|
// log._rintf("WARN Health.setHealth(): низкий уровень здоровья(%v)\n", val)
|
|
// log._rintf("WARN Health.setHealth(): низкий уровень здоровья(%v)\n", val)
|
|
|
sf.МанёврНадоУст()
|
|
sf.МанёврНадоУст()
|
|
|
case val > 500: // Разрешить стрельбы
|
|
case val > 500: // Разрешить стрельбы
|
|
|
sf.ВыстрелБлок().Reset()
|
|
sf.ВыстрелБлок().Reset()
|
|
|
- sf.isRepair.Reset()
|
|
|
|
|
- if delta > sf.full.Get()*4/10 { // Проверить на критичность падения здоровья на 40%
|
|
|
|
|
|
|
+ sf.еслиНадоЛечить.Reset()
|
|
|
|
|
+ if delta > sf.здоровПолн.Get()*4/10 { // Проверить на критичность падения здоровья на 40%
|
|
|
// log._rintf("WARN Health.setHealth(): большая разовая потеря здоровья(%v)\n", delta)
|
|
// log._rintf("WARN Health.setHealth(): большая разовая потеря здоровья(%v)\n", delta)
|
|
|
- sf.isRepair.Set()
|
|
|
|
|
|
|
+ sf.еслиНадоЛечить.Set()
|
|
|
sf.МанёврНадоУст()
|
|
sf.МанёврНадоУст()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|