From 7d477ba35a2d81e918b13adbab4372edcd447838 Mon Sep 17 00:00:00 2001
From: Anton Vakhrushev <anwinged@ya.ru>
Date: Thu, 15 Oct 2020 10:26:07 +0300
Subject: [PATCH] Display hero health

---
 src/Container.ts              |  5 ++++-
 src/ControlPanel.ts           |  6 ++++++
 src/Core/Hero.ts              |  4 ++++
 src/Dashboard/Dashboard.vue   |  5 ++++-
 src/Dashboard/HeroView.vue    | 26 ++++++++++++++++++++++++++
 src/Executor.ts               |  8 ++------
 src/Grabber/GrabberManager.ts | 18 ++++++++++++------
 7 files changed, 58 insertions(+), 14 deletions(-)
 create mode 100644 src/Dashboard/HeroView.vue

diff --git a/src/Container.ts b/src/Container.ts
index 0f19f95..0837200 100644
--- a/src/Container.ts
+++ b/src/Container.ts
@@ -86,7 +86,10 @@ export class Container {
         this._grabberManager =
             this._grabberManager ||
             (() => {
-                return new GrabberManager(this.villageFactory);
+                return new GrabberManager(
+                    this.villageFactory,
+                    new ConsoleLogger(GrabberManager.name)
+                );
             })();
         return this._grabberManager;
     }
diff --git a/src/ControlPanel.ts b/src/ControlPanel.ts
index ecdbb7b..2e7e00b 100644
--- a/src/ControlPanel.ts
+++ b/src/ControlPanel.ts
@@ -23,6 +23,8 @@ import { timestamp } from './Helpers/Time';
 import { notify, parseLocation, waitForLoad } from './Helpers/Browser';
 import { Action } from './Queue/Action';
 import { Task } from './Queue/Task';
+import { HeroAttributes } from './Core/Hero';
+import { HeroStorage } from './Storage/HeroStorage';
 
 Vue.use(Vuex);
 
@@ -31,6 +33,7 @@ interface GameState {
     version: string;
     activeVillageState: VillageState | undefined;
     villageStates: ReadonlyArray<VillageState>;
+    heroAttr: HeroAttributes;
     taskList: ReadonlyArray<Task>;
     actionList: ReadonlyArray<Action>;
     pauseSeconds: number;
@@ -64,17 +67,20 @@ export class ControlPanel {
         const villageFactory = this.villageFactory;
 
         const executionState = new ExecutionStorage();
+        const heroStorage = new HeroStorage();
 
         const state: GameState = {
             name: 'Control',
             version: this.version,
             activeVillageState: undefined,
             villageStates: [],
+            heroAttr: HeroAttributes.default(),
             taskList: [],
             actionList: [],
             pauseSeconds: 0,
 
             refresh() {
+                this.heroAttr = heroStorage.getAttributes();
                 this.taskList = scheduler.getTaskItems();
                 this.actionList = scheduler.getActionItems();
                 const { pauseTs } = executionState.getExecutionSettings();
diff --git a/src/Core/Hero.ts b/src/Core/Hero.ts
index 5c3b6a2..64ac65d 100644
--- a/src/Core/Hero.ts
+++ b/src/Core/Hero.ts
@@ -6,6 +6,10 @@ export class HeroAttributes {
     constructor(health: number) {
         this.health = health;
     }
+
+    static default() {
+        return new HeroAttributes(0);
+    }
 }
 
 export type HeroAllResourcesType = 'all';
diff --git a/src/Dashboard/Dashboard.vue b/src/Dashboard/Dashboard.vue
index 60cbb2d..1ccd493 100644
--- a/src/Dashboard/Dashboard.vue
+++ b/src/Dashboard/Dashboard.vue
@@ -1,8 +1,9 @@
 <template>
   <main id="dashboard" v-on:keyup.76="toggleLogs">
     <section id="dashboard-primary">
-      <hdr></hdr>
+      <hdr />
       <village-state-list />
+      <hero-view />
       <hr class="separator" />
       <task-list />
     </section>
@@ -21,10 +22,12 @@ import LogList from './LogList';
 import { mapState } from 'vuex';
 import { Mutations } from './Store';
 import VillageEditor from './VillageEditor';
+import HeroView from './HeroView';
 export default {
   components: {
     'village-editor': VillageEditor,
     'hdr': Header,
+    'hero-view': HeroView,
     'task-list': TaskList,
     'village-state-list': VillageStateList,
     'log-list': LogList,
diff --git a/src/Dashboard/HeroView.vue b/src/Dashboard/HeroView.vue
new file mode 100644
index 0000000..3c65ea0
--- /dev/null
+++ b/src/Dashboard/HeroView.vue
@@ -0,0 +1,26 @@
+<template>
+  <table class="hero">
+    <tr>
+      <td>Герой</td>
+      <td>Здоровье</td>
+      <td v-text="shared.heroAttr.health"></td>
+    </tr>
+  </table>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      shared: this.$root.$data,
+    };
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import 'style';
+.hero {
+  @extend %table;
+}
+</style>
diff --git a/src/Executor.ts b/src/Executor.ts
index 734a131..6296073 100644
--- a/src/Executor.ts
+++ b/src/Executor.ts
@@ -165,12 +165,8 @@ export class Executor {
     }
 
     private runGrabbers() {
-        try {
-            this.logger.info('Rug grabbers');
-            this.grabberManager.grab();
-        } catch (e) {
-            this.logger.warn('Grabbers fails with', e.message);
-        }
+        this.logger.info('Rug grabbers');
+        this.grabberManager.grab();
     }
 }
 
diff --git a/src/Grabber/GrabberManager.ts b/src/Grabber/GrabberManager.ts
index 39903be..dbae314 100644
--- a/src/Grabber/GrabberManager.ts
+++ b/src/Grabber/GrabberManager.ts
@@ -8,18 +8,24 @@ import { ForgePageGrabber } from './ForgePageGrabber';
 import { GuildHallPageGrabber } from './GuildHallPageGrabber';
 import { VillageFactory } from '../Village/VillageFactory';
 import { VillageBuildingsPageGrabber } from './VillageBuildingsPageGrabber';
+import { GrabError } from '../Errors';
+import { Logger } from '../Logger';
 
 export class GrabberManager {
-    private factory: VillageFactory;
-
-    constructor(factory: VillageFactory) {
-        this.factory = factory;
-    }
+    constructor(private readonly factory: VillageFactory, private readonly logger: Logger) {}
 
     grab() {
         const grabbers = this.createGrabbers();
         for (let grabber of grabbers) {
-            grabber.grab();
+            try {
+                grabber.grab();
+            } catch (e) {
+                if (e instanceof GrabError) {
+                    this.logger.warn('Grabbers fails with', e.message);
+                } else {
+                    throw e;
+                }
+            }
         }
     }