about summary refs log blame commit diff stats
path: root/src/App.svelte
blob: 502f4650bb3f13f92dcba4dd7186f56757b6559c (plain) (tree)
1
2
3
4
5
6
7
8
9
        
                                                                             
                        

                                          


                                                       
 
                                                









                    
               


                                              


                     
                          

                                     
                           



                                                                 






                                  
                                     
                                                                             





                                                                      











                                             




                                                 








                                                     






                                      
                                
                                                                  


                               
 






                                       
                                
                                                                               




                             
                              
                                        
                 

         
 
        
      

                                                 
                                                         
       


                        
                                        

                     
                         








                                  
                                                 
              
                                                                   

                                                                        





                              
                                                     
                                                                          




                                                                   
                                                    
              
                                                                   





                                                                        
                                        


                                     

                                                                                          
               




                                                                       
                                     


                                                                  




                                                                       



                                                                  




                                                                       


                                                                                              
               




                                                                       




















                                                                                     

               
<script>
  import { level, paWeather, aWeather, hWeather, pyWeather } from "./stores";
  import ew from "./ew";
  import { formatUtc } from "./times";
  import { getMatches } from "./bestiary";
  import day from "dayjs";
  import relativeTime from "dayjs/plugin/relativeTime";
  day.extend(relativeTime);

  let date = new Date().getTime() * (1440 / 70);
  let matches,
    upMatches,
    otherMatches,
    normalMatches,
    pagosForecast,
    anemosForecast,
    pyrosForecast,
    hydatosForecast;

  newForecasts();
  newMatches();
  setInterval(() => {
    date = new Date().getTime() * (1440 / 70);
  }, 1000);
  setInterval(() => {
    newForecasts();
    newMatches();
  }, 10000); // 10 seconds
  $: currentEzTime = formatUtc(date);

  function newForecasts() {
    anemosForecast = ew.forecast(ew.ANEMOS_WEATHER, "anemos");
    pagosForecast = ew.forecast(ew.PAGOS_WEATHER, "pagos");
    pyrosForecast = ew.forecast(ew.PYROS_WEATHER, "pyros");
    hydatosForecast = ew.forecast(ew.HYDATOS_WEATHER, "hydatos");
    paWeather.set(pagosForecast);
    pyWeather.set(pyrosForecast);
    hWeather.set(hydatosForecast);
    aWeather.set(anemosForecast);
  }

  function newMatches() {
    let forecast = getZoneForecast();
    matches = getMatches(forecast, $level).sort((a, b) => a.level < b.level);

    upMatches = matches.filter((m) => m.uptime.isUp);
    normalMatches = matches.filter((m) => !m.special);
    otherMatches = matches.filter((m) => m.special && !m.uptime.isUp);
  }

  function getZoneForecast() {
    if ($level >= 20 && $level < 35) {
      return pagosForecast;
    } else if ($level >= 35 && $level < 50) {
      return pyrosForecast;
    } else if ($level >= 50) {
      return hydatosForecast;
    } else {
      return anemosForecast;
    }
  }

  function getWeatherChangeTime() {
    // Doesn't matter which forecast
    return day(anemosForecast[1].date).fromNow();
  }

  function formatLevel(m) {
    if (m.level) {
      return m.level;
    } else if (m.levelRange) {
      return `${m.levelRange[0]}-${m.levelRange[1]}`;
    }
    return "??";
  }

  function formatNextUptime(futures) {
    let i;
    futures.find((f, idx) => {
      if (f) i = idx;
      return f;
    });

    if (typeof i === "number") {
      return `in ${day(getZoneForecast()[i + 1].date).fromNow()}`;
    }
    return "in the far future";
  }

  function formatUptimeUntil(futures) {
    let i;
    futures.find((f, idx) => {
      if (!f) i = idx;
      return !f;
    });

    if (typeof i === "number") {
      return `for another ${day(getZoneForecast()[i + 1].date).fromNow(true)}`;
    }

    return "for a long time";
  }

  function levelChanged(evt) {
    level.set(Number(evt.target.value));
    newMatches();
  }
</script>

