Repository navigation
feat: plot Midtown breakables on the current minimap #460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kai8484
wants to merge
21
commits into
develop
Choose a base branch
from
new-midtown-breakables-map
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+398
−201
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
d6853f4
Plot Midtown breakables on the current minimap
kai8484 ddd9eed
Outline breakables map dots so neighbouring dots stay distinct
kai8484 f3a1e8c
Split Midtown breakables maps by spawn time and address review
kai8484 e48e250
Use opaque Midtown minimap and enlarge breakables legend
ThePyrotechnic 9b08822
Reuse _world_to_pixel for breakables dots
ThePyrotechnic 9adc9bb
Skip Maps category check on dry runs
ThePyrotechnic a5091fa
Tidy compact legend after restyle
ThePyrotechnic 63cbe3b
remove unused assets
ThePyrotechnic ceafb27
Pass spawn order to _breakables_plot explicitly
ThePyrotechnic e26930d
Plot single-kind breakables maps from BREAKABLES
ThePyrotechnic e5e6076
Export map_file_stems from game_map
ThePyrotechnic d8eeb2a
Derive uploaded map files from game_map.map_file_stems
ThePyrotechnic 8483609
Update stale everything_5min example in game_map comment
ThePyrotechnic 78ea39e
Default MapPlotter to the base map's own size
ThePyrotechnic 5737ac7
Scale breakables dot radius with the output size
ThePyrotechnic c504944
Correct _breakables_plot docstring after the move to MAP_OUTPUT_SIZE
ThePyrotechnic ecdfcc6
Warn when breakables map colours fall back to a shared colour
ThePyrotechnic f4d9d12
Merge develop and resolve import conflicts
kai8484 d13e856
Shrink map PNGs with nearest-neighbour upscaling and palette saving
kai8484 c2b10e3
Use the Source2Viewer CLI in update_minimap.py instead of a custom VP…
kai8484 2dc8ef2
fix: fixed png path
hassayag File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| """ | ||
| Regenerate the Midtown base map used by the game_map parser from an installed copy of Deadlock | ||
|
|
||
| The minimap texture lives in game/citadel/pak01_*.vpk, which deadbot does not download, so the | ||
| map is committed to src/parser/parsers/game_map/assets/minimap_midtown_opaque.png. | ||
| Re-run this whenever the map changes. | ||
|
|
||
| Requires the Source2Viewer CLI (https://github.com/ValveResourceFormat/ValveResourceFormat/releases), | ||
| passed with --decompiler or the DECOMPILER_CMD environment variable: | ||
|
|
||
| python scripts/update_minimap.py --game "C:/Program Files (x86)/Steam/steamapps/common/Deadlock/game" --decompiler Source2Viewer-CLI.exe | ||
| """ | ||
|
|
||
| import argparse | ||
| import os | ||
| import subprocess | ||
| import tempfile | ||
| from pathlib import Path | ||
|
|
||
| from PIL import Image | ||
|
|
||
| # The street map. Older revisions ship alongside it with a hash suffix, e.g. minimap_midtown_mid_psd_dd4bcbf9.vtex_c | ||
| MINIMAP_TEXTURE = 'panorama/images/minimap/base/minimap_midtown_mid_psd.vtex_c' | ||
| OUTPUT_PATH = Path('src/parser/parsers/game_map/assets/minimap_midtown_opaque.png') | ||
| # The texture is translucent everywhere, so it is drawn onto this colour to make it readable on any page background | ||
| BACKGROUND = (175, 161, 144) | ||
|
|
||
|
|
||
| def _srgb_to_linear(value: int) -> float: | ||
| c = value / 255 | ||
| return c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4 | ||
|
|
||
|
|
||
| def _linear_to_srgb(c: float) -> int: | ||
| c = c * 12.92 if c <= 0.0031308 else 1.055 * c ** (1 / 2.4) - 0.055 | ||
| return round(min(max(c, 0), 1) * 255) | ||
|
|
||
|
|
||
| SRGB_TO_LINEAR = [_srgb_to_linear(v) for v in range(256)] | ||
|
|
||
|
|
||
| def extract_minimap(decompiler: str, game_dir: str, texture: str) -> Image.Image: | ||
| """Export the minimap texture from pak01 as a PNG with the Source2Viewer CLI""" | ||
| vpk = os.path.join(game_dir, 'citadel', 'pak01_dir.vpk') | ||
|
|
||
| with tempfile.TemporaryDirectory() as tmp: | ||
| output_dir = os.path.join(tmp, 'minimap.png') | ||
|
|
||
| # With a --vpk_filepath matching a single file, --output is that file's path | ||
| subprocess.run([decompiler, '-i', vpk, '--vpk_filepath', texture, '-o', output_dir, '-d'], check=True) | ||
|
|
||
| png = Path(output_dir) / Path(texture).with_suffix('.png') | ||
| with Image.open(png) as image: | ||
| return image.convert('RGBA') | ||
|
|
||
|
|
||
| def flatten(image: Image.Image, background: tuple[int, int, int]) -> Image.Image: | ||
| """ | ||
| Draw an RGBA image onto a solid background. Blends in linear light, like image editors do, rather than on the | ||
| raw sRGB values, which would leave the translucent map much darker | ||
| """ | ||
| background_linear = [SRGB_TO_LINEAR[c] for c in background] | ||
| rgba = image.convert('RGBA').tobytes() | ||
| pixels = bytearray() | ||
| for i in range(0, len(rgba), 4): | ||
| a = rgba[i + 3] / 255 | ||
| pixels += bytes(_linear_to_srgb(SRGB_TO_LINEAR[c] * a + bg * (1 - a)) for c, bg in zip(rgba[i : i + 3], background_linear)) | ||
| return Image.frombytes('RGB', image.size, bytes(pixels)) | ||
|
|
||
|
|
||
| def main(): | ||
| parser = argparse.ArgumentParser(description='Regenerate the Midtown base map asset from the game files') | ||
| parser.add_argument('--game', required=True, help='Deadlock game directory, the one containing citadel/') | ||
| parser.add_argument('--decompiler', default=os.getenv('DECOMPILER_CMD'), help='Path to the Source2Viewer CLI (default: $DECOMPILER_CMD)') | ||
| parser.add_argument('--texture', default=MINIMAP_TEXTURE, help=f'Minimap texture inside pak01 (default: {MINIMAP_TEXTURE})') | ||
| parser.add_argument('--out', default=OUTPUT_PATH, type=Path, help=f'Output path (default: {OUTPUT_PATH})') | ||
| args = parser.parse_args() | ||
| if not args.decompiler: | ||
| parser.error('pass --decompiler or set DECOMPILER_CMD to the Source2Viewer CLI') | ||
|
|
||
| image = flatten(extract_minimap(args.decompiler, args.game, args.texture), BACKGROUND) | ||
| image.save(args.out, optimize=True) | ||
| print(f'Wrote {image.width}x{image.height} map to {args.out}') | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| from .__main__ import GameMapParser as GameMapParser | ||
| from .__main__ import map_file_stems as map_file_stems |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate you've written a vpk parser 🤯. We can instead do this much easier with the source2viewer cli. We used to use this to parse vpk files before the days of SteamDB integration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, swapped it out for the Source2Viewer CLI. The script now just runs
-i pak01_dir.vpk --vpk_filepath panorama/images/minimap/base/minimap_midtown_mid_psd.vtex_c -o … -d, using--decompileror$DECOMPILER_CMDlike deadbot used to, then flattens the texture onto the tan background to produceminimap_midtown_opaque.png. The flatten blends in linear light so it matches the committed map, to within 1/255.