Skip to content

Commit 111579e

Browse files
committed
Merge PR #1811 of DragonDev1906
2 parents 999e613 + 854069f commit 111579e

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed

docs/config.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,29 @@ BiomeOverlay
12481248

12491249
BiomeOverlay(biomes=[("Forest", (0, 255, 0)), ("Desert", (255, 0, 0))])
12501250

1251+
HeatmapOverlay
1252+
Color the map according to when a chunk was last visited. The color for Timestamps
1253+
between t_invisible and t_full will be interpolated between 0 and 255.
1254+
This RenderPrimitive might require use of the forcerender option.
1255+
Otherwise the Overlay might not get updated for not visited chunks (resulting in them
1256+
always being the brightest color, as if recently visited).
1257+
1258+
**Options**
1259+
1260+
t_invisible
1261+
The timestamp when the overlay will get invisible. The default is 30 days ago.
1262+
1263+
t_now
1264+
The timestamp when the overlay will be fully visible. The default is today.
1265+
1266+
Example::
1267+
1268+
HeatmapOverlay(
1269+
t_invisible=int((t_now - timedelta(days=2)).timestamp()),
1270+
t_full=int(t_now.timestamp()),
1271+
)
1272+
1273+
12511274
Defining Custom Rendermodes
12521275
---------------------------
12531276

overviewer_core/rendermodes.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#
1313
# You should have received a copy of the GNU General Public License along
1414
# with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
15+
from datetime import datetime, timedelta
1516

1617
from PIL import Image
1718
from . import textures
@@ -231,6 +232,17 @@ class BiomeOverlay(Overlay):
231232
'alpha' : ('an integer value between 0 (transparent) and 255 (opaque)', None),
232233
}
233234

235+
class HeatmapOverlay(Overlay):
236+
t_now = datetime.now()
237+
name = "overlay-heatmap"
238+
options = {
239+
't_invisible': (
240+
'the timestamp when the overlay will get invisible (e.g. 1 month go)',
241+
int((t_now - timedelta(days=30)).timestamp())
242+
),
243+
't_full': ('the timestamp when the overlay will be fully visible (e.g. now)', int(t_now.timestamp())),
244+
}
245+
234246
class Hide(RenderPrimitive):
235247
name = "hide"
236248
options = {
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* This file is part of the Minecraft Overviewer.
3+
*
4+
* Minecraft Overviewer is free software: you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License as published
6+
* by the Free Software Foundation, either version 3 of the License, or (at
7+
* your option) any later version.
8+
*
9+
* Minecraft Overviewer is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12+
* Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License along
15+
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <math.h>
19+
#include "overlay.h"
20+
21+
typedef struct {
22+
/* inherits from overlay */
23+
RenderPrimitiveOverlay parent;
24+
int t_invisible;
25+
int delta_t;
26+
} RenderPrimitiveHeatmap;
27+
28+
static void get_color(void* data, RenderState* state,
29+
uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) {
30+
RenderPrimitiveHeatmap* self = (RenderPrimitiveHeatmap*)data;
31+
long mtime;
32+
float _value_f;
33+
char value;
34+
PyObject *mtime_pyobj;
35+
36+
// Set default values (will get overridden based on self->mode)
37+
*r = 255;
38+
*g = 0;
39+
*b = 0;
40+
41+
// Get the chunk modified time
42+
mtime_pyobj = PyObject_CallMethod(state->regionset, "get_chunk_mtime", "ii", state->chunkx, state->chunkz);
43+
if (mtime_pyobj == NULL || mtime_pyobj == Py_None) {
44+
*a = 0;
45+
return;
46+
}
47+
mtime = PyLong_AsLong(mtime_pyobj);
48+
Py_XDECREF(mtime_pyobj);
49+
50+
// Convert the time to a value in the range [0,255] based on t_invisible and delta_t
51+
_value_f = (mtime - self->t_invisible) / (float)self->delta_t;
52+
value = _value_f <= 0 ? 0 : (_value_f >= 1 ? 255 : 255*_value_f);
53+
*a = value;
54+
}
55+
56+
static bool
57+
overlay_heatmap_start(void* data, RenderState* state, PyObject* support) {
58+
RenderPrimitiveHeatmap* self;
59+
int t_full;
60+
61+
/* first, chain up */
62+
bool ret = primitive_overlay.start(data, state, support);
63+
if (ret != false)
64+
return ret;
65+
66+
/* now do custom initializations */
67+
self = (RenderPrimitiveHeatmap*)data;
68+
self->parent.get_color = get_color;
69+
70+
if (!render_mode_parse_option(support, "t_invisible", "I", &(self->t_invisible)))
71+
return true;
72+
73+
if (!render_mode_parse_option(support, "t_full", "I", &t_full))
74+
return true;
75+
76+
self->delta_t = t_full - self->t_invisible;
77+
return false;
78+
}
79+
80+
static void
81+
overlay_heatmap_finish(void* data, RenderState* state) {
82+
/* chain up */
83+
primitive_overlay.finish(data, state);
84+
}
85+
86+
RenderPrimitiveInterface primitive_overlay_heatmap = {
87+
"overlay-heatmap",
88+
sizeof(RenderPrimitiveHeatmap),
89+
overlay_heatmap_start,
90+
overlay_heatmap_finish,
91+
NULL,
92+
NULL,
93+
overlay_draw,
94+
};

0 commit comments

Comments
 (0)