about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.svelte34
-rw-r--r--src/bestiary.js47
-rw-r--r--src/ew.js141
-rw-r--r--src/pagos.bestiary.json1
-rw-r--r--src/stores.js4
-rw-r--r--src/times.js7
6 files changed, 230 insertions, 4 deletions
diff --git a/src/App.svelte b/src/App.svelte
index 27f7f73..0de1e0e 100644
--- a/src/App.svelte
+++ b/src/App.svelte
@@ -1,17 +1,43 @@
 <script>
-  import { level } from "./stores";
+  import { level, paWeather } from "./stores";
+  import ew from "./ew";
+  import { onMount } from "svelte";
+  import { formatUtc } from "./times";
+  import { getMatches } from "./bestiary";
+
+  onMount(async () => {
+    updateWeatherStores();
+  });
+
+  let date = new Date().getTime() * (1440 / 70);
+
+  setInterval(() => {
+    date = new Date().getTime() * (1440 / 70);
+  }, 1000);
+  $: currentEzTime = formatUtc(date);
+
+  function updateWeatherStores() {
+    paWeather.set(ew.forecast(ew.PAGOS_WEATHER));
+  }
+
+  const pagosForecast = ew.forecast(ew.PAGOS_WEATHER);
+  getMatches(pagosForecast, $level);
 
   function levelChanged(evt) {
-    level.set(Number(evt.data));
+    level.set(Number(evt.target.value));
   }
 </script>
 
 <div class="app">
   <h2>
-    Level: <input on:input={levelChanged} type="number" min="1" max="60" />
+    Level: <input on:change={levelChanged} type="number" min="1" max="60" />
   </h2>
 
-  Level is {$level}
+  Level is {$level}<br />
+
+  Time is {currentEzTime}<br />
+
+  Anemos Weather is {pagosForecast[0].weatherName}
 </div>
 
 <style></style>