<header>
  <ul>
    <li><strong>Eureka Mark Tracker</strong></li>
    <li>ET: {currentEzTime}</li>
    <li>Next weather change {getWeatherChangeTime()}</li>
  </ul>
</header>
<main class="container">
  <div class="pure-g">
    <div class="pure-u-1 pure-u-md-3-4">
      <h2>
        Level: <input
          :value={$level}
          on:change={levelChanged}
          type="number"
          min="1"
          max="60"
        />
      </h2>

      <h5>matches</h5>
      <ul>
        {#each upMatches as m (m.name + m.level)}
          <li>
            <em>(Lv{formatLevel(m)})</em> <strong>{m.name}</strong>
            ({#if m.mutating}mutates{/if}{#if m.augmenting}augments{/if}
            {formatUptimeUntil(m.uptime.futureUptime)})
          </li>
        {/each}
      </ul>

      <h5>regular enemies</h5>
      <ul>
        {#each normalMatches as m (m.name + m.level)}
          <li><em>(Lv{formatLevel(m)})</em> <strong>{m.name}</strong></li>
        {/each}
      </ul>

      <h5>special enemies that do not mutate/augment right now</h5>
      <ul>
        {#each otherMatches as m (m.name + m.level)}
          <li>
            <em>(Lv{formatLevel(m)})</em> <strong>{m.name}</strong>
            ({#if m.mutating}mutates{/if}{#if m.augmenting}augments{/if}
            {formatNextUptime(m.uptime.futureUptime)})
          </li>
        {/each}
      </ul>
    </div>
    <div class="pure-u-1 pure-u-md-1-4">
      <div class="pure-menu">
        <ul class="pure-menu-list">
          <li class="pure-menu-item">
            {#if $level < 20}<strong>Anemos</strong>{:else}Anemos{/if}: {anemosForecast[0]
              .weatherName}
          </li>
          {#if $level < 20}<ul>
              {#each [1, 2, 3, 4] as i}<li>
                  {ew.getWeatherName(getZoneForecast()[i].currWeather)}
                </li>{/each}
            </ul>{/if}
          <li class="pure-menu-item">
            {#if $level >= 20 && $level < 35}<strong>Pagos</strong
              >{:else}Pagos{/if}: {pagosForecast[0].weatherName}
          </li>
          {#if $level >= 20 && $level < 35}<ul>
              {#each [1, 2, 3, 4] as i}<li>
                  {ew.getWeatherName(getZoneForecast()[i].currWeather)}
                </li>{/each}
            </ul>{/if}
          <li class="pure-menu-item">
            {#if $level >= 35 && $level < 50}<strong>Pyros</strong
              >{:else}Pyros{/if}: {pyrosForecast[0].weatherName}
          </li>
          {#if $level >= 35 && $level < 500}<ul>
              {#each [1, 2, 3, 4] as i}<li>
                  {ew.getWeatherName(getZoneForecast()[i].currWeather)}
                </li>{/each}
            </ul>{/if}
          <li class="pure-menu-item">
            {#if $level >= 50}<strong>Hydatos</strong>{:else}Hydatos{/if}: {hydatosForecast[0]
              .weatherName}
          </li>
          {#if $level >= 50}<ul>
              {#each [1, 2, 3, 4] as i}<li>
                  {ew.getWeatherName(getZoneForecast()[i].currWeather)}
                </li>{/each}
            </ul>{/if}
        </ul>
      </div>
      <h4>What is this?</h4>
      <p>
        This is a website to keep track of which monsters in Eureka are mutating
        or augmenting right now. Mutating/augmenting massively increases the EXP
        yield, and it is therefore preferrable to go after these monsters when
        levelling in Eureka.
        <br /><br />
        Mutation/augmentation requirements are bound by weather, as well as time
        of day. I created this so I didn't need to look through various google sheets
        and cross-reference with weather forecasts.
      </p>
      <hr />
      <p>
        Created by Raiah Belse (Twintania)<br />
        <a href="https://git.tilde.institute/anastasie/eureka-marks/">Source</a>
      </p>
    </div>
  </div>
</main>

<style></style>