PageSourceSearch

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

js jeanropke.github.io collected 2026-10-03 09:23:44 UTC 5,911 bytes, 159 lines download raw bytes

1class Animal {
2  constructor(preliminary, type) {
3    Object.assign(this, preliminary);
4
5    this.context = document.querySelector(`.menu-hidden[data-type=${type}]`);
6
7    this.element = document.createElement('div');
8    this.element.classList.add('collectible-wrapper');
9    Object.assign(this.element.dataset, { help: 'item', type: this.key, tippyContent: Language.get(`menu.cmpndm.${this.key}`) });
10    this.element.innerHTML = `
11      <img class="collectible-icon" src="./assets/images/icons/game/animals/${this.key}.png">
12      <span class="collectible-text disabled">
13        <p class="collectible" data-text="menu.cmpndm.${this.key}"></p>
14      </span>
15    `;
16    this.element.addEventListener('click', () => (this.isEnabled = !this.isEnabled));
17    Language.translateDom(this.element);
18
19    this.markers = [];
20
21    if (this.groups != null) {
22      this.groups.forEach((_group) => {
23        if (!AnimalCollection.groups[_group]) return console.error(`The animal spawns group for ${_group} could not be found.`);
24        MapBase.yieldingLoop(
25          AnimalCollection.groups[_group].length,
26          50,
27          (index) => {
28            this.marker = AnimalCollection.groups[_group][index];
29            const tempMarker = L.marker([this.marker.x, this.marker.y], {
30              opacity: 0.75,
31              icon: new L.divIcon({
32                iconUrl: 'assets/images/icons/animal.png',
33                iconSize: [32, 32],
34                iconAnchor: [16, 16],
35                popupAnchor: [0, -8],
36              }),
37            });
38
39            // exception from `.bind(this)` to show correct data in marker popup
40            tempMarker.bindPopup(this.popupContent(), { minWidth: 300, maxWidth: 400 });
41            this.data.push(tempMarker._latlng);
42            this.markers.push(tempMarker);
43          },
44          function () {}
45        );
46      });
47    }
48
49    this.context.appendChild(this.element);
50  }
51
52  popupContent() {
53    const animalName = Language.get('map.animal_spawns.name').replace('{animal}', Language.get(`menu.cmpndm.${this.key}`));
54    let description = Language.get('map.animal_spawns.desc').replace('{animal}', Language.get(`menu.cmpndm.${this.key}`));
55
56    if (this.marker.start && this.marker.end) {
57      const startTime = convertToTime(this.marker.start);
58      const endTime = convertToTime(this.marker.end);
59      description = Language.get('map.animal_spawns_timed.desc')
60        .replace('{animal}', Language.get(`menu.cmpndm.${this.key}`))
61        .replace('{start}', startTime)
62        .replace('{end}', endTime);
63    }
64
65    const snippet = document.createElement('div');
66    snippet.innerHTML = `
67          <h1>${animalName}</h1>
68          <span class="marker-content-wrapper">
69            <p>${description}</p>
70          </span>
71          <button class="btn btn-info remove-button full-popup-width" data-text="map.remove"></button>
72          <small>Latitude: ${this.marker.x} / Longitude: ${this.marker.y} / Start: ${this.marker.start} / End: ${this.marker.end}</small>
73    `;
74    Language.translateDom(snippet);
75    snippet.querySelector('small').style.display = Settings.isDebugEnabled ? '' : 'none';
76    snippet.querySelector('button').addEventListener('click', () => (this.isEnabled = false));
77
78    return snippet;
79  }
80
81  set isEnabled(state) {
82    document
83      .querySelectorAll('[data-type="animals"] .collectible-text, [data-type="birds"] .collectible-text, [data-type="fish"] .collectible-text')
84      .forEach((el) => el.classList.add('disabled'));
85
86    if (state) {
87      AnimalCollection.spawnLayer.clearLayers();
88      AnimalCollection.heatmapLayer.setData({ data: this.data });
89      if (this.markers.length > 0) AnimalCollection.spawnLayer.addLayers(this.markers);
90      this.element.querySelector('span').classList.remove('disabled');
91    } else {
92      AnimalCollection.heatmapLayer.setData({ data: [] });
93      AnimalCollection.spawnLayer.clearLayers();
94      this.element.querySelector('span').classList.add('disabled');
95      MapBase.map.closePopup();
96    }
97  }
98
99  get isEnabled() {
100    return !this.element.querySelector('span').classList.contains('disabled');
101  }
102}
103
104class AnimalCollection {
105  static init() {
106    this.heatmapLayer = new HeatmapOverlay({
107      radius: 2.5,
108      maxOpacity: 0.5,
109      minOpacity: 0,
110      scaleRadius: true,
111      useLocalExtrema: false,
112      latField: 'lat',
113      lngField: 'lng',
114      gradient: {
115        0.25: 'rgb(125, 125, 125)',
116        0.55: 'rgb(48, 25, 52)',
117        1.0: 'rgb(255, 42, 32)',
118      },
119    });
120
121    this.spawnLayer = L.canvasIconLayer({ zoomAnimation: true });
122
123    this.groups = [];
124    this.collection = [];
125    this.collectionsData = [];
126    this.quickParams = [];
127
128    AnimalCollection.heatmapLayer.addTo(MapBase.map);
129    AnimalCollection.spawnLayer.addTo(MapBase.map);
130
131    const animalSpawns = Loader.promises['animal_spawns'].consumeJson((data) => (this.groups = data));
132    const animalHeatmap = Loader.promises['hm'].consumeJson((data) => (this.collectionsData = data));
133
134    return Promise.all([animalSpawns, animalHeatmap]).then(() => {
135      console.info('%c[Animals] Loaded!', 'color: #bada55; background: #242424');
136      this.collectionsData.forEach((collection) => this.collection.push(new AnimalCollection(collection)));
137    });
138  }
139
140  constructor(preliminary) {
141    Object.assign(this, preliminary);
142
143    this.animals = [];
144    this.data.forEach((animal) => {
145      this.animals.push(new Animal(animal, this.key));
146      AnimalCollection.quickParams.push(animal.key);
147    });
148
149    AnimalCollection.onLanguageChanged();
150  }
151
152  static onLanguageChanged() {
153    AnimalCollection.collectionsData.forEach((group) => Menu.reorderMenu(document.querySelector(`.menu-hidden[data-type=${group.key}]`)));
154  }
155
156  static hideAllAnimals() {
157    AnimalCollection.collection.forEach((collection) => collection.animals.forEach((animal) => (animal.isEnabled = false)));
158  }
159}

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.