diff --git a/src/bestiary.js b/src/bestiary.js
new file mode 100644
index 0000000..33779d3
--- /dev/null
+++ b/src/bestiary.js
@@ -0,0 +1,47 @@
+import pagosB from "./pagos.bestiary.json";
+import day from "dayjs";
+import isBetween from "dayjs/plugin/isBetween";
+day.extend(isBetween);
+
+export function getMatches(forecast, level) {
+  console.log(level);
+  let res = [];
+  pagosB.forEach((b) => {
+    if (b.level >= level && b.level - 2 < level) {
+      res.push({
+        name: b.name,
+        elem: b.elem,
+        special: b.type > 0,
+        mutating: b.type === 1,
+        augmenting: b.type === 2,
+        uptime: findForecastMatch(forecast, b.conditions),
+      });
+    }
+  });
+  console.log(res);
+}
+
+function getEzTime() {
+  return day(new Date().getTime() * (1440 / 70));
+}
+
+function findForecastMatch(forecast, conditions) {
+  const time = getEzTime();
+  const dn = time.isBetween(time.hour(8), time.hour(18)) ? "day" : "night";
+  return {
+    isUp: forecastMatches(forecast, conditions[dn], 0).length > 0,
+    weathers: forecastMatches(forecast, conditions[dn], 0),
+    futureUptime: [1, 2, 3, 4].map((i) => {
+      const match = forecastMatches(forecast, conditions[dn], i);
+      return {
+        isUp: match.length > 0,
+        weathers: match,
+      };
+    }),
+  };
+}
+
+function forecastMatches(forecast, condition, index) {
+  const currWeather = forecast[index].currWeather;
+  return condition.filter((c) => c === currWeather);
+}
diff --git a/src/ew.js b/src/ew.js
new file mode 100644
index 0000000..3519be1
--- /dev/null
+++ b/src/ew.js
@@ -0,0 +1,141 @@
+import { aWeather, paWeather, pyWeather, hWeather } from "./stores";
+
+const WEATHER = {
+  FAIR: 0,
+  SHOWERS: 1,
+  GALES: 2,
+  BLIZZARDS: 3,
+  HEAT: 4,
+  THUNDER: 5,
+  GLOOM: 6,
+  SNOW: 7,
+  FOG: 8,
+  UMBRAL_WIND: 9,
+};
+
+// Anemos: 30/Fair, 30/Gales, 30/Showers, 10/Snowy
+const ANEMOS_WEATHER = [
+  [WEATHER.FAIR, 30],
+  [WEATHER.GALES, 30],
+  [WEATHER.SHOWERS, 30],
+  [WEATHER.SNOW, 10],
+];
+
+// Pagos: 10/Fair, 18/Fog, 18/Heat, 18/Snow, 18/Thunder, 18/Blizzards
+const PAGOS_WEATHER = [
+  [WEATHER.FAIR, 10],
+  [WEATHER.FOG, 18],
+  [WEATHER.HEAT, 18],
+  [WEATHER.SNOW, 18],
+  [WEATHER.THUNDER, 18],
+  [WEATHER.BLIZZARDS, 18],
+];
+
+// Pyros: 10/Fair, 18/Heat, 18/Thunder, 18/Blizzards, 18/Umbral Wind, 18/Snow
+const PYROS_WEATHER = [
+  [WEATHER.FAIR, 10],
+  [WEATHER.HEAT, 18],
+  [WEATHER.THUNDER, 18],
+  [WEATHER.BLIZZARDS, 18],
+  [WEATHER.UMBRAL_WIND, 18],
+  [WEATHER.SNOW, 18],
+];
+
+// Hydatos: 12/Fair, 22/Showers, 22/Gloom, 22/Thunder, 22/Snow
+const HYDATOS_WEATHER = [
+  [WEATHER.FAIR, 12],
+  [WEATHER.SHOWERS, 22],
+  [WEATHER.GLOOM, 22],
+  [WEATHER.THUNDER, 22],
+  [WEATHER.SNOW, 22],
+];
+
+function getWeatherName(weather) {
+  switch (weather) {
+    case 0:
+      return "Fair";
+    case 1:
+      return "Showers";
+    case 2:
+      return "Gales";
+    case 3:
+      return "Blizzards";
+    case 4:
+      return "Heat";
+    case 5:
+      return "Thunder";
+    case 6:
+      return "Gloom";
+    case 7:
+      return "Snow";
+    case 8:
+      return "Fog";
+    case 9:
+      return "Umbral Wind";
+    default:
+      return "Unknown";
+  }
+}
+
+function getSeed(date = new Date()) {
+  return Math.floor(date.getTime() / 1400000);
+}
+
+function hash(seed = getSeed()) {
+  const base = Math.floor(seed / 3) * 100 + ((seed + 1) % 3) * 8;
+  const step1 = ((base << 11) ^ base) >>> 0;
+  const step2 = ((step1 >>> 8) ^ step1) >>> 0;
+  return step2 % 100;
+}
+
+function hashSeq(seed = getSeed(), count = 10) {
+  const hashes = [];
+  for (let i = 0; i < count; ++i) {
+    hashes.push(hash(seed + i));
+  }
+  return hashes;
+}
+
+function getWeather(rates, hash = hashSeed()) {
+  let total = 0;
+  for (const [weather, chance] of rates) {
+    if ((total += chance) > hash) {
+      return weather;
+    }
+  }
+  return WEATHER.FAIR;
+}
+
+function forecast(rates, seed = getSeed(), count = 10) {
+  const res = [];
+  let prevHash = hash(seed - 1);
+  let prevWeather = getWeather(rates, prevHash);
+
+  for (let i = 0; res.length < count && i < 100000; ++i) {
+    const currHash = hash(seed);
+    const currWeather = getWeather(rates, currHash);
+    res.push({
+      prevWeather,
+      currWeather,
+      weatherName: getWeatherName(currWeather),
+      seed,
+      date: new Date(seed * 1400000),
+    });
+    prevHash = currHash;
+    prevWeather = currWeather;
+    ++seed;
+  }
+
+  return res;
+}
+
+export default {
+  WEATHER,
+  ANEMOS_WEATHER,
+  PAGOS_WEATHER,
+  PYROS_WEATHER,
+  HYDATOS_WEATHER,
+  getWeather,
+  forecast,
+  getWeatherName,
+};
diff --git a/src/pagos.bestiary.json b/src/pagos.bestiary.json
new file mode 100644
index 0000000..eca9afa
--- /dev/null
+++ b/src/pagos.bestiary.json
@@ -0,0 +1 @@
+[{"level":20,"name":"Sylvestre","type":2,"elem":"Wind","conditions":{"day":[0,4,7,5],"night":[3,5,8]}},{"level":20,"name":"Pagos Deepeye","type":1,"elem":"Thunder","conditions":{"day":[],"night":[0,4,7,3,5,8]}},{"level":21,"name":"Val Galago","type":1,"elem":"Thunder","conditions":{"day":[0,4,7,3,5],"night":[]}},{"level":21,"name":"Deadly Dodo","type":0,"elem":null,"conditions":{"day":[],"night":[]}},{"level":21,"name":"Northern Fluturini","type":2,"elem":"Wind","conditions":{"day":[8],"night":[5,8]}},{"level":22,"name":"Snow Slug","type":2,"elem":"Water","conditions":{"day":[3],"night":[3,5]}},{"level":22,"name":"Val Banemite","type":1,"elem":"Thunder","conditions":{"day":[4,3,5],"night":[0,5,8]}},{"level":22,"name":"Val Roselet","type":0,"elem":null,"conditions":{"day":[],"night":[]}},{"level":null,"name":"Zombie Brobinyak","type":2,"elem":"Earth","conditions":{"day":[],"night":[8]}},{"level":23,"name":"Val Mole","type":1,"elem":"Earth","conditions":{"day":[0],"night":[0]}},{"level":23,"name":"Val Ant","type":0,"elem":null,"conditions":{"day":[],"night":[]}},{"level":23,"name":"Iceskin Peiste","type":0,"elem":null,"conditions":{"day":[],"night":[]}},{"level":24,"name":"Snow Aurelia","type":2,"elem":"Water","conditions":{"day":[0,7,5],"night":[0,3,8]}},{"level":24,"name":"Pagos Wolf","type":1,"elem":"Ice","conditions":{"day":[],"night":[0,4,7,3,5,8]}},{"level":24,"name":"Yarzon Survivor","type":0,"elem":null,"conditions":{"day":[],"night":[]}},{"level":25,"name":"Pagos Puk","type":1,"elem":"Fire","conditions":{"day":[5],"night":[5]}},{"level":25,"name":"Savage Ruszor","type":0,"elem":null,"conditions":{"day":[],"night":[]}},{"level":25,"name":"Thunderstorm Sprite","type":1,"elem":"Thunder","conditions":{"day":[5],"night":[5]}},{"level":null,"name":"Demon of the Incunable","type":2,"elem":"Wind","conditions":{"day":[],"night":[4,7,3,5,8]}},{"level":26,"name":"Val Mantis","type":2,"elem":"Earth","conditions":{"day":[4,3],"night":[4,7,3,5,8]}},{"level":26,"name":"Pagos Tursus","type":2,"elem":"Ice","conditions":{"day":[],"night":[]}},{"level":26,"name":"Snowmelt Sprite","type":1,"elem":"Water","conditions":{"day":[8],"night":[8]}},{"level":26,"name":"Northern Colibri","type":1,"elem":"Wind","conditions":{"day":[4,7,3,5,8],"night":[]}},{"level":27,"name":"Pagos Bear","type":1,"elem":"Earth","conditions":{"day":[7,3],"night":[7,3]}},{"level":27,"name":"Frozen Gelato","type":2,"elem":"Ice","conditions":{"day":[0,3,5],"night":[0,4,7,3,5,8]}},{"level":27,"name":"Ember Sprite","type":1,"elem":"Fire","conditions":{"day":[4],"night":[4]}},{"level":28,"name":"Coralline Uragnite","type":1,"elem":"Water","conditions":{"day":[4,3,5],"night":[4,7,8]}},{"level":28,"name":"Eurekan Vindthurs","type":1,"elem":"Ice","conditions":{"day":[4],"night":[4]}},{"level":29,"name":"Pagos Wildebeest","type":1,"elem":"Thunder","conditions":{"day":[0,4,7,3,5,8],"night":[4,7,5,8]}},{"level":29,"name":"Emberflash Matamata","type":1,"elem":"Water","conditions":{"day":[4],"night":[4]}},{"level":29,"name":"Zombie Wyvern","type":2,"elem":"Wind","conditions":{"day":[4,7,3,5,8],"night":[4,7,3,8]}},{"level":30,"name":"Ice Mirrorknight","type":1,"elem":"Wind","conditions":{"day":[4],"night":[4]}},{"level":30,"name":"Pagos Croc","type":1,"elem":"Earth","conditions":{"day":[],"night":[0,4,7,3,5,8]}},{"level":null,"name":"Geshunpest","type":2,"elem":"Thunder","conditions":{"day":[],"night":[7,3,8]}},{"level":31,"name":"Withered Sankchinni","type":1,"elem":"Wind","conditions":{"day":[8],"night":[8]}},{"level":31,"name":"Val Guardian","type":1,"elem":"Earth","conditions":{"day":[],"night":[0,4,7,3,5,8]}},{"level":32,"name":"Pagos Hippocerf","type":2,"elem":"Wind","conditions":{"day":[4,7,3,5],"night":[7,3,5,8]}},{"level":32,"name":"Decotitus","type":1,"elem":"Earth","conditions":{"day":[0,4,7,3,5,8],"night":[]}},{"level":32,"name":"Snowstorm Sprite","type":1,"elem":"Ice","conditions":{"day":[7,3],"night":[7,3]}},{"level":33,"name":"Pagos Centaur","type":1,"elem":"Thunder","conditions":{"day":[4],"night":[4]}},{"level":33,"name":"Val Keeper","type":2,"elem":"Earth","conditions":{"day":[4,7,3,5,8],"night":[7,3,5,8]}},{"level":33,"name":"Thunderstorm Sprite","type":1,"elem":"Thunder","conditions":{"day":[5],"night":[5]}},{"level":null,"name":"Haunt","type":2,"elem":"Water","conditions":{"day":[],"night":[0,4,7,3,5,8]}},{"level":34,"name":"Urolith Guard","type":1,"elem":"Earth","conditions":{"day":[7,3],"night":[7,3]}},{"level":34,"name":"Frozen Aevis","type":1,"elem":"Thunder","conditions":{"day":[4,7,3,5,8],"night":[]}},{"level":35,"name":"Valley Manticore","type":1,"elem":"Fire","conditions":{"day":[0,4,7,3,5,8],"night":[]}},{"level":35,"name":"Val Corpse Flower","type":1,"elem":"Ice","conditions":{"day":[0],"night":[0]}},{"level":36,"name":"Blizzard Goobbue","type":1,"elem":"Ice","conditions":{"day":[],"night":[0,4,7,3,5,8]}},{"level":null,"name":"Val Corpse","type":2,"elem":"Ice","conditions":{"day":[],"night":[0,7,8]}},{"level":36,"name":"World Serpent","type":1,"elem":"Fire","conditions":{"day":[8],"night":[8]}},{"level":37,"name":"Storm Manta","type":1,"elem":"Water","conditions":{"day":[0],"night":[0]}},{"level":37,"name":"Void Syricta","type":1,"elem":"Earth","conditions":{"day":[3],"night":[3]}},{"level":38,"name":"Val Ymir","type":1,"elem":"Thunder","conditions":{"day":[4,8],"night":[]}},{"level":38,"name":"Pagos Anubys","type":1,"elem":"Water","conditions":{"day":[0,4,7,3,5,8],"night":[0,4,7,3,5,8]}},{"level":39,"name":"Greater Amphiphtre","type":1,"elem":"Fire","conditions":{"day":[0,5],"night":[0,5]}},{"level":39,"name":"Escaped Tyrannosaur","type":1,"elem":"Earth","conditions":{"day":[],"night":[0,4,7,3,5,8]}},{"level":40,"name":"Frozen Void Dragon","type":2,"elem":"Ice","conditions":{"day":[0,4,7,3,5,8],"night":[0,4,3,5,8]}},{"level":40,"name":"Pagos Chimera","type":1,"elem":"Thunder","conditions":{"day":[3],"night":[3]}},{"level":40,"name":"Val Griffin","type":1,"elem":"Wind","conditions":{"day":[0],"night":[0]}}]
\ No newline at end of file
diff --git a/src/stores.js b/src/stores.js
index f203bfd..65b3a79 100644
--- a/src/stores.js
+++ b/src/stores.js
@@ -3,6 +3,10 @@ import { writable } from "svelte/store";
 const localStorage = window.localStorage;
 
 export const level = localStorageStore(0);
+export const aWeather = writable();
+export const paWeather = writable();
+export const pyWeather = writable();
+export const hWeather = writable();
 
 function localStorageStore(key) {
   const item = localStorage.getItem(key);
diff --git a/src/times.js b/src/times.js
new file mode 100644
index 0000000..5615c19
--- /dev/null
+++ b/src/times.js
@@ -0,0 +1,7 @@
+import day from "dayjs";
+import utc from "dayjs/plugin/utc";
+day.extend(utc);
+
+export function formatUtc(date) {
+  return day.utc(date).format("HH:mm");
+}