about summary refs log tree commit diff stats
path: root/apworld
diff options
context:
space:
mode:
Diffstat (limited to 'apworld')
-rw-r--r--apworld/__init__.py10
-rw-r--r--apworld/client/manager.gd16
-rw-r--r--apworld/client/minimap.gd13
-rw-r--r--apworld/regions.py6
4 files changed, 38 insertions, 7 deletions
diff --git a/apworld/__init__.py b/apworld/__init__.py index 9e445c7..e126fc0 100644 --- a/apworld/__init__.py +++ b/apworld/__init__.py
@@ -4,6 +4,7 @@ Archipelago init file for Lingo 2
4from typing import ClassVar 4from typing import ClassVar
5 5
6from BaseClasses import ItemClassification, Item, Tutorial 6from BaseClasses import ItemClassification, Item, Tutorial
7from Options import OptionError
7from settings import Group, UserFilePath 8from settings import Group, UserFilePath
8from worlds.AutoWorld import WebWorld, World 9from worlds.AutoWorld import WebWorld, World
9from .items import Lingo2Item, ANTI_COLLECTABLE_TRAPS 10from .items import Lingo2Item, ANTI_COLLECTABLE_TRAPS
@@ -82,9 +83,9 @@ class Lingo2World(World):
82 else: 83 else:
83 shuffle_entrances(self) 84 shuffle_entrances(self)
84 85
85 from Utils import visualize_regions 86 #from Utils import visualize_regions
86 87
87 visualize_regions(self.multiworld.get_region("Menu", self.player), "my_world.puml") 88 #visualize_regions(self.multiworld.get_region("Menu", self.player), "my_world.puml")
88 89
89 def create_items(self): 90 def create_items(self):
90 pool = [self.create_item(name) for name in self.player_logic.real_items] 91 pool = [self.create_item(name) for name in self.player_logic.real_items]
@@ -109,6 +110,11 @@ class Lingo2World(World):
109 for i in range(0, item_difference): 110 for i in range(0, item_difference):
110 pool.append(self.create_item(self.get_filler_item_name())) 111 pool.append(self.create_item(self.get_filler_item_name()))
111 112
113 if not any(ItemClassification.progression in item.classification for item in pool):
114 raise OptionError(f"Lingo 2 player {self.player} has no progression items. Please enable at least one "
115 f"option that would add progression gating to your world, such as Shuffle Doors or "
116 f"Shuffle Letters.")
117
112 self.multiworld.itempool += pool 118 self.multiworld.itempool += pool
113 119
114 def create_item(self, name: str) -> Item: 120 def create_item(self, name: str) -> Item:
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index 4f5018f..dac09b2 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd
@@ -75,6 +75,8 @@ var strict_cyan_ending = false
75var strict_purple_ending = false 75var strict_purple_ending = false
76var victory_condition = -1 76var victory_condition = -1
77 77
78var color_by_material_path = {}
79
78signal could_not_connect 80signal could_not_connect
79signal connect_status 81signal connect_status
80signal ap_connected 82signal ap_connected
@@ -112,6 +114,20 @@ func _init():
112 if data.size() > 6: 114 if data.size() > 6:
113 show_minimap = data[6] 115 show_minimap = data[6]
114 116
117 # We need to create a mapping from material paths to the original colors of
118 # those materials. We force reload the materials, overwriting any custom
119 # textures, and create the mapping. We then reload the textures in case the
120 # player had a custom one enabled.
121 var directory = DirAccess.open("res://assets/materials")
122 for material_name in directory.get_files():
123 var material = ResourceLoader.load(
124 "res://assets/materials/" + material_name, "", ResourceLoader.CACHE_MODE_REPLACE
125 )
126
127 color_by_material_path[material.resource_path] = Color(material.albedo_color)
128
129 settings.load_user_textures()
130
115 131
116func _ready(): 132func _ready():
117 client = SCRIPT_client.new() 133 client = SCRIPT_client.new()
diff --git a/apworld/client/minimap.gd b/apworld/client/minimap.gd index 5640716..bf70114 100644 --- a/apworld/client/minimap.gd +++ b/apworld/client/minimap.gd
@@ -126,6 +126,7 @@ func _process(_delta):
126 126
127 127
128func _renderMap(gridmap): 128func _renderMap(gridmap):
129 var ap = global.get_node("Archipelago")
129 var heights = {} 130 var heights = {}
130 131
131 var rendered = Image.create_empty(cell_width, cell_height, false, Image.FORMAT_RGBA8) 132 var rendered = Image.create_empty(cell_width, cell_height, false, Image.FORMAT_RGBA8)
@@ -133,7 +134,7 @@ func _renderMap(gridmap):
133 134
134 var meshes_node = get_tree().get_root().get_node("scene/Meshes") 135 var meshes_node = get_tree().get_root().get_node("scene/Meshes")
135 if meshes_node != null: 136 if meshes_node != null:
136 _renderMeshNode(gridmap, meshes_node, rendered) 137 _renderMeshNode(ap, gridmap, meshes_node, rendered)
137 138
138 for pos in gridmap.get_used_cells(): 139 for pos in gridmap.get_used_cells():
139 var in_plane = Vector2i(pos.x, pos.z) 140 var in_plane = Vector2i(pos.x, pos.z)
@@ -146,20 +147,22 @@ func _renderMap(gridmap):
146 var cell_item = gridmap.get_cell_item(pos) 147 var cell_item = gridmap.get_cell_item(pos)
147 var mesh = gridmap.mesh_library.get_item_mesh(cell_item) 148 var mesh = gridmap.mesh_library.get_item_mesh(cell_item)
148 var material = mesh.surface_get_material(0) 149 var material = mesh.surface_get_material(0)
149 var color = material.albedo_color 150 var color = ap.color_by_material_path.get(material.resource_path, Color.TRANSPARENT)
150 151
151 rendered.set_pixel(pos.x - cell_left, pos.z - cell_top, color) 152 rendered.set_pixel(pos.x - cell_left, pos.z - cell_top, color)
152 153
153 return rendered 154 return rendered
154 155
155 156
156func _renderMeshNode(gridmap, mesh, rendered): 157func _renderMeshNode(ap, gridmap, mesh, rendered):
157 if mesh is MeshInstance3D: 158 if mesh is MeshInstance3D:
158 var local_tl = gridmap.map_to_local(Vector3i(cell_left, 0, cell_top)) 159 var local_tl = gridmap.map_to_local(Vector3i(cell_left, 0, cell_top))
159 var global_tl = gridmap.to_global(local_tl) 160 var global_tl = gridmap.to_global(local_tl)
160 var mesh_material = mesh.get_surface_override_material(0) 161 var mesh_material = mesh.get_surface_override_material(0)
161 if mesh_material != null: 162 if mesh_material != null:
162 var mesh_color = mesh_material.albedo_color 163 var mesh_color = ap.color_by_material_path.get(
164 mesh_material.resource_path, Color.TRANSPARENT
165 )
163 166
164 for y in range( 167 for y in range(
165 max(mesh.position.z - mesh.scale.z / 2 - global_tl.z, 0), 168 max(mesh.position.z - mesh.scale.z / 2 - global_tl.z, 0),
@@ -172,4 +175,4 @@ func _renderMeshNode(gridmap, mesh, rendered):
172 rendered.set_pixel(x, y, mesh_color) 175 rendered.set_pixel(x, y, mesh_color)
173 176
174 for child in mesh.get_children(): 177 for child in mesh.get_children():
175 _renderMeshNode(gridmap, child, rendered) 178 _renderMeshNode(ap, gridmap, child, rendered)
diff --git a/apworld/regions.py b/apworld/regions.py index 1215f5a..0c3858d 100644 --- a/apworld/regions.py +++ b/apworld/regions.py
@@ -132,6 +132,12 @@ def create_regions(world: "Lingo2World"):
132 reqs.simplify() 132 reqs.simplify()
133 reqs.remove_room(from_region) 133 reqs.remove_room(from_region)
134 134
135 if to_region in reqs.rooms:
136 # This connection can't ever increase access because you're required to have access to the other side in
137 # order for it to be usable. We will just not create the connection at all, in order to help GER figure out
138 # what regions are dead ends.
139 continue
140
135 connection = Entrance(world.player, connection_name, regions[from_region]) 141 connection = Entrance(world.player, connection_name, regions[from_region])
136 connection.access_rule = make_location_lambda(reqs, world, regions) 142 connection.access_rule = make_location_lambda(reqs, world, regions)
137 143