diff --git a/attribution.txt b/attribution.txt index 3431abc..b00eb79 100644 --- a/attribution.txt +++ b/attribution.txt @@ -9,3 +9,5 @@ cogs by Chameleon Design from the Noun Project temple by rivercon from the Noun Project Beer by Serhii Smirnov from the Noun Project Caravel by Rahmat Hidayat from the Noun Project +question mark by Icon Lauk from the Noun Project +Hiking Trail by Weltenraser from the Noun Project diff --git a/questhelper/map/map_generator.py b/questhelper/map/map_generator.py index 556e105..6ef4929 100644 --- a/questhelper/map/map_generator.py +++ b/questhelper/map/map_generator.py @@ -1,5 +1,42 @@ -from map.quest_map import QuestMap +import random +from typing import List + +import map.quest_map +from map.quest_map import QuestMap, MapEncounter, EncounterType + + +def generate_encounter_inaccessible() -> MapEncounter: + return MapEncounter(EncounterType.INACCESSIBLE) + + +def generate_encounter_battle(battle_type: EncounterType): + assert battle_type in map.quest_map.ENCOUNTER_TYPES_BATTLE + return MapEncounter(battle_type) + + +def generate_encounter_town(): + town_type = random.choice(map.quest_map.ENCOUNTER_TYPES_TOWN) + return MapEncounter(town_type) def generate_map() -> QuestMap: - return QuestMap() + quest_map = QuestMap() + encounters_rows = [] + for r in range(11): + row: List[MapEncounter] = [] + if r == 10: + row.append(generate_encounter_inaccessible()) + row.append(generate_encounter_battle(EncounterType.BATTLE_BOSS)) + row.append(generate_encounter_inaccessible()) + elif r in (1, 4, 7): + elite_column = random.randrange(4) # 75% chance of elite + for c in range(3): + battle_type = EncounterType.BATTLE_ELITE if c == elite_column else EncounterType.BATTLE_REGULAR + row.append(generate_encounter_battle(battle_type)) + else: + for c in range(3): + row.append(generate_encounter_town()) + encounters_rows.append(row) + + quest_map.encounters = encounters_rows + return quest_map diff --git a/questhelper/map/map_renderer.py b/questhelper/map/map_renderer.py index b98ee33..52a59a4 100644 --- a/questhelper/map/map_renderer.py +++ b/questhelper/map/map_renderer.py @@ -1,13 +1,50 @@ from map.quest_map import MapEncounter, QuestMap, EncounterType +from typing import List, Dict, Optional + _ICONS = { - EncounterType.BATTLE_REGULAR: 'noun_Battle_3647629.png' + EncounterType.BATTLE_REGULAR: 'noun_Battle_3647629.png', + EncounterType.BATTLE_ELITE: 'noun_Shield_3806325.png', + EncounterType.BATTLE_BOSS: 'noun_dragon_3820621.png', + EncounterType.TOWN_TAVERN: 'noun_Beer_3054928.png', + EncounterType.TOWN_DOCKS: 'noun_Caravel_2421659.png', + EncounterType.TOWN_MARKET: 'noun_Store_786819.png', + EncounterType.TOWN_LIBRARY: 'noun_Library_3820590.png', + EncounterType.TOWN_WORKSHOP: 'noun_cogs_442166.png', + EncounterType.TOWN_TOWN_HALL: 'noun_brussels town hall_3284349.png', + EncounterType.TOWN_TEMPLE: 'noun_temple_2382601.png', + EncounterType.TOWN_REST: 'noun_Tent_3814999.png', + EncounterType.TOWN_ROAD: 'noun_Hiking Trail_2686687.png', } -def render_map(quest_map: QuestMap): - return [__render_encounter(MapEncounter(EncounterType.BATTLE_REGULAR))] * 3 +def render_map(quest_map: QuestMap) -> List[Dict]: + rendered_encounters = [] + + row: List[MapEncounter] + for r, row in enumerate(quest_map.encounters): + for c, encounter in enumerate(row): + rendered_encounter = _render_encounter(r, c, encounter) + if rendered_encounter is not None: + rendered_encounters.append(rendered_encounter) + + return rendered_encounters -def __render_encounter(encounter: MapEncounter): - return f'map/{_ICONS[encounter.type]}' +def _render_encounter(r: int, c: int, encounter: MapEncounter) -> Optional[Dict]: + if encounter.type == EncounterType.INACCESSIBLE: + return None + + icon = f'map/{_ICONS[encounter.type]}' + x = 200 * c + y = 100 * r + w = 90 + h = 90 + return { + 'description': encounter.description, + 'src': icon, + 'x': x, + 'y': y, + 'w': w, + 'h': h, + } diff --git a/questhelper/map/quest_map.py b/questhelper/map/quest_map.py index 0f5020e..b37f42a 100644 --- a/questhelper/map/quest_map.py +++ b/questhelper/map/quest_map.py @@ -1,16 +1,66 @@ import dataclasses import enum +from typing import List + class EncounterType(enum.Enum): + INACCESSIBLE = 'inaccessible' BATTLE_REGULAR = 'battle_regular' + BATTLE_ELITE = 'battle_elite' + BATTLE_BOSS = 'battle_boss' + TOWN_TAVERN = 'town_tavern' + TOWN_DOCKS = 'town_docks' + TOWN_MARKET = 'town_market' + TOWN_LIBRARY = 'town_library' + TOWN_WORKSHOP = 'town_workshop' + TOWN_TOWN_HALL = 'town_town_hall' + TOWN_TEMPLE = 'town_temple' + TOWN_REST = 'town_rest' + TOWN_ROAD = 'town_road' -class QuestMap: - def __init__(self): - pass +ENCOUNTER_TYPES_BATTLE = [ + EncounterType.BATTLE_REGULAR, + EncounterType.BATTLE_ELITE, + EncounterType.BATTLE_BOSS, +] + + +ENCOUNTER_TYPES_TOWN = [ + EncounterType.TOWN_TAVERN, + EncounterType.TOWN_DOCKS, + EncounterType.TOWN_MARKET, + EncounterType.TOWN_LIBRARY, + EncounterType.TOWN_WORKSHOP, + EncounterType.TOWN_TOWN_HALL, + EncounterType.TOWN_TEMPLE, + EncounterType.TOWN_REST, + EncounterType.TOWN_ROAD, +] + + +class DiagonalPath(enum.Enum): + NO_PATH = 'no_path' + TOWARDS_LEFT = 'towards_left' + TOWARDS_RIGHT = 'towards_right' @dataclasses.dataclass class MapEncounter: type: EncounterType + + @property + def description(self): + return str(self.type) + + +class QuestMap: + def __init__(self): + # List of rows of encounters, each row has 3 encounters. + # Starts with earlier encounter, ends with boss encounter. + # Inaccessible encounters can be None (like in last line). + self.encounters: List[List[MapEncounter]] = [] + + # List of rows of diagonal paths, each row has 2 paths. + self.diagonals: List[List[DiagonalPath]] = [] diff --git a/questhelper/map/static/map/noun_Hiking Trail_2686687.png b/questhelper/map/static/map/noun_Hiking Trail_2686687.png new file mode 100644 index 0000000..abadcaf Binary files /dev/null and b/questhelper/map/static/map/noun_Hiking Trail_2686687.png differ diff --git a/questhelper/map/static/map/noun_question mark_3204388.png b/questhelper/map/static/map/noun_question mark_3204388.png new file mode 100644 index 0000000..c5db949 Binary files /dev/null and b/questhelper/map/static/map/noun_question mark_3204388.png differ diff --git a/questhelper/map/templates/map/index.html b/questhelper/map/templates/map/index.html index 389655b..70ac730 100644 --- a/questhelper/map/templates/map/index.html +++ b/questhelper/map/templates/map/index.html @@ -2,10 +2,16 @@

Map

- + + diff --git a/questhelper/map/views.py b/questhelper/map/views.py index 2d4f47c..404025f 100644 --- a/questhelper/map/views.py +++ b/questhelper/map/views.py @@ -11,5 +11,5 @@ def index(request): rendered_map = map_renderer.render_map(quest_map) template = loader.get_template('map/index.html') - context = {'rooms': rendered_map} + context = {'encounters': rendered_map} return HttpResponse(template.render(context, request))