PageSourceSearch

https://jeanropke.github.io/RDOMap/assets/js/treasures.js?nocache=1552

js jeanropke.github.io collected 2026-10-03 09:23:33 UTC 5,169 bytes, 148 lines download raw bytes

1class Treasure {
2
3  // requires MapBase.map, Menu.reorderMenu, Settings.some and DOM ready
4  // not idempotent
5  static init() {
6    this.treasuresParentElement = document.querySelector('.menu-option.clickable[data-type=treasure]');
7    this.treasuresParentElement.classList.toggle('disabled', !this.treasuresOnMap);
8    this.treasuresParentElement.addEventListener('click', () => this.treasuresOnMap = !this.treasuresOnMap);
9
10    this.treasures = [];
11    this.quickParams = [];
12    this.layer = L.layerGroup();
13    this.layer.addTo(MapBase.map);
14
15    const pane = MapBase.map.createPane('treasureX');
16    pane.style.zIndex = 450; // X-markers on top of circle, but behind “normal” markers/shadows
17    pane.style.pointerEvents = 'none';
18
19    this.context = document.querySelector('.menu-hidden[data-type=treasure]');
20    this.context.classList.toggle('disabled', !this.treasuresOnMap);
21
22    this.crossIcon = L.icon({
23      iconUrl: './assets/images/icons/cross.png',
24      iconSize: [16, 16],
25      iconAnchor: [8, 8],
26    });
27
28    this.onSettingsChanged();
29
30    document.querySelectorAll('.menu-hidden[data-type="treasure"] > *:first-child button').forEach((btn) =>
31      btn.addEventListener('click', (e) => {
32        e.preventDefault();
33        const showAll = e.target.getAttribute('data-text') === 'menu.show_all';
34        Treasure.treasures.forEach(treasure => treasure.onMap = showAll);
35      })
36    );
37
38    return Loader.promises['treasures'].consumeJson(data => {
39      data.forEach(item => {
40        this.treasures.push(new Treasure(item));
41        this.quickParams.push(item.text);
42      });
43      this.onLanguageChanged();
44      console.info('%c[Treasures] Loaded!', 'color: #bada55; background: #242424');
45    });
46  }
47
48  static onLanguageChanged() {
49    Menu.reorderMenu(this.context);
50  }
51  static onSettingsChanged() {
52    this.treasures.forEach(treasure => treasure.reinitMarker());
53  }
54
55  // not idempotent (on the environment)
56  constructor(preliminary) {
57    Object.assign(this, preliminary);
58    this._shownKey = `shown.${this.text}`;
59    this.element = document.createElement('div');
60    this.element.classList.add('collectible-wrapper');
61    Object.assign(this.element.dataset, { help: 'item', tippyContent: Language.get(this.text) });
62    this.element.addEventListener('click', () => this.onMap = !this.onMap);
63    this.element.innerHTML = `<p class="collectible" data-text="${this.text}"></p>`;
64    Language.translateDom(this.element);
65
66    this.reinitMarker();
67
68    Treasure.context.appendChild(this.element);
69  }
70
71  // auto remove marker? from map, recreate marker, auto add? marker
72  // idempotent
73  reinitMarker() {
74    if (this.marker) Treasure.layer.removeLayer(this.marker);
75    this.marker = L.layerGroup();
76    this.marker.addLayer(L.circle([this.x, this.y], {
77      color: '#f4e98a',
78      fillColor: '#f4e98a',
79      fillOpacity: linear(Settings.overlayOpacity, 0, 1, 0.1, 0.5),
80      radius: this.radius,
81    })
82      .bindPopup(this.popupContent.bind(this), { minWidth: 300 })
83    );
84    this.locations.forEach(cross =>
85      this.marker.addLayer(L.marker([cross.x, cross.y], {
86        icon: Treasure.crossIcon,
87        pane: 'treasureX',
88      })
89        .bindPopup(this.popupContent.bind(this), { minWidth: 300 }))
90    );
91    this.onMap = this.onMap;
92  }
93
94  popupContent() {
95    const snippet = document.createElement('div');
96    snippet.classList.add('handover-wrapper-with-no-influence');
97    snippet.innerHTML = `
98        <h1 data-text="${this.text}"></h1>
99        <button type="button" class="btn btn-info remove-button treasure-button" data-text="map.remove"></button>
100    `;
101    Language.translateDom(snippet);
102    snippet.querySelector('button').addEventListener('click', () => this.onMap = false);
103
104    return snippet;
105  }
106
107  set onMap(state) {
108    if (state) {
109      if (MapBase.isPreviewMode || Treasure.treasuresOnMap)
110        Treasure.layer.addLayer(this.marker);
111      if (!MapBase.isPreviewMode)
112        localStorage.setItem(`rdo.${this._shownKey}`, 'true');
113      this.element.classList.remove('disabled');
114    } else {
115      if (Treasure.treasuresOnMap)
116        Treasure.layer.removeLayer(this.marker);
117      if (!MapBase.isPreviewMode)
118        localStorage.removeItem(`rdo.${this._shownKey}`);
119      this.element.classList.add('disabled');
120    }
121  }
122  get onMap() {
123    return !!localStorage.getItem(`rdo.${this._shownKey}`);
124  }
125
126  static set treasuresOnMap(state) {
127    if (state) {
128      MapBase.map.addLayer(Treasure.layer);
129      if (!MapBase.isPreviewMode)
130        localStorage.setItem('rdo.treasures', 'true');
131
132      this.treasures.forEach(_t => {
133        if (_t.onMap) _t.onMap = state;
134      });
135    } else {
136      Treasure.layer.remove();
137      if (!MapBase.isPreviewMode)
138        localStorage.removeItem('rdo.treasures');
139    }
140
141    this.treasuresParentElement.classList.toggle('disabled', !state);
142    this.context.classList.toggle('disabled', !state);
143  }
144
145  static get treasuresOnMap() {
146    return !!localStorage.getItem('rdo.treasures');
147  }
148}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.