overviewer / Minecraft-Overviewer

Render high-resolution maps of a Minecraft world with a Leaflet powered interface
https://overviewer.org/
GNU General Public License v3.0
3.35k stars 481 forks source link

Filter functions for POIs do not work with Minecraft 1.18 #2026

Open timmcmaster opened 2 years ago

timmcmaster commented 2 years ago

I have been using Overviewer for a few years and have a bunch of filters to show chests/beds/portals etc. As of 1.18 these don't seem to find any POIs (though the filters are still added to the map). It might be my issue, though I've had a bit of a look and couldn't see anything obvious.

Attached config file with filters anonymised_configfile.txt .

Plagiatus commented 2 years ago

I've ran into a similar issue. I just came back to overviewer for a new world I made with my friends in 1.18, and I can't get even the most basic POIs to work, basically just copying from the documentation.

def playerIcons(poi):
    if poi['id'] == 'Player':
        poi['icon'] = "https://overviewer.org/avatar/%s" % poi['EntityId']
        return "Last known location for %s" % poi['EntityId']

def townFilter(poi):
    if poi["id"] == "Town":
        return poi["name"]

worlds["Survival"] = "C:/Users/<me>/AppData/Roaming/.minecraft/saves/Survivial_Realm_04_22"

renders["overworld"] = {
    "world": "Survival",
    "title": "Your survival world",
    "crop": [(6000,-2200,6600,-1600)],
    "rendermode": "lighting",
    "manualpois": [
        {
            "id":"Town",
            "x": "6300",
            "y": "64",
            "z": "-1950",
            "name": "test"
        }
    ],
    "markers": [
        dict(name="Towns", filterFunction=townFilter, icon="markers/marker_town.png")
    ],
}

outputdir = "D:/Programme/Overviewer/overviewer-0.17.47/output"

any help would be appreciated.

JayGuerette commented 2 years ago

Here is a working minimal filter:

def villageFilter(poi):
    if poi['id'] == 'minecraft:sign':
        text = "\n".join([poi['Text1'], poi['Text2'], poi['Text3'], poi['Text4']]).strip()
          return text

People sometimes use signs for unconventional purposes, so you may want to filter empty ones:

def villageFilter(poi):
    if poi['id'] == 'minecraft:sign':
      text = "\n".join([poi['Text1'], poi['Text2'], poi['Text3'], poi['Text4']]).strip()
        if not text == '':
          return text

You may want to classify signs to differentiate between a village marker and a general purpose marker. This requires tagging each sign with dye. It changes the color of the text but not the sign. I use map markers that match the color.

def villageFilter(poi):
    if poi['id'] == 'minecraft:sign':
        if poi['Color'] == 'blue':
          text = "\n".join([poi['Text1'], poi['Text2'], poi['Text3'], poi['Text4']]).strip()
          if not text == '':
        return text

def markerFilter(poi):
    if poi['id'] == 'minecraft:sign':
        if poi['Color'] == 'red':
          text = "\n".join([poi['Text1'], poi['Text2'], poi['Text3'], poi['Text4']]).strip()
          if not text == '':
            return text

Then define in the config:

'markers': [
    dict(name="villages", icon="village.svg", showIconInLegend=True,  createInfoWindow=False, filterFunction=villageFilter),
    dict(name="markers", icon="marker.svg", showIconInLegend=True,  createInfoWindow=False, filterFunction=markerFilter)
],
Plagiatus commented 2 years ago

@JayGuerette are you sure that this works in the latest version of overviewer (0.17.47) and minecraft (1.18.2)? Because even when I copy your more basic one I cannot get it to show any signs at all in my world.

drnixon commented 2 years ago

Try using single quotes. The following works for me in 1.18.

# Shows all defined towns
def townFilter(poi):
    if poi['id'] == 'Town':
        return poi['name']

# Shows all signs
# Attempting to filter out signs with no text (generate naturally in spruce villages)
def signFilter(poi):
    if poi['id'] == 'Sign' or poi['id'] == 'minecraft:sign':
        if ''.join([poi['Text1'], poi['Text2'], poi['Text3'], poi['Text4']]) == "":
            return None
        else:
            return "\n".join([poi['Text1'], poi['Text2'], poi['Text3'], poi['Text4']])

I also call the filters differently for renders. Rather than embed the manual POIs in the render settings for each world, I define a list of POIs once which allows me to pull it in for multiple renders (e.g. overworld day and overworld night). An example below assuming you are using the town and sign POI from my example above.

# define list of towns for overworld
town_markers = [
       {'id': 'Town',   'x': 6300,  'y': 64,    'z': -1950, 'name': 'Test 1'},
       {'id': 'Town',   'x': 0, 'y': 64,    'z': 0, 'name': 'Test 2'}
    ]

# defines markers to show in all overworld renders
overworld_markers = [
    dict(
        name="Towns",
        filterFunction=townFilter,
        icon="icons/marker_town.png",
        ),
    dict(
        name="All signs",
        filterFunction=signFilter,
        )
    ]

# Renders overworld
renders["survivalday"] = {
    "world": "Survival",
    "title": "Your survival world",
    "rendermode": smooth_lighting,
    "dimension": "overworld",
    "defaultzoom": 7,
    'manualpois': town_markers,
    'markers': overworld_markers,
}

If you add a night render just include the 'markers: overworld_markers' bit and the same town and sign markers will be added without needing to redefine the towns on a per-render basis.

I have no idea whether single quotes are required for the manualpois and markers lines, but my render script has them this way and it works, so I leave it that way.

Plagiatus commented 2 years ago

I changed everything to single quotes, moved the markers into their own variables, but nothing seems to make them appear.

I'm using the exe file, not the py file. Might that have something to do with it?

CounterPillow commented 2 years ago

the problem isn't with your config, Minecraft just changed how it stores entities in 1.18 and overviewer doesn't support this yet.

@drnixon please don't waste people's time. The quotes used do not play a role at all.