From f6b0f860f762d10583de80967cb969b1a84a627a Mon Sep 17 00:00:00 2001 From: henriquenakashima Date: Sun, 28 Mar 2021 15:09:08 -0400 Subject: [PATCH] Render encounters --- attribution.txt | 2 + questhelper/map/map_generator.py | 41 ++++++++++++- questhelper/map/map_renderer.py | 47 +++++++++++++-- questhelper/map/quest_map.py | 56 +++++++++++++++++- .../static/map/noun_Hiking Trail_2686687.png | Bin 0 -> 19295 bytes .../static/map/noun_question mark_3204388.png | Bin 0 -> 13301 bytes questhelper/map/templates/map/index.html | 16 +++-- questhelper/map/views.py | 2 +- 8 files changed, 148 insertions(+), 16 deletions(-) create mode 100644 questhelper/map/static/map/noun_Hiking Trail_2686687.png create mode 100644 questhelper/map/static/map/noun_question mark_3204388.png 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 0000000000000000000000000000000000000000..abadcafe879d8e4a8a738600b974d6d200899d6f GIT binary patch literal 19295 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

Map

-
    -My image -{% for room in rooms %} -
  • {{ room }}
  • + +
    +{% for e in encounters %} + {{e.description}} {% endfor %} -
+ + 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))