Skip to content

Commit

Permalink
Save and load custom room map layouts.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaythebusinessgoose authored and gmjosack committed Dec 18, 2023
1 parent 94bf137 commit 920a7e9
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 10 deletions.
23 changes: 22 additions & 1 deletion src/modlunky2/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import shutil
import time
from enum import Enum
from typing import List, Optional, TypeVar, Set
from typing import Dict, List, Optional, TypeVar, Set

try:
import winreg
Expand Down Expand Up @@ -206,6 +206,21 @@ def level_sequence(cls):
def vanilla(cls):
return cls("Vanilla setroom [warning]", "setroom{y}-{x}", False)

@serialize(rename_all="kebabcase")
@deserialize(rename_all="kebabcase")
@dataclass
class CustomRoomMapSegment:
name: str
templates: List[List[str]]


@serialize(rename_all="kebabcase")
@deserialize(rename_all="kebabcase")
@dataclass
class CustomRoomMap:
name: str
segments: List[CustomRoomMapSegment]


@serialize(rename_all="kebabcase")
@deserialize(rename_all="kebabcase")
Expand Down Expand Up @@ -248,6 +263,12 @@ class Config:
custom_level_editor_default_save_format: Optional[CustomLevelSaveFormat] = field(
default=None, skip_if_default=True
)
custom_room_maps: Dict[str, List[CustomRoomMap]] = field(
default_factory=dict, skip_if_default=True
)
default_custom_room_maps: Dict[str, int] = field(
default_factory=dict, skip_if_default=True
)
command_prefix: Optional[List[str]] = field(default=None, skip_if_default=True)
api_port: int = field(default=9526)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from modlunky2.ui.levels.vanilla_levels.multi_room.room_map import (
find_roommap,
get_template_draw_item,
RoomMap,
)
from modlunky2.ui.levels.vanilla_levels.multi_room.template_draw_item import (
TemplateDrawItem,
Expand Down Expand Up @@ -73,6 +74,7 @@ def __init__(
self.tile_image_map = {}
self.room_templates = []
self.template_draw_map = []
self.default_draw_map = None
self.reverse_layers = True

self.zoom_level = zoom
Expand Down Expand Up @@ -146,6 +148,7 @@ def toggle_panel_hidden():
self.canvas.hide_grid_lines,
self.canvas.hide_room_lines,
self.__update_zoom_internal,
self.use_roommap_at,
self.change_template_at,
self.clear_template_at,
self.change_room_at,
Expand Down Expand Up @@ -173,14 +176,36 @@ def image_for_tile_code(self, tile_code):
self.tile_image_map[tile_name] = new_tile_image
return new_tile_image

def open_lvl(self, lvl, biome, tile_palette_map, room_templates):
self.lvl = lvl
self.lvl_biome = biome
self.tile_palette_map = tile_palette_map
self.tile_image_map = {}
self.room_templates = room_templates
def use_roommap_at(self, index):
if self.lvl is None:
return

def template_draw_map_for_roommap(room_map):
def get_template_draw_item_named(template_name):
if template_name is None:
return None
for index, template in enumerate(self.room_templates):
if template_name == template.name:
return get_template_draw_item(template, index)

return None

mappy = []
for segment in room_map.segments:
mappy.append(
RoomMap(
segment.name,
[[get_template_draw_item_named(template_name) for template_name in row] for row in segment.templates]
)
)
return mappy

room_maps = self.modlunky_config.custom_room_maps.get(self.lvl)
if index is None or index == -1 or index >= len(room_maps):
self.template_draw_map = self.default_draw_map
else:
self.template_draw_map = template_draw_map_for_roommap(room_maps[index])

self.template_draw_map = find_roommap(room_templates)
self.canvas.grid_remove()

self.canvas = MultiCanvasContainer(
Expand All @@ -200,9 +225,22 @@ def open_lvl(self, lvl, biome, tile_palette_map, room_templates):
self.show_intro()

self.options_panel.reset()
self.options_panel.set_templates(self.template_draw_map, room_templates)
self.options_panel.set_lvl(self.lvl)
self.options_panel.set_templates(self.template_draw_map, self.room_templates)
self.draw_canvas()

def open_lvl(self, lvl, biome, tile_palette_map, room_templates):
self.lvl = lvl
self.lvl_biome = biome
self.tile_palette_map = tile_palette_map
self.tile_image_map = {}
self.room_templates = room_templates

self.default_draw_map = find_roommap(room_templates)
# self.template_draw_map = find_roommap(room_templates)

self.use_roommap_at(self.modlunky_config.default_custom_room_maps.get(self.lvl))

def redraw(self):
self.canvas.clear()
self.show_intro()
Expand Down
118 changes: 117 additions & 1 deletion src/modlunky2/ui/levels/vanilla_levels/multi_room/options_panel.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import tkinter as tk
from tkinter import ttk

from modlunky2.config import Config
from modlunky2.config import Config, CustomRoomMap, CustomRoomMapSegment
from modlunky2.levels.level_templates import TemplateSetting
from modlunky2.ui.levels.vanilla_levels.multi_room.reversed_rooms import REVERSED_ROOMS
from modlunky2.ui.widgets import PopupWindow, ScrollableFrameLegacy
Expand Down Expand Up @@ -503,6 +503,7 @@ def __init__(
on_update_hide_grid_lines,
on_update_hide_room_lines,
on_update_zoom_level,
on_select_layout,
on_change_template_at,
on_clear_template,
on_select_room,
Expand All @@ -520,6 +521,7 @@ def __init__(
self.on_update_hide_grid_lines = on_update_hide_grid_lines
self.on_update_hide_room_lines = on_update_hide_room_lines
self.on_update_zoom_level = on_update_zoom_level
self.on_select_layout = on_select_layout
self.on_change_template_at = on_change_template_at
self.on_clear_template = on_clear_template
self.on_select_room = on_select_room
Expand All @@ -536,6 +538,7 @@ def __init__(

self.room_map = []
self.templates = []
self.lvl = None

self.button_for_selected_room = None
self.button_for_selected_empty_room = None
Expand Down Expand Up @@ -618,6 +621,32 @@ def update_grid_size(_):

settings_row += 1

self.layout_frame = tk.Frame(self.scrollview.scrollable_frame)
self.layout_frame.grid(row=settings_row, column=0, sticky="news", padx=10, pady=10)

self.layout_label = tk.Label(self.layout_frame, text="Layout:")
self.layout_label.grid(row=0, column=0, sticky="w")


self.layout_combobox = ttk.Combobox(self.layout_frame, height=25)
self.layout_combobox.grid(row=0, column=1, sticky="nsw", padx=(0, 10))
self.layout_combobox["values"] = ["Default"]
self.layout_combobox.set("Default")
self.layout_combobox["state"] = "readonly"
self.layout_combobox.bind(
"<<ComboboxSelected>>", lambda _: self.select_layout()
)

self.layout_combobox.grid_remove()
self.layout_label.grid_remove()

self.save_layout_button = tk.Button(self.layout_frame, text="Save layout", command=self.save_room_map)
self.save_layout_button.grid(row=0, column=2, sticky="w")
self.save_layout_button.grid_remove()
self.layout_frame.grid_remove()

settings_row += 1

self.room_type_frame = tk.Frame(self.scrollview.scrollable_frame)
self.room_type_frame.grid(
row=settings_row, column=0, sticky="news", padx=10, pady=10
Expand Down Expand Up @@ -652,18 +681,105 @@ def update_grid_size(_):
self.room_options.grid(row=settings_row, column=0, sticky="news")
self.room_options.grid_remove()


def save_room_map(self):
win = PopupWindow("Save Layout", self.modlunky_config)

item_name = ""

col1_lbl = ttk.Label(win, text="Name: ")
col1_ent = ttk.Entry(win)
col1_ent.insert(0, item_name) # Default to rooms current name
col1_lbl.grid(row=0, column=0, padx=2, pady=2, sticky="nse")
col1_ent.grid(row=0, column=1, padx=2, pady=2, sticky="news")

def save_and_destroy():
if col1_ent.get() == "":
return
segments = []
for template_map in self.room_map:
segment = CustomRoomMapSegment(
template_map.name,
[[room.template.name if room else "" for room in row] for row in template_map.rooms]
)
segments.append(segment)
room_map = CustomRoomMap(col1_ent.get(), segments)
level_room_maps = self.modlunky_config.custom_room_maps.get(self.lvl)
if level_room_maps is None:
level_room_maps = []
level_room_maps.append(room_map)
self.modlunky_config.custom_room_maps[self.lvl] = level_room_maps
self.modlunky_config.default_custom_room_maps[self.lvl] = len(level_room_maps) - 1
self.modlunky_config.save()
self.update_layouts()

win.destroy()

separator = ttk.Separator(win)
separator.grid(row=1, column=0, columnspan=2, pady=5, sticky="news")

buttons = ttk.Frame(win)
buttons.grid(row=2, column=0, columnspan=2, sticky="news")
buttons.columnconfigure(0, weight=1)
buttons.columnconfigure(1, weight=1)

ok_button = ttk.Button(buttons, text="Save", command=save_and_destroy)
ok_button.grid(row=0, column=0, pady=5, sticky="news")

cancel_button = ttk.Button(buttons, text="Cancel", command=win.destroy)
cancel_button.grid(row=0, column=1, pady=5, sticky="news")

def update_room_map_template(self, template_index, map_index, row, column):
template = self.templates[template_index]
self.on_change_template_at(map_index, row, column, template, template_index)
self.layout_frame.grid()
self.save_layout_button.grid()

def clear_template(self, map_index, row, column):
self.on_clear_template(map_index, row, column)
self.layout_frame.grid()
self.save_layout_button.grid()

def reset(self):
self.button_for_selected_room = None
self.button_for_selected_empty_room = None
self.room_options.grid_remove()
self.room_options.reset()
self.layout_frame.grid_remove()
self.save_layout_button.grid_remove()

def select_layout(self):
selected_layout = self.layout_combobox.current()
if selected_layout is None:
selected_layout = 0

self.modlunky_config.default_custom_room_maps[self.lvl] = selected_layout - 1
self.on_select_layout(selected_layout - 1)
self.modlunky_config.save()

def update_layouts(self):
level_room_maps = self.modlunky_config.custom_room_maps.get(self.lvl)
if level_room_maps is not None and len(level_room_maps) > 0:
self.layout_combobox.grid()
self.layout_label.grid()
self.layout_frame.grid()
self.layout_combobox["values"] = ["Default"] + [map.name for map in level_room_maps]
default_layout = self.modlunky_config.default_custom_room_maps.get(self.lvl)
layout_index = default_layout + 1 if default_layout is not None else 0
self.layout_combobox.current(layout_index)
self.layout_combobox.set(self.layout_combobox["values"][layout_index])
else:
self.layout_combobox.grid_remove()
self.layout_label.grid_remove()

def set_lvl(self, lvl):
self.lvl = lvl
self.layout_frame.grid_remove()
self.save_layout_button.grid_remove()
self.layout_combobox.grid_remove()
self.layout_label.grid_remove()

self.update_layouts()

def set_templates(self, room_map, templates):
self.button_for_selected_room = None
Expand Down

0 comments on commit 920a7e9

Please sign in to comment.