diff options
656 files changed, 13266 insertions, 1549 deletions
diff --git a/.gitignore b/.gitignore index b30b031..05901b2 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -5,3 +5,4 @@ apworld/generated/ | |||
5 | __pycache__ | 5 | __pycache__ |
6 | .vs/ | 6 | .vs/ |
7 | ^out/ | 7 | ^out/ |
8 | client/Archipelago/generated/ | ||
diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..131b8a0 --- /dev/null +++ b/CHANGELOG.md | |||
@@ -0,0 +1,229 @@ | |||
1 | # lingo2-archipelago Releases | ||
2 | |||
3 | ## v7.1.0 - 2025-10-07 | ||
4 | |||
5 | - Added a "Get Path" button to the locations tracker. This shows you the path | ||
6 | you're currently expected to be able to take in order to reach that | ||
7 | location/worldport/goal. | ||
8 | - Worldport names in the spoiler log have been changed to be more descriptive. | ||
9 | - Jumping into The Graveyard from The Sun Temple is now in logic. | ||
10 | - Solving the FLIP panels above the Liberated and Literate entrances by looking | ||
11 | up is now in logic. | ||
12 | - Renamed some locations so that they're shorter. | ||
13 | - Fixed bug where White Ending would kick the player out of Archipelago. | ||
14 | - Fixed bug where the minimap would be completely white when a texture pack is | ||
15 | enabled. | ||
16 | - Generation failures while shuffling worldports should be significantly less | ||
17 | common. | ||
18 | |||
19 | Download: | ||
20 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.1.0/lingo2.apworld)<br/> | ||
21 | Template YAML: | ||
22 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.1.0/Lingo%202.yaml)<br/> | ||
23 | Source: [v7.1.0](https://code.fourisland.com/lingo2-archipelago/tag/?h=v7.1.0) | ||
24 | |||
25 | ## v7.0.2 - 2025-10-03 | ||
26 | |||
27 | - Fixed issue connecting to password-protected slots. | ||
28 | - Added instructions for using the client on Linux. | ||
29 | |||
30 | Download: | ||
31 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.0.2/lingo2.apworld)<br/> | ||
32 | Template YAML: | ||
33 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.0.2/Lingo%202.yaml)<br/> | ||
34 | Source: [v7.0.2](https://code.fourisland.com/lingo2-archipelago/tag/?h=v7.0.2) | ||
35 | |||
36 | ## v7.0.1 - 2025-10-01 | ||
37 | |||
38 | - Fixed logic error regarding the Plaza Entrance in The Repetitive. Going from | ||
39 | The Plaza to The Repetitive does not require the door to be open in vanilla | ||
40 | doors, but both directions require the door item when doors are shuffled. | ||
41 | - Fixed Worldports tracker tab getting messed up after disconnecting and | ||
42 | reconnecting to multiworld. | ||
43 | - Improved error messages when failing to connect. The game now also shows you | ||
44 | when your connection has dropped. | ||
45 | |||
46 | Download: | ||
47 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.0.1/lingo2.apworld)<br/> | ||
48 | Template YAML: | ||
49 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.0.1/Lingo%202.yaml)<br/> | ||
50 | Source: [v7.0.1](https://code.fourisland.com/lingo2-archipelago/tag/?h=v7.0.1) | ||
51 | |||
52 | ## v7.0.0 - 2025-09-30 | ||
53 | |||
54 | - Major update! First and foremost: the client and apworld are no longer | ||
55 | separate! There is only an apworld now, which you install into your | ||
56 | Archipelago custom worlds folder as per normal. In order to play a randomized | ||
57 | world, you open the Archipelago Launcher and click Lingo 2 Client. The first | ||
58 | time you do this, it will ask you for the location of your Lingo2.exe, which | ||
59 | you can find by right clicking on the game in Steam and clicking Browse Local | ||
60 | Files. | ||
61 | - **Built-in tracker**: The in-game text client has a new tab called "Locations" | ||
62 | which lists the currently accessible locations similar to how Universal | ||
63 | Tracker does it. There is also an optional overlay you can enable in the | ||
64 | settings, which shows you some of your accessible locations on screen while | ||
65 | you're playing. If you're playing with vanilla letters, the tracker won't show | ||
66 | you locations that are solvable with letters until you collect the actual | ||
67 | letters, in order to help direct you better. More features will be coming to | ||
68 | the tracker in the future! | ||
69 | - **Worldport shuffle**: The first part of entrance randomization is here! | ||
70 | Enabling this shuffles the destinations of the worldports, which are the | ||
71 | loading zones you walk into in order to change maps. Some restrictions apply, | ||
72 | which are noted in the option description. The tracker will show a list of | ||
73 | worldports you haven't entered yet, and will also not show you what lies | ||
74 | beyond a worldport until you've entered it. There is also a tab in the | ||
75 | textclient showing you the mapping between worldports you've already entered. | ||
76 | - **Minimap**: There is an option in the settings to show a minimap in the | ||
77 | corner of the screen. This shows an overhead view of the map you're on, and | ||
78 | where you are in it. More features will be coming to the minimap in the | ||
79 | future! | ||
80 | - Fixed the gate outside the Daedalus entrance in The Great not opening when | ||
81 | control center colors are shuffled. | ||
82 | |||
83 | Download: | ||
84 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.0.0/lingo2.apworld)<br/> | ||
85 | Template YAML: | ||
86 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v7.0.0/Lingo%202.yaml)<br/> | ||
87 | Source: [v7.0.0](https://code.fourisland.com/lingo2-archipelago/tag/?h=v7.0.0) | ||
88 | |||
89 | ## Legacy Client v6.7 - 2025-09-19 | ||
90 | |||
91 | - Added a compass overlay. This makes it clearer which direction corresponds to | ||
92 | which compass direction, which is useful since many location/item names | ||
93 | reference compass directions. It can be enabled in the settings screen on the | ||
94 | pause menu. | ||
95 | - Compatability update for the changes in v6.6 of the apworld. | ||
96 | |||
97 | Download: | ||
98 | [lingo2-archipelago-client-v6.7.zip](https://files.fourisland.com/releases/lingo2-archipelago/client/lingo2-archipelago-client-v6.7.zip)<br/> | ||
99 | Source: | ||
100 | [v6.7](https://code.fourisland.com/lingo2-archipelago/tag/?h=client-v6.7) | ||
101 | |||
102 | ## Legacy Apworld v6.6 - 2025-09-19 | ||
103 | |||
104 | - Added options that make the requirements for Purple Ending and Cyan Ending | ||
105 | stricter. With the strict options on, players are required to have all purple | ||
106 | (level 1) letters in order to get Purple Ending, and all cyan (level 2) | ||
107 | letters to get Cyan Ending. These options are on by default. | ||
108 | - Renamed several items and locations, mostly regarding changing relative | ||
109 | directions (left, right, etc) to compass directions. The colored SMILE panels | ||
110 | in Daedalus now have clearer names too. | ||
111 | - Fixed some minor logic errors. | ||
112 | |||
113 | Download: | ||
114 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v6.6/lingo2.apworld)<br/> | ||
115 | Template YAML: | ||
116 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v6.6/Lingo%202.yaml)<br/> | ||
117 | Source: | ||
118 | [v6.6](https://code.fourisland.com/lingo2-archipelago/tag/?h=apworld-v6.6) | ||
119 | |||
120 | ## Legacy Client v5.6 - 2025-09-17 | ||
121 | |||
122 | - Letter locations will no longer reappear after being collected. | ||
123 | - This also prevents a potential scenario in which it is impossible to access | ||
124 | the location "The Congruent - Obverse Yellow Puzzles" when door shuffle is | ||
125 | disabled. | ||
126 | |||
127 | Download: | ||
128 | [lingo2-archipelago-client-v5.6.zip](https://files.fourisland.com/releases/lingo2-archipelago/client/lingo2-archipelago-client-v5.6.zip)<br/> | ||
129 | Source: | ||
130 | [v5.6](https://code.fourisland.com/lingo2-archipelago/tag/?h=client-v5.6) | ||
131 | |||
132 | ## Legacy Client v5.5 - 2025-09-16 | ||
133 | |||
134 | - Compatability update for v5.5 of the apworld. | ||
135 | |||
136 | Download: | ||
137 | [lingo2-archipelago-client-v5.5.zip](https://files.fourisland.com/releases/lingo2-archipelago/client/lingo2-archipelago-client-v5.5.zip)<br/> | ||
138 | Source: | ||
139 | [v5.5](https://code.fourisland.com/lingo2-archipelago/tag/?h=client-v5.5) | ||
140 | |||
141 | ## Legacy Apworld v5.5 - 2025-09-16 | ||
142 | |||
143 | - Fixed a panel in The Ancient that was missing a symbol. | ||
144 | - Fixed an issue where you could be expected to get S1 in The Darkroom without | ||
145 | having U. | ||
146 | - Renamed a few locations. | ||
147 | |||
148 | Download: | ||
149 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v5.5/lingo2.apworld)<br/> | ||
150 | Template YAML: | ||
151 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v5.5/Lingo%202.yaml)<br/> | ||
152 | Source: | ||
153 | [v5.5](https://code.fourisland.com/lingo2-archipelago/tag/?h=apworld-v5.5) | ||
154 | |||
155 | ## Legacy Apworld v4.4 - 2025-09-14 | ||
156 | |||
157 | - Fixed panel set location names. | ||
158 | |||
159 | Download: | ||
160 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v4.4/lingo2.apworld)<br/> | ||
161 | Template YAML: | ||
162 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v4.4/Lingo%202.yaml)<br/> | ||
163 | Source: | ||
164 | [v4.4](https://code.fourisland.com/lingo2-archipelago/tag/?h=apworld-v4.4) | ||
165 | |||
166 | ## Legacy Client v4.4 - 2025-09-13 | ||
167 | |||
168 | - Added support for anti-collectable trap items. | ||
169 | - Fixed entrance to The Jubilant not opening properly when using control center | ||
170 | color shuffle. | ||
171 | - Fixed the location "The Entry (Colored Doors Area) - OPEN" not sending. | ||
172 | - Fixed level 2 letters not activating properly when letter shuffle is set to | ||
173 | Item Cyan. | ||
174 | - Messages are now cleared out when returning to the main menu. | ||
175 | - The player is prevented from accidentally breaking roof access logic when | ||
176 | returning to Daedalus from Icarus. | ||
177 | |||
178 | Download: | ||
179 | [lingo2-archipelago-client-v4.4.zip](https://files.fourisland.com/releases/lingo2-archipelago/client/lingo2-archipelago-client-v4.4.zip)<br/> | ||
180 | Source: | ||
181 | [v4.4](https://code.fourisland.com/lingo2-archipelago/tag/?h=client-v4.4) | ||
182 | |||
183 | ## Legacy Apworld v4.3 - 2025-09-13 | ||
184 | |||
185 | - Added a location for the anti-collectable in The Repetitive. | ||
186 | - Added trap items. These remove letters from your keyboard until you use the | ||
187 | Key Return in The Entry, similar to the anti-collectable in The Repetitive. | ||
188 | This can be controlled using the `trap_percentage` option, which defaults to | ||
189 | zero. | ||
190 | - Fixed crash on load when using Python 3.11. | ||
191 | |||
192 | Download: | ||
193 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v4.3/lingo2.apworld)<br/> | ||
194 | Template YAML: | ||
195 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v4.3/Lingo%202.yaml)<br/> | ||
196 | Source: | ||
197 | [v4.3](https://code.fourisland.com/lingo2-archipelago/tag/?h=apworld-v4.3) | ||
198 | |||
199 | ## Legacy Client v3.3 - 2025-09-12 | ||
200 | |||
201 | - Fixed issue downloading large datapackages (such as TUNIC's). | ||
202 | - Connection failures now show error messages. | ||
203 | |||
204 | Download: | ||
205 | [lingo2-archipelago-client-v3.3.zip](https://files.fourisland.com/releases/lingo2-archipelago/client/lingo2-archipelago-client-v3.3.zip)<br/> | ||
206 | Source: | ||
207 | [v3.3](https://code.fourisland.com/lingo2-archipelago/tag/?h=client-v3.3) | ||
208 | |||
209 | ## Legacy Client v3.2 - 2025-09-12 | ||
210 | |||
211 | - Initial release for testing. Features include door shuffle, letter shuffle, | ||
212 | and symbol shuffle. | ||
213 | |||
214 | Download: | ||
215 | [lingo2-archipelago-client-v3.2.zip](https://files.fourisland.com/releases/lingo2-archipelago/client/lingo2-archipelago-client-v3.2.zip)<br/> | ||
216 | Source: | ||
217 | [v3.2](https://code.fourisland.com/lingo2-archipelago/tag/?h=client-v3.2) | ||
218 | |||
219 | ## Legacy Apworld v3.2 - 2025-09-12 | ||
220 | |||
221 | - Initial release for testing. Features include door shuffle, letter shuffle, | ||
222 | and symbol shuffle. | ||
223 | |||
224 | Download: | ||
225 | [lingo2.apworld](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v3.2/lingo2.apworld)<br/> | ||
226 | Template YAML: | ||
227 | [Lingo 2.yaml](https://files.fourisland.com/releases/lingo2-archipelago/apworld/v3.2/Lingo%202.yaml)<br/> | ||
228 | Source: | ||
229 | [v3.2](https://code.fourisland.com/lingo2-archipelago/tag/?h=apworld-v3.2) | ||
diff --git a/README.md b/README.md new file mode 100644 index 0000000..4a522ac --- /dev/null +++ b/README.md | |||
@@ -0,0 +1,210 @@ | |||
1 | # lingo2-archipelago | ||
2 | |||
3 | [Archipelago](https://archipelago.gg/) is an open-source project that supports | ||
4 | randomizing a number of different games and combining them into one cooperative | ||
5 | experience. Items from each game are hidden in other games. For more information | ||
6 | about Archipelago, you can look at their website. | ||
7 | |||
8 | This is a project that modifies the game | ||
9 | [Lingo 2](https://www.lingothegame.com/lingo2.html) so that it can be played as | ||
10 | part of an Archipelago multiworld game. | ||
11 | |||
12 | ## Installation | ||
13 | |||
14 | 1. Download the Lingo 2 Apworld from | ||
15 | [the releases page](https://code.fourisland.com/lingo2-archipelago/about/CHANGELOG.md). | ||
16 | 2. If you do not already have it, download and install the | ||
17 | [Archipelago software](https://github.com/ArchipelagoMW/Archipelago/releases/). | ||
18 | 3. Double click on `lingo2.apworld` to install it, or copy it manually to the | ||
19 | `custom_worlds` folder of your Archipelago installation. | ||
20 | |||
21 | ## Joining a Multiworld game (Windows) | ||
22 | |||
23 | 1. Open the Archipelago Launcher. | ||
24 | 2. Select "Lingo 2 Client". | ||
25 | 3. The first time you do this, Archipelago will prompt you for the location of | ||
26 | the Lingo 2 executable file ("Lingo2.exe"). You can find this by | ||
27 | right-clicking on Lingo 2 in Steam, going to "Manage", and clicking "Browse | ||
28 | local files". | ||
29 | 4. Lingo 2 will open, and you will see a form asking for your connection | ||
30 | details. Enter the Archipelago address, slot name, and password into the | ||
31 | fields. | ||
32 | 5. Press Connect. | ||
33 | 6. Enjoy! | ||
34 | |||
35 | To continue an earlier game, you can perform the exact same steps as above. | ||
36 | |||
37 | ## Joining a Multiworld game (Non-Windows) | ||
38 | |||
39 | Lingo 2 only officially supports Windows, but has been known to work on Linux | ||
40 | using Proton. Archipelago can be played on a non-Windows system, but the process | ||
41 | is a little more complex. | ||
42 | |||
43 | 1. Download | ||
44 | [archipelago.tscn](https://code.fourisland.com/lingo2-archipelago/plain/client/archipelago.tscn) | ||
45 | and put it in your custom maps folder. You only have to do this once. | ||
46 | 2. Open Lingo 2, and select Archipelago from the level selection list. | ||
47 | 3. Put the path to your `lingo2.apworld` into the field provided. You only have | ||
48 | to do this once, as the game will remember what you put in. | ||
49 | 4. Click Start and wait for the connection settings screen to load. | ||
50 | 5. Open the Archipelago Launcher. | ||
51 | 6. Select "Lingo 2 Client". | ||
52 | 7. You should see "Connected to Lingo 2!" You can then return to Lingo 2 and | ||
53 | fill out your connection details. | ||
54 | 8. Press Connect. | ||
55 | 9. Enjoy! | ||
56 | |||
57 | ## Frequently Asked Questions | ||
58 | |||
59 | ### Why aren't the starting room letters shuffled? | ||
60 | |||
61 | The letter requirements for solving puzzles are very restrictive, especially in | ||
62 | the early game. It is possible for the generator to find some subset of letters | ||
63 | and doors to place in the starting room such that you are not trapped, but this | ||
64 | places a lot of strain on generation and leads to significantly more generation | ||
65 | failures. | ||
66 | |||
67 | As a result, the starting room letters (H1, I1, N1, and T1) are always present | ||
68 | in the starting room, even when remote letter shuffle is enabled. These letters | ||
69 | will _also_ count as clearing a check, so you will send out another item at the | ||
70 | same time as collecting the letter. | ||
71 | |||
72 | ### What areas are randomized? | ||
73 | |||
74 | Almost all maps that you can access from the base game are randomized. The | ||
75 | exceptions are: | ||
76 | |||
77 | - Icarus (this will be randomized at some point, although it will be optional) | ||
78 | - Demo | ||
79 | - The Hinterlands (this will probably be repurposed) | ||
80 | - The beta tester gift maps | ||
81 | |||
82 | ### Is my progress saved locally? | ||
83 | |||
84 | Lingo 2 autosaves your progress every time you solve a puzzle, get a | ||
85 | collectable, or interact with a keyholder. The randomizer generates a savefile | ||
86 | name based on your Multiworld seed and slot number, so you should be able to | ||
87 | seamlessly switch between multiworlds and even slots within a multiworld. | ||
88 | |||
89 | The exception to this is different rooms created from the same multiworld seed. | ||
90 | The client is unable to tell rooms in a seed apart (this is a limitation of the | ||
91 | Archipelago API), so the client will use the same save file for the same slot in | ||
92 | different rooms on the same seed. You can work around this by manually moving or | ||
93 | removing the save folder from the users directory in Lingo 2's game files. | ||
94 | |||
95 | If you play the base game again, you will see one or more save files with a long | ||
96 | name that begins with "zzAP\_". These are the saves for your multiworlds. They | ||
97 | can be safely deleted after you have completed the associated multiworld. It is | ||
98 | not recommended to load these save files outside of the randomizer. | ||
99 | |||
100 | A connection to Archipelago is required to resume playing a multiworld. This is | ||
101 | because the set of items you have received is not stored locally. | ||
102 | |||
103 | ### What about wall snipes? | ||
104 | |||
105 | "Wall sniping" refers to the fact that you are able to solve puzzles on the | ||
106 | other side of opaque walls. The player is never expected to or required to do | ||
107 | this in normal gameplay. This randomizer does not change how wall snipes work, | ||
108 | but it will likewise never require the use of them. | ||
109 | |||
110 | ### How do cyan doors work? | ||
111 | |||
112 | In the base game, there are a number of cyan-colored doors that ordinarily open | ||
113 | once you collect H2 in The Repetitive. There are also a handful of panels that | ||
114 | only appear upon getting H2 as well, which the apworld treats the same as the | ||
115 | cyan doors. | ||
116 | |||
117 | There is an option that lets you choose how these doors and panels behave. By | ||
118 | default, they act the same as in the base game: they only open or appear after | ||
119 | collecting H2. Note that this means the actual H2 collectable in The Repetitive. | ||
120 | Receiving H2 via remote letter shuffle does not count for this requirement. | ||
121 | However, you can also make cyan doors activate upon collecting or receiving your | ||
122 | first double letter, regardless of what it is or if it's remote. Finally, you | ||
123 | can lock cyan doors behind an item called "Cyan Doors". | ||
124 | |||
125 | It is important to note, however, that the Cyan Door Behavior option only | ||
126 | applies to cyan doors that are not already affected by another type of | ||
127 | shuffling. When door shuffle is on, the following cyan doors are activated by | ||
128 | individual items and are not impacted by your choice of Cyan Door Behavior: | ||
129 | |||
130 | - The entrance to The Tower from The Great (The Great - Tower Entrance) | ||
131 | - The entrance to The Butterfly from The Bearer (The Bearer - Butterfly | ||
132 | Entrance) | ||
133 | - The entrance to The Repetitive from The Entry (The Entry - Repetitive | ||
134 | Entrance) | ||
135 | - The eye painting near the yellow color hallway in Daedalus (Daedalus - Eye | ||
136 | Painting) | ||
137 | - The Red I room in The Repetitive (The Repetitive - Anti Collectable Room) | ||
138 | |||
139 | Additionally, when control center color shuffle is enabled, the orange door in | ||
140 | The Unkempt (which ordinarily doubles as a cyan door) opens upon receiving the | ||
141 | Control Center Orange Doors item, instead of following the Cyan Door Behavior | ||
142 | option. | ||
143 | |||
144 | ### Help! I lost C/G in The Congruent! | ||
145 | |||
146 | If you place C or G into the relevant keyholders in The Congruent, the keyholder | ||
147 | disappears. You can retrieve your letter immediately by pressing C or G again | ||
148 | before leaving solve mode, as the keyholder will still be considered to be | ||
149 | "focused", even though it has moved. If you have already moved, though, there is | ||
150 | another way to get your letters back: just use the Key Return in The Entry. | ||
151 | |||
152 | ### Why is the tracker telling me to solve a panel that's currently red? | ||
153 | |||
154 | Red usually indicates that a panel cannot be solved because of missing letters. | ||
155 | However, that only applies to the puzzle's main answer. If a puzzle has | ||
156 | alternate answers, you may be expected to use one of those instead of the main | ||
157 | one. As long as you have all of the necessary letters, an alternate answer can | ||
158 | be typed into a red panel even though it does not show you typing. When you | ||
159 | finish typing the answer, the panel will solve as normal. | ||
160 | |||
161 | ## Running from source | ||
162 | |||
163 | The randomizer is mostly written in Python and GDScript, which do not need to be | ||
164 | compiled. However, there are three files that need to be generated before the | ||
165 | apworld can be used. | ||
166 | |||
167 | The first file is `data.binpb`, the datafile containing the randomizer logic. | ||
168 | You can read about how to generate it on | ||
169 | [its own README page](https://code.fourisland.com/lingo2-archipelago/about/data/README.md). | ||
170 | Once you have it, put it in a subfolder of `apworld` called `generated`. | ||
171 | |||
172 | The second generated file is `data_pb2.py`. This file allows Archipelago to read | ||
173 | the datafile. We use `protoc`, the Protocol Buffer compiler, to generate it. As | ||
174 | of 0.6.3, Archipelago has protobuf 3.20.3 packaged with it, which means we need | ||
175 | to compile our proto file with a similar version. | ||
176 | |||
177 | If you followed the steps to generate `data.binpb` and compiled the `datapacker` | ||
178 | tool yourself, you will already have protobuf version 3.21.12 installed through | ||
179 | vcpkg. You can then run a command similar to this in order to generate the | ||
180 | python file. | ||
181 | |||
182 | ```shell | ||
183 | .\out\build\x64-Debug\vcpkg_installed\x64-windows\tools\protobuf\protoc.exe -Iproto\ ^ | ||
184 | --python_out=apworld\generated\ .\proto\data.proto | ||
185 | ``` | ||
186 | |||
187 | The exact path to `protoc.exe` is going to depend on where vcpkg installed its | ||
188 | packages. The above location is where Visual Studio will probably put it. | ||
189 | |||
190 | The third generated file is `proto.gd`. This is the GDScript version of the | ||
191 | previous file. We use a Godot script to generate it, which means | ||
192 | [the Godot Editor](https://godotengine.org/download/) is required. From the root | ||
193 | of the repository: | ||
194 | |||
195 | ```shell | ||
196 | cd vendor\godobuf | ||
197 | godot --headless -s addons\protobuf\protobuf_cmdln.gd --input=..\..\proto\data.proto ^ | ||
198 | --output=..\..\apworld\generated\proto.gd | ||
199 | ``` | ||
200 | |||
201 | If you are not on Windows, replace the forward slashes with backslashes as | ||
202 | appropriate (and the caret with a forward slash). You will also probably need to | ||
203 | replace "godot" at the start of the second line with a path to a Godot Editor | ||
204 | executable. | ||
205 | |||
206 | After generating those three files, the apworld should be functional. You can | ||
207 | copy it into an Archipelago source tree (rename the folder `apworld` to `lingo2` | ||
208 | if you do so) if you want to edit/debug the code. Otherwise, you can zip up the | ||
209 | folder and rename it to `lingo2.apworld` in order to package it for | ||
210 | distribution. | ||
diff --git a/apworld/__init__.py b/apworld/__init__.py index 14bb4bc..e126fc0 100644 --- a/apworld/__init__.py +++ b/apworld/__init__.py | |||
@@ -1,18 +1,40 @@ | |||
1 | """ | 1 | """ |
2 | Archipelago init file for Lingo 2 | 2 | Archipelago init file for Lingo 2 |
3 | """ | 3 | """ |
4 | from BaseClasses import ItemClassification, Item | 4 | from typing import ClassVar |
5 | |||
6 | from BaseClasses import ItemClassification, Item, Tutorial | ||
7 | from Options import OptionError | ||
8 | from settings import Group, UserFilePath | ||
5 | from worlds.AutoWorld import WebWorld, World | 9 | from worlds.AutoWorld import WebWorld, World |
6 | from .items import Lingo2Item | 10 | from .items import Lingo2Item, ANTI_COLLECTABLE_TRAPS |
7 | from .options import Lingo2Options | 11 | from .options import Lingo2Options |
8 | from .player_logic import Lingo2PlayerLogic | 12 | from .player_logic import Lingo2PlayerLogic |
9 | from .regions import create_regions | 13 | from .regions import create_regions, shuffle_entrances, connect_ports_from_ut |
10 | from .static_logic import Lingo2StaticLogic | 14 | from .static_logic import Lingo2StaticLogic |
15 | from worlds.LauncherComponents import Component, Type, components, launch as launch_component, icon_paths | ||
11 | 16 | ||
12 | 17 | ||
13 | class Lingo2WebWorld(WebWorld): | 18 | class Lingo2WebWorld(WebWorld): |
14 | rich_text_options_doc = True | 19 | rich_text_options_doc = True |
15 | theme = "grass" | 20 | theme = "grass" |
21 | tutorials = [Tutorial( | ||
22 | "Multiworld Setup Guide", | ||
23 | "A guide to playing Lingo 2 with Archipelago.", | ||
24 | "English", | ||
25 | "en_Lingo_2.md", | ||
26 | "setup/en", | ||
27 | ["hatkirby"] | ||
28 | )] | ||
29 | |||
30 | |||
31 | class Lingo2Settings(Group): | ||
32 | class ExecutableFile(UserFilePath): | ||
33 | """Path to the Lingo 2 executable""" | ||
34 | is_exe = True | ||
35 | |||
36 | exe_file: ExecutableFile = ExecutableFile() | ||
37 | start_game: bool = True | ||
16 | 38 | ||
17 | 39 | ||
18 | class Lingo2World(World): | 40 | class Lingo2World(World): |
@@ -24,6 +46,9 @@ class Lingo2World(World): | |||
24 | game = "Lingo 2" | 46 | game = "Lingo 2" |
25 | web = Lingo2WebWorld() | 47 | web = Lingo2WebWorld() |
26 | 48 | ||
49 | settings: ClassVar[Lingo2Settings] | ||
50 | settings_key = "lingo2_options" | ||
51 | |||
27 | topology_present = True | 52 | topology_present = True |
28 | 53 | ||
29 | options_dataclass = Lingo2Options | 54 | options_dataclass = Lingo2Options |
@@ -32,18 +57,35 @@ class Lingo2World(World): | |||
32 | static_logic = Lingo2StaticLogic() | 57 | static_logic = Lingo2StaticLogic() |
33 | item_name_to_id = static_logic.item_name_to_id | 58 | item_name_to_id = static_logic.item_name_to_id |
34 | location_name_to_id = static_logic.location_name_to_id | 59 | location_name_to_id = static_logic.location_name_to_id |
60 | item_name_groups = static_logic.item_name_groups | ||
61 | location_name_groups = static_logic.location_name_groups | ||
62 | |||
63 | for_tracker: ClassVar[bool] = False | ||
35 | 64 | ||
36 | player_logic: Lingo2PlayerLogic | 65 | player_logic: Lingo2PlayerLogic |
37 | 66 | ||
67 | port_pairings: dict[int, int] | ||
68 | |||
38 | def generate_early(self): | 69 | def generate_early(self): |
39 | self.player_logic = Lingo2PlayerLogic(self) | 70 | self.player_logic = Lingo2PlayerLogic(self) |
71 | self.port_pairings = {} | ||
40 | 72 | ||
41 | def create_regions(self): | 73 | def create_regions(self): |
42 | create_regions(self) | 74 | create_regions(self) |
43 | 75 | ||
44 | from Utils import visualize_regions | 76 | def connect_entrances(self): |
77 | if self.options.shuffle_worldports: | ||
78 | if hasattr(self.multiworld, "re_gen_passthrough") and "Lingo 2" in self.multiworld.re_gen_passthrough: | ||
79 | slot_value = self.multiworld.re_gen_passthrough["Lingo 2"]["port_pairings"] | ||
80 | self.port_pairings = {int(fp): int(tp) for fp, tp in slot_value.items()} | ||
81 | |||
82 | connect_ports_from_ut(self.port_pairings, self) | ||
83 | else: | ||
84 | shuffle_entrances(self) | ||
45 | 85 | ||
46 | visualize_regions(self.multiworld.get_region("Menu", self.player), "my_world.puml") | 86 | #from Utils import visualize_regions |
87 | |||
88 | #visualize_regions(self.multiworld.get_region("Menu", self.player), "my_world.puml") | ||
47 | 89 | ||
48 | def create_items(self): | 90 | def create_items(self): |
49 | 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] |
@@ -51,14 +93,83 @@ class Lingo2World(World): | |||
51 | total_locations = sum(len(locs) for locs in self.player_logic.locations_by_room.values()) | 93 | total_locations = sum(len(locs) for locs in self.player_logic.locations_by_room.values()) |
52 | 94 | ||
53 | item_difference = total_locations - len(pool) | 95 | item_difference = total_locations - len(pool) |
96 | |||
97 | if self.options.trap_percentage > 0: | ||
98 | num_traps = int(item_difference * self.options.trap_percentage / 100) | ||
99 | item_difference = item_difference - num_traps | ||
100 | |||
101 | trap_names = [] | ||
102 | trap_weights = [] | ||
103 | for letter_name, weight in self.static_logic.letter_weights.items(): | ||
104 | trap_names.append(f"Anti {letter_name}") | ||
105 | trap_weights.append(weight) | ||
106 | |||
107 | bad_letters = self.random.choices(trap_names, weights=trap_weights, k=num_traps) | ||
108 | pool += [self.create_item(trap_name) for trap_name in bad_letters] | ||
109 | |||
54 | for i in range(0, item_difference): | 110 | for i in range(0, item_difference): |
55 | pool.append(self.create_item("Nothing")) | 111 | pool.append(self.create_item(self.get_filler_item_name())) |
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.") | ||
56 | 117 | ||
57 | self.multiworld.itempool += pool | 118 | self.multiworld.itempool += pool |
58 | 119 | ||
59 | def create_item(self, name: str) -> Item: | 120 | def create_item(self, name: str) -> Item: |
60 | return Lingo2Item(name, ItemClassification.filler if name == "Nothing" else ItemClassification.progression, | 121 | return Lingo2Item(name, ItemClassification.filler if name == self.get_filler_item_name() else |
122 | ItemClassification.trap if name in ANTI_COLLECTABLE_TRAPS else | ||
123 | ItemClassification.progression, | ||
61 | self.item_name_to_id.get(name), self.player) | 124 | self.item_name_to_id.get(name), self.player) |
62 | 125 | ||
63 | def set_rules(self): | 126 | def set_rules(self): |
64 | self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) | 127 | self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player) |
128 | |||
129 | def fill_slot_data(self): | ||
130 | slot_options = [ | ||
131 | "cyan_door_behavior", | ||
132 | "daedalus_roof_access", | ||
133 | "keyholder_sanity", | ||
134 | "shuffle_control_center_colors", | ||
135 | "shuffle_doors", | ||
136 | "shuffle_gallery_paintings", | ||
137 | "shuffle_letters", | ||
138 | "shuffle_symbols", | ||
139 | "shuffle_worldports", | ||
140 | "strict_cyan_ending", | ||
141 | "strict_purple_ending", | ||
142 | "victory_condition", | ||
143 | ] | ||
144 | |||
145 | slot_data: dict[str, object] = { | ||
146 | **self.options.as_dict(*slot_options), | ||
147 | "version": self.static_logic.get_data_version(), | ||
148 | } | ||
149 | |||
150 | if self.options.shuffle_worldports: | ||
151 | slot_data["port_pairings"] = self.port_pairings | ||
152 | |||
153 | return slot_data | ||
154 | |||
155 | def get_filler_item_name(self) -> str: | ||
156 | return "A Job Well Done" | ||
157 | |||
158 | # for the universal tracker, doesn't get called in standard gen | ||
159 | # docs: https://github.com/FarisTheAncient/Archipelago/blob/tracker/worlds/tracker/docs/re-gen-passthrough.md | ||
160 | @staticmethod | ||
161 | def interpret_slot_data(slot_data: dict[str, object]) -> dict[str, object]: | ||
162 | # returning slot_data so it regens, giving it back in multiworld.re_gen_passthrough | ||
163 | # we are using re_gen_passthrough over modifying the world here due to complexities with ER | ||
164 | return slot_data | ||
165 | |||
166 | |||
167 | def launch_client(*args): | ||
168 | from .context import client_main | ||
169 | launch_component(client_main, name="Lingo2Client", args=args) | ||
170 | |||
171 | |||
172 | icon_paths["lingo2_ico"] = f"ap:{__name__}/logo.png" | ||
173 | component = Component("Lingo 2 Client", component_type=Type.CLIENT, func=launch_client, | ||
174 | description="Open Lingo 2.", supports_uri=True, game_name="Lingo 2", icon="lingo2_ico") | ||
175 | components.append(component) | ||
diff --git a/apworld/client/animationListener.gd b/apworld/client/animationListener.gd new file mode 100644 index 0000000..c3b26db --- /dev/null +++ b/apworld/client/animationListener.gd | |||
@@ -0,0 +1,38 @@ | |||
1 | extends "res://scripts/nodes/listeners/animationListener.gd" | ||
2 | |||
3 | var item_id | ||
4 | var item_amount | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var node_path = String( | ||
9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
10 | ) | ||
11 | |||
12 | var gamedata = global.get_node("Gamedata") | ||
13 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | ||
14 | if door_id != null: | ||
15 | var ap = global.get_node("Archipelago") | ||
16 | var item_lock = ap.get_item_id_for_door(door_id) | ||
17 | |||
18 | if item_lock != null: | ||
19 | item_id = item_lock[0] | ||
20 | item_amount = item_lock[1] | ||
21 | |||
22 | self.senders = [] | ||
23 | self.senderGroup = [] | ||
24 | self.nested = false | ||
25 | self.complete_at = 0 | ||
26 | self.max_length = 0 | ||
27 | self.excludeSenders = [] | ||
28 | |||
29 | call_deferred("_readier") | ||
30 | |||
31 | super._ready() | ||
32 | |||
33 | |||
34 | func _readier(): | ||
35 | var ap = global.get_node("Archipelago") | ||
36 | |||
37 | if ap.client.getItemAmount(item_id) >= item_amount: | ||
38 | handleTriggered() | ||
diff --git a/apworld/client/apworld_runtime.gd b/apworld/client/apworld_runtime.gd new file mode 100644 index 0000000..faf8e0c --- /dev/null +++ b/apworld/client/apworld_runtime.gd | |||
@@ -0,0 +1,44 @@ | |||
1 | extends Node | ||
2 | |||
3 | var apworld_reader | ||
4 | |||
5 | |||
6 | func _init(path): | ||
7 | apworld_reader = ZIPReader.new() | ||
8 | apworld_reader.open(path) | ||
9 | |||
10 | |||
11 | func _get_true_path(path): | ||
12 | if path.begins_with("../"): | ||
13 | return "lingo2/%s" % path.substr(3) | ||
14 | else: | ||
15 | return "lingo2/client/%s" % path | ||
16 | |||
17 | |||
18 | func load_script(path): | ||
19 | var true_path = _get_true_path(path) | ||
20 | |||
21 | var script = GDScript.new() | ||
22 | script.source_code = apworld_reader.read_file(true_path).get_string_from_utf8() | ||
23 | script.reload() | ||
24 | |||
25 | return script | ||
26 | |||
27 | |||
28 | func read_path(path): | ||
29 | var true_path = _get_true_path(path) | ||
30 | return apworld_reader.read_file(true_path) | ||
31 | |||
32 | |||
33 | func load_script_as_scene(path, scene_name): | ||
34 | var script = load_script(path) | ||
35 | var instance = script.new() | ||
36 | instance.name = scene_name | ||
37 | |||
38 | get_tree().unload_current_scene() | ||
39 | _load_scene.call_deferred(instance) | ||
40 | |||
41 | |||
42 | func _load_scene(instance): | ||
43 | get_tree().get_root().add_child(instance) | ||
44 | get_tree().current_scene = instance | ||
diff --git a/apworld/client/assets/goal.png b/apworld/client/assets/goal.png new file mode 100644 index 0000000..bd1650d --- /dev/null +++ b/apworld/client/assets/goal.png | |||
Binary files differ | |||
diff --git a/apworld/client/assets/location.png b/apworld/client/assets/location.png new file mode 100644 index 0000000..5304deb --- /dev/null +++ b/apworld/client/assets/location.png | |||
Binary files differ | |||
diff --git a/apworld/client/assets/worldport.png b/apworld/client/assets/worldport.png new file mode 100644 index 0000000..19dfdc3 --- /dev/null +++ b/apworld/client/assets/worldport.png | |||
Binary files differ | |||
diff --git a/apworld/client/client.gd b/apworld/client/client.gd new file mode 100644 index 0000000..9a4b402 --- /dev/null +++ b/apworld/client/client.gd | |||
@@ -0,0 +1,275 @@ | |||
1 | extends Node | ||
2 | |||
3 | const ap_version = {"major": 0, "minor": 6, "build": 3, "class": "Version"} | ||
4 | |||
5 | var SCRIPT_websocketserver | ||
6 | |||
7 | var _server | ||
8 | var _should_process = false | ||
9 | |||
10 | var _remote_version = {"major": 0, "minor": 0, "build": 0} | ||
11 | var _gen_version = {"major": 0, "minor": 0, "build": 0} | ||
12 | |||
13 | var ap_server = "" | ||
14 | var ap_user = "" | ||
15 | var ap_pass = "" | ||
16 | |||
17 | var _seed = "" | ||
18 | var _team = 0 | ||
19 | var _slot = 0 | ||
20 | var _checked_locations = [] | ||
21 | var _checked_worldports = [] | ||
22 | var _received_indexes = [] | ||
23 | var _received_items = {} | ||
24 | var _slot_data = {} | ||
25 | var _accessible_locations = [] | ||
26 | var _accessible_worldports = [] | ||
27 | var _goal_accessible = false | ||
28 | |||
29 | signal could_not_connect | ||
30 | signal connect_status | ||
31 | signal client_connected(slot_data) | ||
32 | signal item_received(item, amount) | ||
33 | signal location_scout_received(location_id, item_name, player_name, flags, for_self) | ||
34 | signal text_message_received(message) | ||
35 | signal item_sent_notification(message) | ||
36 | signal hint_received(message) | ||
37 | signal accessible_locations_updated | ||
38 | signal checked_locations_updated | ||
39 | signal checked_worldports_updated | ||
40 | signal keyboard_update_received | ||
41 | |||
42 | |||
43 | func _init(): | ||
44 | set_process_mode(Node.PROCESS_MODE_ALWAYS) | ||
45 | |||
46 | global._print("Instantiated APClient") | ||
47 | |||
48 | |||
49 | func _ready(): | ||
50 | _server = SCRIPT_websocketserver.new() | ||
51 | _server.client_connected.connect(_on_web_socket_server_client_connected) | ||
52 | _server.client_disconnected.connect(_on_web_socket_server_client_disconnected) | ||
53 | _server.message_received.connect(_on_web_socket_server_message_received) | ||
54 | add_child(_server) | ||
55 | _server.listen(43182) | ||
56 | |||
57 | |||
58 | func _reset_state(): | ||
59 | _should_process = false | ||
60 | _received_items = {} | ||
61 | _received_indexes = [] | ||
62 | _checked_worldports = [] | ||
63 | _accessible_locations = [] | ||
64 | _accessible_worldports = [] | ||
65 | _goal_accessible = false | ||
66 | |||
67 | |||
68 | func disconnect_from_ap(): | ||
69 | sendMessage([{"cmd": "Disconnect"}]) | ||
70 | |||
71 | |||
72 | func _on_web_socket_server_client_connected(peer_id: int) -> void: | ||
73 | var peer: WebSocketPeer = _server.peers[peer_id] | ||
74 | print("Remote client connected: %d. Protocol: %s" % [peer_id, peer.get_selected_protocol()]) | ||
75 | _server.send(-peer_id, "[%d] connected" % peer_id) | ||
76 | |||
77 | |||
78 | func _on_web_socket_server_client_disconnected(peer_id: int) -> void: | ||
79 | var peer: WebSocketPeer = _server.peers[peer_id] | ||
80 | print( | ||
81 | ( | ||
82 | "Remote client disconnected: %d. Code: %d, Reason: %s" | ||
83 | % [peer_id, peer.get_close_code(), peer.get_close_reason()] | ||
84 | ) | ||
85 | ) | ||
86 | _server.send(-peer_id, "[%d] disconnected" % peer_id) | ||
87 | |||
88 | |||
89 | func _on_web_socket_server_message_received(_peer_id: int, packet: String) -> void: | ||
90 | global._print("Got data from server: " + packet) | ||
91 | var json = JSON.new() | ||
92 | var jserror = json.parse(packet) | ||
93 | if jserror != OK: | ||
94 | global._print("Error parsing packet from AP: " + jserror.error_string) | ||
95 | return | ||
96 | |||
97 | for message in json.data: | ||
98 | var cmd = message["cmd"] | ||
99 | global._print("Received command: " + cmd) | ||
100 | |||
101 | if cmd == "Connected": | ||
102 | _seed = message["seed_name"] | ||
103 | _remote_version = message["version"] | ||
104 | _gen_version = message["generator_version"] | ||
105 | _team = message["team"] | ||
106 | _slot = message["slot"] | ||
107 | _slot_data = message["slot_data"] | ||
108 | |||
109 | _checked_locations = [] | ||
110 | for location in message["checked_locations"]: | ||
111 | _checked_locations.append(int(location)) | ||
112 | |||
113 | client_connected.emit(_slot_data) | ||
114 | |||
115 | elif cmd == "ConnectionRefused": | ||
116 | could_not_connect.emit(message["text"]) | ||
117 | global._print("Connection to AP refused") | ||
118 | |||
119 | elif cmd == "UpdateLocations": | ||
120 | for location in message["locations"]: | ||
121 | var lint = int(location) | ||
122 | if not _checked_locations.has(lint): | ||
123 | _checked_locations.append(lint) | ||
124 | |||
125 | checked_locations_updated.emit() | ||
126 | |||
127 | elif cmd == "UpdateWorldports": | ||
128 | for port_id in message["worldports"]: | ||
129 | var lint = int(port_id) | ||
130 | if not _checked_worldports.has(lint): | ||
131 | _checked_worldports.append(lint) | ||
132 | |||
133 | checked_worldports_updated.emit() | ||
134 | |||
135 | elif cmd == "ItemReceived": | ||
136 | for item in message["items"]: | ||
137 | var index = int(item["index"]) | ||
138 | if _received_indexes.has(index): | ||
139 | # Do not re-process items. | ||
140 | continue | ||
141 | |||
142 | _received_indexes.append(index) | ||
143 | |||
144 | var item_id = int(item["id"]) | ||
145 | _received_items[item_id] = _received_items.get(item_id, 0) + 1 | ||
146 | |||
147 | item_received.emit(item, _received_items[item_id]) | ||
148 | |||
149 | elif cmd == "TextMessage": | ||
150 | text_message_received.emit(message["data"]) | ||
151 | |||
152 | elif cmd == "ItemSentNotif": | ||
153 | item_sent_notification.emit(message) | ||
154 | |||
155 | elif cmd == "HintReceived": | ||
156 | hint_received.emit(message) | ||
157 | |||
158 | elif cmd == "LocationInfo": | ||
159 | for loc in message["locations"]: | ||
160 | location_scout_received.emit( | ||
161 | int(loc["id"]), loc["item"], loc["player"], int(loc["flags"]), int(loc["self"]) | ||
162 | ) | ||
163 | |||
164 | elif cmd == "AccessibleLocations": | ||
165 | _accessible_locations.clear() | ||
166 | _accessible_worldports.clear() | ||
167 | |||
168 | for loc in message["locations"]: | ||
169 | _accessible_locations.append(int(loc)) | ||
170 | |||
171 | if "worldports" in message: | ||
172 | for port_id in message["worldports"]: | ||
173 | _accessible_worldports.append(int(port_id)) | ||
174 | |||
175 | _goal_accessible = bool(message.get("goal", false)) | ||
176 | |||
177 | accessible_locations_updated.emit() | ||
178 | |||
179 | elif cmd == "UpdateKeyboard": | ||
180 | var updates = {} | ||
181 | for k in message["updates"]: | ||
182 | updates[k] = int(message["updates"][k]) | ||
183 | |||
184 | keyboard_update_received.emit(updates) | ||
185 | |||
186 | elif cmd == "PathReply": | ||
187 | var textclient = global.get_node("Textclient") | ||
188 | textclient.display_logical_path( | ||
189 | message["type"], int(message.get("id", null)), message["path"] | ||
190 | ) | ||
191 | |||
192 | |||
193 | func connectToServer(server, un, pw): | ||
194 | sendMessage([{"cmd": "Connect", "server": server, "player": un, "password": pw}]) | ||
195 | |||
196 | ap_server = server | ||
197 | ap_user = un | ||
198 | ap_pass = pw | ||
199 | |||
200 | _should_process = true | ||
201 | |||
202 | connect_status.emit("Connecting...") | ||
203 | |||
204 | |||
205 | func sendMessage(msg): | ||
206 | var payload = JSON.stringify(msg) | ||
207 | _server.send(0, payload) | ||
208 | |||
209 | |||
210 | func connectToRoom(): | ||
211 | connect_status.emit("Authenticating...") | ||
212 | |||
213 | sendMessage( | ||
214 | [ | ||
215 | { | ||
216 | "cmd": "Connect", | ||
217 | "password": ap_pass, | ||
218 | "game": "Lingo 2", | ||
219 | "name": ap_user, | ||
220 | } | ||
221 | ] | ||
222 | ) | ||
223 | |||
224 | |||
225 | func requestSync(): | ||
226 | sendMessage([{"cmd": "Sync"}]) | ||
227 | |||
228 | |||
229 | func sendLocation(loc_id): | ||
230 | sendMessage([{"cmd": "LocationChecks", "locations": [loc_id]}]) | ||
231 | |||
232 | |||
233 | func sendLocations(loc_ids): | ||
234 | sendMessage([{"cmd": "LocationChecks", "locations": loc_ids}]) | ||
235 | |||
236 | |||
237 | func say(textdata): | ||
238 | sendMessage([{"cmd": "Say", "text": textdata}]) | ||
239 | |||
240 | |||
241 | func completedGoal(): | ||
242 | sendMessage([{"cmd": "StatusUpdate", "status": 30}]) # CLIENT_GOAL | ||
243 | |||
244 | |||
245 | func scoutLocations(loc_ids): | ||
246 | sendMessage([{"cmd": "LocationScouts", "locations": loc_ids}]) | ||
247 | |||
248 | |||
249 | func updateKeyboard(updates): | ||
250 | sendMessage([{"cmd": "UpdateKeyboard", "keyboard": updates}]) | ||
251 | |||
252 | |||
253 | func checkWorldport(port_id): | ||
254 | if not _checked_worldports.has(port_id): | ||
255 | sendMessage([{"cmd": "CheckWorldport", "port_id": port_id}]) | ||
256 | |||
257 | |||
258 | func getLogicalPath(object_type, object_id): | ||
259 | var msg = {"cmd": "GetPath", "type": object_type} | ||
260 | if object_id != null: | ||
261 | msg["id"] = object_id | ||
262 | |||
263 | sendMessage([msg]) | ||
264 | |||
265 | |||
266 | func sendQuit(): | ||
267 | sendMessage([{"cmd": "Quit"}]) | ||
268 | |||
269 | |||
270 | func hasItem(item_id): | ||
271 | return _received_items.has(item_id) | ||
272 | |||
273 | |||
274 | func getItemAmount(item_id): | ||
275 | return _received_items.get(item_id, 0) | ||
diff --git a/apworld/client/collectable.gd b/apworld/client/collectable.gd new file mode 100644 index 0000000..4a17a2a --- /dev/null +++ b/apworld/client/collectable.gd | |||
@@ -0,0 +1,16 @@ | |||
1 | extends "res://scripts/nodes/collectable.gd" | ||
2 | |||
3 | |||
4 | func pickedUp(): | ||
5 | if unlock_type == "key": | ||
6 | var ap = global.get_node("Archipelago") | ||
7 | if ap.get_letter_behavior(unlock_key, level == 2) == ap.kLETTER_BEHAVIOR_VANILLA: | ||
8 | ap.keyboard.collect_local_letter(unlock_key, level) | ||
9 | else: | ||
10 | ap.keyboard.update_unlocks() | ||
11 | |||
12 | super.pickedUp() | ||
13 | |||
14 | |||
15 | func setScoutedText(text): | ||
16 | get_node("MeshInstance3D").mesh.text = text.replace(" ", "\n") | ||
diff --git a/apworld/client/compass.gd b/apworld/client/compass.gd new file mode 100644 index 0000000..c90475a --- /dev/null +++ b/apworld/client/compass.gd | |||
@@ -0,0 +1,66 @@ | |||
1 | extends Node2D | ||
2 | |||
3 | const RADIUS = 48 | ||
4 | |||
5 | var _font | ||
6 | |||
7 | |||
8 | func _ready(): | ||
9 | _font = load("res://assets/fonts/Lingo2.ttf") | ||
10 | |||
11 | |||
12 | func _draw(): | ||
13 | draw_circle(Vector2.ZERO, RADIUS, Color(1.0, 1.0, 1.0, 0.8), true) | ||
14 | draw_circle(Vector2.ZERO, RADIUS, Color.BLACK, false) | ||
15 | draw_string( | ||
16 | _font, | ||
17 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
18 | "N", | ||
19 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
20 | -1, | ||
21 | 16, | ||
22 | Color.BLACK | ||
23 | ) | ||
24 | draw_set_transform(Vector2.ZERO, PI / 2) | ||
25 | draw_string( | ||
26 | _font, | ||
27 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
28 | "E", | ||
29 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
30 | -1, | ||
31 | 16, | ||
32 | Color.BLACK | ||
33 | ) | ||
34 | draw_set_transform(Vector2.ZERO, PI) | ||
35 | draw_string( | ||
36 | _font, | ||
37 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
38 | "S", | ||
39 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
40 | -1, | ||
41 | 16, | ||
42 | Color.BLACK | ||
43 | ) | ||
44 | draw_set_transform(Vector2.ZERO, PI * 3.0 / 2.0) | ||
45 | draw_string( | ||
46 | _font, | ||
47 | Vector2(-4, -RADIUS * 3.0 / 4.0), | ||
48 | "W", | ||
49 | HorizontalAlignment.HORIZONTAL_ALIGNMENT_LEFT, | ||
50 | -1, | ||
51 | 16, | ||
52 | Color.BLACK | ||
53 | ) | ||
54 | draw_set_transform(Vector2.ZERO) | ||
55 | draw_colored_polygon( | ||
56 | PackedVector2Array( | ||
57 | [Vector2(0, -RADIUS * 5.0 / 8.0), Vector2(-RADIUS / 6.0, 0), Vector2(RADIUS / 6.0, 0)] | ||
58 | ), | ||
59 | Color.RED | ||
60 | ) | ||
61 | draw_colored_polygon( | ||
62 | PackedVector2Array( | ||
63 | [Vector2(0, RADIUS * 5.0 / 8.0), Vector2(-RADIUS / 6.0, 0), Vector2(RADIUS / 6.0, 0)] | ||
64 | ), | ||
65 | Color.GRAY | ||
66 | ) | ||
diff --git a/apworld/client/compass_overlay.gd b/apworld/client/compass_overlay.gd new file mode 100644 index 0000000..56e81ff --- /dev/null +++ b/apworld/client/compass_overlay.gd | |||
@@ -0,0 +1,17 @@ | |||
1 | extends CanvasLayer | ||
2 | |||
3 | var SCRIPT_compass | ||
4 | |||
5 | var compass | ||
6 | |||
7 | |||
8 | func _ready(): | ||
9 | compass = SCRIPT_compass.new() | ||
10 | compass.position = Vector2(1840, 80) | ||
11 | add_child(compass) | ||
12 | |||
13 | visible = false | ||
14 | |||
15 | |||
16 | func update_rotation(ry): | ||
17 | compass.rotation = ry | ||
diff --git a/apworld/client/door.gd b/apworld/client/door.gd new file mode 100644 index 0000000..49f5728 --- /dev/null +++ b/apworld/client/door.gd | |||
@@ -0,0 +1,46 @@ | |||
1 | extends "res://scripts/nodes/door.gd" | ||
2 | |||
3 | var item_id | ||
4 | var item_amount | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var node_path = String( | ||
9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
10 | ) | ||
11 | |||
12 | var gamedata = global.get_node("Gamedata") | ||
13 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | ||
14 | if door_id != null: | ||
15 | var ap = global.get_node("Archipelago") | ||
16 | var item_lock = ap.get_item_id_for_door(door_id) | ||
17 | |||
18 | if item_lock != null: | ||
19 | item_id = item_lock[0] | ||
20 | item_amount = item_lock[1] | ||
21 | |||
22 | self.senders = [] | ||
23 | self.senderGroup = [] | ||
24 | self.nested = false | ||
25 | self.complete_at = 0 | ||
26 | self.max_length = 0 | ||
27 | self.excludeSenders = [] | ||
28 | |||
29 | call_deferred("_readier") | ||
30 | |||
31 | if global.map == "the_sun_temple": | ||
32 | if name == "spe_EndPlatform" or name == "spe_entry_2": | ||
33 | senders = [NodePath("/root/scene/Panels/EndCheck_dog")] | ||
34 | |||
35 | if global.map == "the_parthenon": | ||
36 | if name == "spe_entry_1": | ||
37 | senders = [NodePath("/root/scene/Panels/EndCheck_dog")] | ||
38 | |||
39 | super._ready() | ||
40 | |||
41 | |||
42 | func _readier(): | ||
43 | var ap = global.get_node("Archipelago") | ||
44 | |||
45 | if ap.client.getItemAmount(item_id) >= item_amount: | ||
46 | handleTriggered() | ||
diff --git a/apworld/client/effects.gd b/apworld/client/effects.gd new file mode 100644 index 0000000..9dc1dd8 --- /dev/null +++ b/apworld/client/effects.gd | |||
@@ -0,0 +1,32 @@ | |||
1 | extends CanvasLayer | ||
2 | |||
3 | var _label | ||
4 | |||
5 | var _disconnected = false | ||
6 | |||
7 | |||
8 | func _ready(): | ||
9 | _label = Label.new() | ||
10 | _label.name = "Label" | ||
11 | _label.offset_left = 20 | ||
12 | _label.offset_top = 20 | ||
13 | _label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT | ||
14 | _label.vertical_alignment = VERTICAL_ALIGNMENT_TOP | ||
15 | _label.theme = preload("res://assets/themes/baseUI.tres") | ||
16 | _label.add_theme_font_size_override("font_size", 36) | ||
17 | add_child(_label) | ||
18 | |||
19 | |||
20 | func set_connection_lost(arg): | ||
21 | _disconnected = arg | ||
22 | |||
23 | _update_label() | ||
24 | |||
25 | |||
26 | func _update_label(): | ||
27 | var text = [] | ||
28 | |||
29 | if _disconnected: | ||
30 | text.append("Disconnected from multiworld.") | ||
31 | |||
32 | _label.text = "\n".join(text) | ||
diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd new file mode 100644 index 0000000..9305003 --- /dev/null +++ b/apworld/client/gamedata.gd | |||
@@ -0,0 +1,294 @@ | |||
1 | extends Node | ||
2 | |||
3 | var SCRIPT_proto | ||
4 | |||
5 | var objects | ||
6 | var door_id_by_map_node_path = {} | ||
7 | var painting_id_by_map_node_path = {} | ||
8 | var panel_id_by_map_node_path = {} | ||
9 | var port_id_by_map_node_path = {} | ||
10 | var door_id_by_ap_id = {} | ||
11 | var map_id_by_name = {} | ||
12 | var progressive_id_by_ap_id = {} | ||
13 | var letter_id_by_ap_id = {} | ||
14 | var symbol_item_ids = [] | ||
15 | var anti_trap_ids = {} | ||
16 | var location_name_by_id = {} | ||
17 | var ending_display_name_by_name = {} | ||
18 | |||
19 | var kSYMBOL_ITEMS | ||
20 | |||
21 | |||
22 | func _init(proto_script): | ||
23 | SCRIPT_proto = proto_script | ||
24 | |||
25 | kSYMBOL_ITEMS = { | ||
26 | SCRIPT_proto.PuzzleSymbol.SUN: "Sun Symbol", | ||
27 | SCRIPT_proto.PuzzleSymbol.SPARKLES: "Sparkles Symbol", | ||
28 | SCRIPT_proto.PuzzleSymbol.ZERO: "Zero Symbol", | ||
29 | SCRIPT_proto.PuzzleSymbol.EXAMPLE: "Example Symbol", | ||
30 | SCRIPT_proto.PuzzleSymbol.BOXES: "Boxes Symbol", | ||
31 | SCRIPT_proto.PuzzleSymbol.PLANET: "Planet Symbol", | ||
32 | SCRIPT_proto.PuzzleSymbol.PYRAMID: "Pyramid Symbol", | ||
33 | SCRIPT_proto.PuzzleSymbol.CROSS: "Cross Symbol", | ||
34 | SCRIPT_proto.PuzzleSymbol.SWEET: "Sweet Symbol", | ||
35 | SCRIPT_proto.PuzzleSymbol.GENDER: "Gender Symbol", | ||
36 | SCRIPT_proto.PuzzleSymbol.AGE: "Age Symbol", | ||
37 | SCRIPT_proto.PuzzleSymbol.SOUND: "Sound Symbol", | ||
38 | SCRIPT_proto.PuzzleSymbol.ANAGRAM: "Anagram Symbol", | ||
39 | SCRIPT_proto.PuzzleSymbol.JOB: "Job Symbol", | ||
40 | SCRIPT_proto.PuzzleSymbol.STARS: "Stars Symbol", | ||
41 | SCRIPT_proto.PuzzleSymbol.NULL: "Null Symbol", | ||
42 | SCRIPT_proto.PuzzleSymbol.EVAL: "Eval Symbol", | ||
43 | SCRIPT_proto.PuzzleSymbol.LINGO: "Lingo Symbol", | ||
44 | SCRIPT_proto.PuzzleSymbol.QUESTION: "Question Symbol", | ||
45 | } | ||
46 | |||
47 | |||
48 | func load(data_bytes): | ||
49 | objects = SCRIPT_proto.AllObjects.new() | ||
50 | |||
51 | var result_code = objects.from_bytes(data_bytes) | ||
52 | if result_code != SCRIPT_proto.PB_ERR.NO_ERRORS: | ||
53 | print("Could not load generated data: %d" % result_code) | ||
54 | return | ||
55 | |||
56 | for map in objects.get_maps(): | ||
57 | map_id_by_name[map.get_name()] = map.get_id() | ||
58 | |||
59 | for door in objects.get_doors(): | ||
60 | var map = objects.get_maps()[door.get_map_id()] | ||
61 | |||
62 | if not map.get_name() in door_id_by_map_node_path: | ||
63 | door_id_by_map_node_path[map.get_name()] = {} | ||
64 | |||
65 | var map_data = door_id_by_map_node_path[map.get_name()] | ||
66 | for receiver in door.get_receivers(): | ||
67 | map_data[receiver] = door.get_id() | ||
68 | |||
69 | for painting_id in door.get_move_paintings(): | ||
70 | var painting = objects.get_paintings()[painting_id] | ||
71 | map_data[painting.get_path()] = door.get_id() | ||
72 | |||
73 | if door.has_ap_id(): | ||
74 | door_id_by_ap_id[door.get_ap_id()] = door.get_id() | ||
75 | |||
76 | if ( | ||
77 | door.get_type() == SCRIPT_proto.DoorType.STANDARD | ||
78 | or door.get_type() == SCRIPT_proto.DoorType.LOCATION_ONLY | ||
79 | or door.get_type() == SCRIPT_proto.DoorType.GRAVESTONE | ||
80 | ): | ||
81 | location_name_by_id[door.get_ap_id()] = _get_door_location_name(door) | ||
82 | |||
83 | for painting in objects.get_paintings(): | ||
84 | var room = objects.get_rooms()[painting.get_room_id()] | ||
85 | var map = objects.get_maps()[room.get_map_id()] | ||
86 | |||
87 | if not map.get_name() in painting_id_by_map_node_path: | ||
88 | painting_id_by_map_node_path[map.get_name()] = {} | ||
89 | |||
90 | var _map_data = painting_id_by_map_node_path[map.get_name()] | ||
91 | |||
92 | for port in objects.get_ports(): | ||
93 | var room = objects.get_rooms()[port.get_room_id()] | ||
94 | var map = objects.get_maps()[room.get_map_id()] | ||
95 | |||
96 | if not map.get_name() in port_id_by_map_node_path: | ||
97 | port_id_by_map_node_path[map.get_name()] = {} | ||
98 | |||
99 | var map_data = port_id_by_map_node_path[map.get_name()] | ||
100 | map_data[port.get_path()] = port.get_id() | ||
101 | |||
102 | for progressive in objects.get_progressives(): | ||
103 | progressive_id_by_ap_id[progressive.get_ap_id()] = progressive.get_id() | ||
104 | |||
105 | for letter in objects.get_letters(): | ||
106 | letter_id_by_ap_id[letter.get_ap_id()] = letter.get_id() | ||
107 | location_name_by_id[letter.get_ap_id()] = _get_letter_location_name(letter) | ||
108 | |||
109 | for mastery in objects.get_masteries(): | ||
110 | location_name_by_id[mastery.get_ap_id()] = _get_mastery_location_name(mastery) | ||
111 | |||
112 | for ending in objects.get_endings(): | ||
113 | var location_name = _get_ending_location_name(ending) | ||
114 | location_name_by_id[ending.get_ap_id()] = location_name | ||
115 | ending_display_name_by_name[ending.get_name()] = location_name | ||
116 | |||
117 | for keyholder in objects.get_keyholders(): | ||
118 | if keyholder.has_key(): | ||
119 | location_name_by_id[keyholder.get_ap_id()] = _get_keyholder_location_name(keyholder) | ||
120 | |||
121 | for panel in objects.get_panels(): | ||
122 | var room = objects.get_rooms()[panel.get_room_id()] | ||
123 | var map = objects.get_maps()[room.get_map_id()] | ||
124 | |||
125 | if not map.get_name() in panel_id_by_map_node_path: | ||
126 | panel_id_by_map_node_path[map.get_name()] = {} | ||
127 | |||
128 | var map_data = panel_id_by_map_node_path[map.get_name()] | ||
129 | map_data[panel.get_path()] = panel.get_id() | ||
130 | |||
131 | for symbol_name in kSYMBOL_ITEMS.values(): | ||
132 | symbol_item_ids.append(objects.get_special_ids()[symbol_name]) | ||
133 | |||
134 | for special_name in objects.get_special_ids().keys(): | ||
135 | if special_name.begins_with("Anti "): | ||
136 | anti_trap_ids[objects.get_special_ids()[special_name]] = ( | ||
137 | special_name.substr(5).to_lower() | ||
138 | ) | ||
139 | |||
140 | |||
141 | func get_door_for_map_node_path(map_name, node_path): | ||
142 | if not door_id_by_map_node_path.has(map_name): | ||
143 | return null | ||
144 | |||
145 | var map_data = door_id_by_map_node_path[map_name] | ||
146 | return map_data.get(node_path, null) | ||
147 | |||
148 | |||
149 | func get_panel_for_map_node_path(map_name, node_path): | ||
150 | if not panel_id_by_map_node_path.has(map_name): | ||
151 | return null | ||
152 | |||
153 | var map_data = panel_id_by_map_node_path[map_name] | ||
154 | return map_data.get(node_path, null) | ||
155 | |||
156 | |||
157 | func get_port_for_map_node_path(map_name, node_path): | ||
158 | if not port_id_by_map_node_path.has(map_name): | ||
159 | return null | ||
160 | |||
161 | var map_data = port_id_by_map_node_path[map_name] | ||
162 | return map_data.get(node_path, null) | ||
163 | |||
164 | |||
165 | func get_door_ap_id(door_id): | ||
166 | var door = objects.get_doors()[door_id] | ||
167 | if door.has_ap_id(): | ||
168 | return door.get_ap_id() | ||
169 | else: | ||
170 | return null | ||
171 | |||
172 | |||
173 | func get_door_map_name(door_id): | ||
174 | var door = objects.get_doors()[door_id] | ||
175 | var map = objects.get_maps()[door.get_map_id()] | ||
176 | return map.get_name() | ||
177 | |||
178 | |||
179 | func get_door_receivers(door_id): | ||
180 | var door = objects.get_doors()[door_id] | ||
181 | return door.get_receivers() | ||
182 | |||
183 | |||
184 | func get_worldport_display_name(port_id): | ||
185 | var port = objects.get_ports()[port_id] | ||
186 | return "%s - %s" % [_get_room_object_map_name(port), port.get_display_name()] | ||
187 | |||
188 | |||
189 | func _get_map_object_map_name(obj): | ||
190 | return objects.get_maps()[obj.get_map_id()].get_display_name() | ||
191 | |||
192 | |||
193 | func _get_room_object_map_name(obj): | ||
194 | return _get_map_object_map_name(objects.get_rooms()[obj.get_room_id()]) | ||
195 | |||
196 | |||
197 | func _get_room_object_location_prefix(obj): | ||
198 | var room = objects.get_rooms()[obj.get_room_id()] | ||
199 | var game_map = objects.get_maps()[room.get_map_id()] | ||
200 | |||
201 | if room.has_panel_display_name(): | ||
202 | return "%s (%s)" % [game_map.get_display_name(), room.get_panel_display_name()] | ||
203 | else: | ||
204 | return game_map.get_display_name() | ||
205 | |||
206 | |||
207 | func _get_door_location_name(door): | ||
208 | var map_part = _get_room_object_location_prefix(door) | ||
209 | |||
210 | if door.has_location_name(): | ||
211 | return "%s - %s" % [map_part, door.get_location_name()] | ||
212 | |||
213 | var generated_location_name = _get_generated_door_location_name(door) | ||
214 | if generated_location_name != null: | ||
215 | return generated_location_name | ||
216 | |||
217 | return "%s - %s" % [map_part, door.get_name()] | ||
218 | |||
219 | |||
220 | func _get_generated_door_location_name(door): | ||
221 | if door.get_type() != SCRIPT_proto.DoorType.STANDARD: | ||
222 | return null | ||
223 | |||
224 | if door.get_keyholders().size() > 0 or door.get_endings().size() > 0 or door.has_complete_at(): | ||
225 | return null | ||
226 | |||
227 | if door.get_panels().size() > 4: | ||
228 | return null | ||
229 | |||
230 | var map_areas = [] | ||
231 | for panel_id in door.get_panels(): | ||
232 | var panel = objects.get_panels()[panel_id.get_panel()] | ||
233 | var panel_room = objects.get_rooms()[panel.get_room_id()] | ||
234 | # It's okay if panel_display_name is not present because then it's coalesced with other unnamed areas. | ||
235 | var panel_display_name = "" | ||
236 | if panel_room.has_panel_display_name(): | ||
237 | panel_display_name = panel_room.get_panel_display_name() | ||
238 | if not map_areas.has(panel_display_name): | ||
239 | map_areas.append(panel_display_name) | ||
240 | |||
241 | if map_areas.size() > 1: | ||
242 | return null | ||
243 | |||
244 | var game_map = objects.get_maps()[door.get_map_id()] | ||
245 | var map_area = map_areas[0] | ||
246 | var map_part | ||
247 | if map_area == "": | ||
248 | map_part = game_map.get_display_name() | ||
249 | else: | ||
250 | map_part = "%s (%s)" % [game_map.get_display_name(), map_area] | ||
251 | |||
252 | var panel_names = [] | ||
253 | for panel_id in door.get_panels(): | ||
254 | var panel_data = objects.get_panels()[panel_id.get_panel()] | ||
255 | var panel_name | ||
256 | if panel_data.has_display_name(): | ||
257 | panel_name = panel_data.get_display_name() | ||
258 | else: | ||
259 | panel_name = panel_data.get_name() | ||
260 | |||
261 | var location_part | ||
262 | if panel_id.has_answer(): | ||
263 | location_part = "%s/%s" % [panel_name, panel_id.get_answer().to_upper()] | ||
264 | else: | ||
265 | location_part = panel_name | ||
266 | |||
267 | panel_names.append(location_part) | ||
268 | |||
269 | panel_names.sort() | ||
270 | |||
271 | return map_part + " - " + ", ".join(panel_names) | ||
272 | |||
273 | |||
274 | func _get_letter_location_name(letter): | ||
275 | var letter_level = 2 if (letter.has_level2() and letter.get_level2()) else 1 | ||
276 | var letter_name = "%s%d" % [letter.get_key().to_upper(), letter_level] | ||
277 | return "%s - %s" % [_get_room_object_map_name(letter), letter_name] | ||
278 | |||
279 | |||
280 | func _get_mastery_location_name(mastery): | ||
281 | return "%s - Mastery" % _get_room_object_map_name(mastery) | ||
282 | |||
283 | |||
284 | func _get_ending_location_name(ending): | ||
285 | return ( | ||
286 | "%s - %s Ending" % [_get_room_object_map_name(ending), ending.get_name().to_pascal_case()] | ||
287 | ) | ||
288 | |||
289 | |||
290 | func _get_keyholder_location_name(keyholder): | ||
291 | return ( | ||
292 | "%s - %s Keyholder" | ||
293 | % [_get_room_object_location_prefix(keyholder), keyholder.get_key().to_upper()] | ||
294 | ) | ||
diff --git a/apworld/client/keyHolder.gd b/apworld/client/keyHolder.gd new file mode 100644 index 0000000..3c037ff --- /dev/null +++ b/apworld/client/keyHolder.gd | |||
@@ -0,0 +1,38 @@ | |||
1 | extends "res://scripts/nodes/keyHolder.gd" | ||
2 | |||
3 | |||
4 | func setFromAp(key, level): | ||
5 | if level > 0: | ||
6 | has_key = true | ||
7 | is_complete = "%s%d" % [key, level] | ||
8 | held_key = key | ||
9 | held_level = level | ||
10 | get_node("Hinge/Letter").mesh.text = held_key | ||
11 | get_node("Hinge/Letter2").mesh.text = held_key | ||
12 | setMaterial() | ||
13 | emit_signal("trigger") | ||
14 | else: | ||
15 | has_key = false | ||
16 | held_key = "" | ||
17 | held_level = 0 | ||
18 | setMaterial() | ||
19 | get_node("Hinge/Letter").mesh.text = "-" | ||
20 | get_node("Hinge/Letter2").mesh.text = "-" | ||
21 | is_complete = "" | ||
22 | emit_signal("untrigger") | ||
23 | |||
24 | |||
25 | func addKey(key): | ||
26 | var node_path = String( | ||
27 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
28 | ) | ||
29 | var ap = global.get_node("Archipelago") | ||
30 | ap.keyboard.put_in_keyholder(key, global.map, node_path) | ||
31 | |||
32 | |||
33 | func removeKey(): | ||
34 | var node_path = String( | ||
35 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
36 | ) | ||
37 | var ap = global.get_node("Archipelago") | ||
38 | ap.keyboard.remove_from_keyholder(held_key, global.map, node_path) | ||
diff --git a/apworld/client/keyHolderChecker.gd b/apworld/client/keyHolderChecker.gd new file mode 100644 index 0000000..a75a9e4 --- /dev/null +++ b/apworld/client/keyHolderChecker.gd | |||
@@ -0,0 +1,24 @@ | |||
1 | extends "res://scripts/nodes/listeners/keyHolderChecker.gd" | ||
2 | |||
3 | |||
4 | func check(): | ||
5 | var ap = global.get_node("Archipelago") | ||
6 | var matches = [] | ||
7 | for map in ap.keyboard.keyholder_state.keys(): | ||
8 | var nodes = ap.keyboard.keyholder_state[map] | ||
9 | for node in nodes.keys(): | ||
10 | matches.append([nodes[node], 1, map, "/root/scene/%s" % node]) | ||
11 | |||
12 | var count = 0 | ||
13 | for key_match in matches: | ||
14 | var active = ( | ||
15 | key_match[2] + String(key_match[3]).replace("/root/scene/Components/KeyHolders/", ".") | ||
16 | ) | ||
17 | if map[active] == key_match[0]: | ||
18 | emit_signal("trigger_letter", key_match[0], true) | ||
19 | count += 1 | ||
20 | else: | ||
21 | emit_signal("trigger_letter", key_match[0], false) | ||
22 | |||
23 | if count > 25: | ||
24 | emit_signal("trigger") | ||
diff --git a/apworld/client/keyHolderResetterListener.gd b/apworld/client/keyHolderResetterListener.gd new file mode 100644 index 0000000..d5300f3 --- /dev/null +++ b/apworld/client/keyHolderResetterListener.gd | |||
@@ -0,0 +1,8 @@ | |||
1 | extends "res://scripts/nodes/listeners/keyHolderResetterListener.gd" | ||
2 | |||
3 | |||
4 | func reset(): | ||
5 | var ap = global.get_node("Archipelago") | ||
6 | var was_removed = ap.keyboard.reset_keyholders() | ||
7 | if was_removed: | ||
8 | sfxPlayer.sfx_play("pickup") | ||
diff --git a/apworld/client/keyboard.gd b/apworld/client/keyboard.gd new file mode 100644 index 0000000..a59c4d0 --- /dev/null +++ b/apworld/client/keyboard.gd | |||
@@ -0,0 +1,231 @@ | |||
1 | extends Node | ||
2 | |||
3 | const kALL_LETTERS = "abcdefghjiklmnopqrstuvwxyz" | ||
4 | |||
5 | var letters_saved = {} | ||
6 | var letters_in_keyholders = [] | ||
7 | var letters_blocked = [] | ||
8 | var letters_dynamic = {} | ||
9 | var keyholder_state = {} | ||
10 | |||
11 | var filename = "" | ||
12 | |||
13 | |||
14 | func _init(): | ||
15 | reset() | ||
16 | |||
17 | |||
18 | func reset(): | ||
19 | letters_saved.clear() | ||
20 | letters_in_keyholders.clear() | ||
21 | letters_blocked.clear() | ||
22 | letters_dynamic.clear() | ||
23 | keyholder_state.clear() | ||
24 | |||
25 | |||
26 | func load_seed(): | ||
27 | var ap = global.get_node("Archipelago") | ||
28 | |||
29 | reset() | ||
30 | |||
31 | filename = "user://archipelago_keys/%s_%d" % [ap.client._seed, ap.client._slot] | ||
32 | |||
33 | if FileAccess.file_exists(filename): | ||
34 | var ap_file = FileAccess.open(filename, FileAccess.READ) | ||
35 | var localdata = [] | ||
36 | if ap_file != null: | ||
37 | localdata = ap_file.get_var(true) | ||
38 | ap_file.close() | ||
39 | |||
40 | if typeof(localdata) != TYPE_ARRAY: | ||
41 | print("AP keyboard file is corrupted") | ||
42 | localdata = [] | ||
43 | |||
44 | if localdata.size() > 0: | ||
45 | letters_saved = localdata[0] | ||
46 | if localdata.size() > 1: | ||
47 | letters_in_keyholders = localdata[1] | ||
48 | if localdata.size() > 2: | ||
49 | keyholder_state = localdata[2] | ||
50 | |||
51 | if not letters_saved.is_empty(): | ||
52 | ap.client.updateKeyboard(letters_saved) | ||
53 | |||
54 | for k in kALL_LETTERS: | ||
55 | var level = 0 | ||
56 | |||
57 | if ap.get_letter_behavior(k, false) == ap.kLETTER_BEHAVIOR_UNLOCKED: | ||
58 | level += 1 | ||
59 | if ap.get_letter_behavior(k, true) == ap.kLETTER_BEHAVIOR_UNLOCKED: | ||
60 | level += 1 | ||
61 | |||
62 | letters_dynamic[k] = level | ||
63 | |||
64 | update_unlocks() | ||
65 | |||
66 | |||
67 | func save(): | ||
68 | var dir = DirAccess.open("user://") | ||
69 | var folder = "archipelago_keys" | ||
70 | if not dir.dir_exists(folder): | ||
71 | dir.make_dir(folder) | ||
72 | |||
73 | var file = FileAccess.open(filename, FileAccess.WRITE) | ||
74 | |||
75 | var data = [ | ||
76 | letters_saved, | ||
77 | letters_in_keyholders, | ||
78 | keyholder_state, | ||
79 | ] | ||
80 | file.store_var(data, true) | ||
81 | file.close() | ||
82 | |||
83 | |||
84 | func update_unlocks(): | ||
85 | unlocks.resetKeys() | ||
86 | |||
87 | var has_doubles = false | ||
88 | |||
89 | for k in kALL_LETTERS: | ||
90 | var level = 0 | ||
91 | |||
92 | if not letters_in_keyholders.has(k): | ||
93 | level = letters_saved.get(k, 0) + letters_dynamic.get(k, 0) | ||
94 | |||
95 | if level >= 2: | ||
96 | level = 2 | ||
97 | has_doubles = true | ||
98 | |||
99 | if letters_blocked.has(k): | ||
100 | level = 0 | ||
101 | |||
102 | unlocks.unlockKey(k, level) | ||
103 | |||
104 | if has_doubles and unlocks.data["double_letters"] != "unlocked": | ||
105 | var ap = global.get_node("Archipelago") | ||
106 | if ap.cyan_door_behavior == ap.kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER: | ||
107 | unlocks.setData("double_letters", "unlocked") | ||
108 | |||
109 | |||
110 | func collect_local_letter(key, level): | ||
111 | var ap = global.get_node("Archipelago") | ||
112 | var true_level = 0 | ||
113 | |||
114 | if ap.get_letter_behavior(key, false) == ap.kLETTER_BEHAVIOR_VANILLA: | ||
115 | true_level += 1 | ||
116 | if level == 2 and ap.get_letter_behavior(key, true) == ap.kLETTER_BEHAVIOR_VANILLA: | ||
117 | true_level += 1 | ||
118 | |||
119 | if true_level < letters_saved.get(key, 0): | ||
120 | return | ||
121 | |||
122 | letters_saved[key] = true_level | ||
123 | |||
124 | ap.client.updateKeyboard({key: true_level}) | ||
125 | |||
126 | if letters_blocked.has(key): | ||
127 | letters_blocked.erase(key) | ||
128 | |||
129 | update_unlocks() | ||
130 | save() | ||
131 | |||
132 | |||
133 | func collect_remote_letter(key, level): | ||
134 | if level < 0 or level > 2 or level < letters_dynamic.get(key, 0): | ||
135 | return | ||
136 | |||
137 | letters_dynamic[key] = level | ||
138 | |||
139 | if letters_blocked.has(key): | ||
140 | letters_blocked.erase(key) | ||
141 | |||
142 | update_unlocks() | ||
143 | save() | ||
144 | |||
145 | |||
146 | func put_in_keyholder(key, map, kh_path): | ||
147 | if not keyholder_state.has(map): | ||
148 | keyholder_state[map] = {} | ||
149 | |||
150 | keyholder_state[map][kh_path] = key | ||
151 | letters_in_keyholders.append(key) | ||
152 | |||
153 | get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp( | ||
154 | key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2) | ||
155 | ) | ||
156 | |||
157 | update_unlocks() | ||
158 | save() | ||
159 | |||
160 | |||
161 | func remove_from_keyholder(key, map, kh_path): | ||
162 | if not keyholder_state.has(map): | ||
163 | # This... shouldn't happen. | ||
164 | keyholder_state[map] = {} | ||
165 | |||
166 | keyholder_state[map].erase(kh_path) | ||
167 | letters_in_keyholders.erase(key) | ||
168 | |||
169 | get_tree().get_root().get_node("scene").get_node(kh_path).setFromAp(key, 0) | ||
170 | |||
171 | update_unlocks() | ||
172 | save() | ||
173 | |||
174 | |||
175 | func block_letter(key): | ||
176 | if not letters_blocked.has(key): | ||
177 | letters_blocked.append(key) | ||
178 | |||
179 | update_unlocks() | ||
180 | |||
181 | |||
182 | func load_keyholders(map): | ||
183 | if keyholder_state.has(map): | ||
184 | var khs = keyholder_state[map] | ||
185 | |||
186 | for path in khs.keys(): | ||
187 | var key = khs[path] | ||
188 | get_tree().get_root().get_node("scene").get_node(path).setFromAp( | ||
189 | key, min(letters_saved.get(key, 0) + letters_dynamic.get(key, 0), 2) | ||
190 | ) | ||
191 | |||
192 | |||
193 | func reset_keyholders(): | ||
194 | if letters_in_keyholders.is_empty() and letters_blocked.is_empty(): | ||
195 | return false | ||
196 | |||
197 | var cleared_anything = not letters_in_keyholders.is_empty() or not letters_blocked.is_empty() | ||
198 | |||
199 | if keyholder_state.has(global.map): | ||
200 | for path in keyholder_state[global.map]: | ||
201 | get_tree().get_root().get_node("scene").get_node(path).setFromAp( | ||
202 | keyholder_state[global.map][path], 0 | ||
203 | ) | ||
204 | |||
205 | keyholder_state.clear() | ||
206 | letters_in_keyholders.clear() | ||
207 | letters_blocked.clear() | ||
208 | |||
209 | update_unlocks() | ||
210 | save() | ||
211 | |||
212 | return cleared_anything | ||
213 | |||
214 | |||
215 | func remote_keyboard_updated(updates): | ||
216 | var reverse = {} | ||
217 | var should_update = false | ||
218 | |||
219 | for k in updates: | ||
220 | if not letters_saved.has(k) or updates[k] > letters_saved[k]: | ||
221 | letters_saved[k] = updates[k] | ||
222 | should_update = true | ||
223 | elif updates[k] < letters_saved[k]: | ||
224 | reverse[k] = letters_saved[k] | ||
225 | |||
226 | if should_update: | ||
227 | update_unlocks() | ||
228 | |||
229 | if not reverse.is_empty(): | ||
230 | var ap = global.get_node("Archipelago") | ||
231 | ap.client.updateKeyboard(reverse) | ||
diff --git a/apworld/client/locationListener.gd b/apworld/client/locationListener.gd new file mode 100644 index 0000000..71792ed --- /dev/null +++ b/apworld/client/locationListener.gd | |||
@@ -0,0 +1,20 @@ | |||
1 | extends Receiver | ||
2 | |||
3 | var location_id | ||
4 | |||
5 | |||
6 | func _ready(): | ||
7 | super._ready() | ||
8 | |||
9 | |||
10 | func handleTriggered(): | ||
11 | triggered += 1 | ||
12 | if triggered >= total: | ||
13 | var ap = global.get_node("Archipelago") | ||
14 | ap.send_location(location_id) | ||
15 | |||
16 | |||
17 | func handleUntriggered(): | ||
18 | triggered -= 1 | ||
19 | if triggered < total: | ||
20 | pass | ||
diff --git a/apworld/client/main.gd b/apworld/client/main.gd new file mode 100644 index 0000000..e1f9610 --- /dev/null +++ b/apworld/client/main.gd | |||
@@ -0,0 +1,296 @@ | |||
1 | extends Node | ||
2 | |||
3 | |||
4 | func _ready(): | ||
5 | var runtime = global.get_node("Runtime") | ||
6 | |||
7 | # Some helpful logging. | ||
8 | if Steam.isSubscribed(): | ||
9 | global._print("Provisioning successful! Build ID: %d" % Steam.getAppBuildId()) | ||
10 | else: | ||
11 | global._print("Provisioning failed.") | ||
12 | |||
13 | # Undo the load screen removing our cursor | ||
14 | get_tree().get_root().set_disable_input(false) | ||
15 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | ||
16 | |||
17 | # Increase the WebSocket input buffer size so that we can download large | ||
18 | # data packages. | ||
19 | ProjectSettings.set_setting("network/limits/websocket_client/max_in_buffer_kb", 8192) | ||
20 | |||
21 | switcher.layer = 4 | ||
22 | |||
23 | # Create the global AP manager, if it doesn't already exist. | ||
24 | if not global.has_node("Archipelago"): | ||
25 | var ap_script = runtime.load_script("manager.gd") | ||
26 | var ap_instance = ap_script.new() | ||
27 | ap_instance.name = "Archipelago" | ||
28 | |||
29 | ap_instance.SCRIPT_client = runtime.load_script("client.gd") | ||
30 | ap_instance.SCRIPT_keyboard = runtime.load_script("keyboard.gd") | ||
31 | ap_instance.SCRIPT_locationListener = runtime.load_script("locationListener.gd") | ||
32 | ap_instance.SCRIPT_minimap = runtime.load_script("minimap.gd") | ||
33 | ap_instance.SCRIPT_victoryListener = runtime.load_script("victoryListener.gd") | ||
34 | ap_instance.SCRIPT_websocketserver = runtime.load_script("vendor/WebSocketServer.gd") | ||
35 | |||
36 | global.add_child(ap_instance) | ||
37 | |||
38 | # Let's also inject any scripts we need to inject now. | ||
39 | installScriptExtension(runtime.load_script("animationListener.gd")) | ||
40 | installScriptExtension(runtime.load_script("collectable.gd")) | ||
41 | installScriptExtension(runtime.load_script("door.gd")) | ||
42 | installScriptExtension(runtime.load_script("keyHolder.gd")) | ||
43 | installScriptExtension(runtime.load_script("keyHolderChecker.gd")) | ||
44 | installScriptExtension(runtime.load_script("keyHolderResetterListener.gd")) | ||
45 | installScriptExtension(runtime.load_script("painting.gd")) | ||
46 | installScriptExtension(runtime.load_script("panel.gd")) | ||
47 | installScriptExtension(runtime.load_script("pauseMenu.gd")) | ||
48 | installScriptExtension(runtime.load_script("player.gd")) | ||
49 | installScriptExtension(runtime.load_script("saver.gd")) | ||
50 | installScriptExtension(runtime.load_script("teleport.gd")) | ||
51 | installScriptExtension(runtime.load_script("teleportListener.gd")) | ||
52 | installScriptExtension(runtime.load_script("visibilityListener.gd")) | ||
53 | installScriptExtension(runtime.load_script("worldport.gd")) | ||
54 | installScriptExtension(runtime.load_script("worldportListener.gd")) | ||
55 | |||
56 | var proto_script = runtime.load_script("../generated/proto.gd") | ||
57 | var gamedata_script = runtime.load_script("gamedata.gd") | ||
58 | var gamedata_instance = gamedata_script.new(proto_script) | ||
59 | gamedata_instance.load(runtime.read_path("../generated/data.binpb")) | ||
60 | gamedata_instance.name = "Gamedata" | ||
61 | global.add_child(gamedata_instance) | ||
62 | |||
63 | var messages_script = runtime.load_script("messages.gd") | ||
64 | var messages_instance = messages_script.new() | ||
65 | messages_instance.name = "Messages" | ||
66 | messages_instance.SCRIPT_rainbowText = runtime.load_script("rainbowText.gd") | ||
67 | global.add_child(messages_instance) | ||
68 | |||
69 | var effects_script = runtime.load_script("effects.gd") | ||
70 | var effects_instance = effects_script.new() | ||
71 | effects_instance.name = "Effects" | ||
72 | global.add_child(effects_instance) | ||
73 | |||
74 | var textclient_script = runtime.load_script("textclient.gd") | ||
75 | var textclient_instance = textclient_script.new() | ||
76 | textclient_instance.name = "Textclient" | ||
77 | global.add_child(textclient_instance) | ||
78 | |||
79 | var compass_overlay_script = runtime.load_script("compass_overlay.gd") | ||
80 | var compass_overlay_instance = compass_overlay_script.new() | ||
81 | compass_overlay_instance.name = "Compass" | ||
82 | compass_overlay_instance.SCRIPT_compass = runtime.load_script("compass.gd") | ||
83 | global.add_child(compass_overlay_instance) | ||
84 | |||
85 | var ap = global.get_node("Archipelago") | ||
86 | var gamedata = global.get_node("Gamedata") | ||
87 | ap.ap_connected.connect(connectionSuccessful) | ||
88 | ap.could_not_connect.connect(connectionUnsuccessful) | ||
89 | ap.connect_status.connect(connectionStatus) | ||
90 | |||
91 | # Populate textboxes with AP settings. | ||
92 | get_node("../Panel/server_box").text = ap.ap_server | ||
93 | get_node("../Panel/player_box").text = ap.ap_user | ||
94 | get_node("../Panel/password_box").text = ap.ap_pass | ||
95 | |||
96 | var history_box = get_node("../Panel/connection_history") | ||
97 | if ap.connection_history.is_empty(): | ||
98 | history_box.disabled = true | ||
99 | else: | ||
100 | history_box.disabled = false | ||
101 | |||
102 | var i = 0 | ||
103 | for details in ap.connection_history: | ||
104 | history_box.get_popup().add_item("%s (%s)" % [details[1], details[0]], i) | ||
105 | i += 1 | ||
106 | |||
107 | history_box.get_popup().id_pressed.connect(historySelected) | ||
108 | |||
109 | # Show client version. | ||
110 | var version = gamedata.objects.get_version() | ||
111 | get_node("../Panel/title").text = ( | ||
112 | "ARCHIPELAGO (%d.%d.%d)" % [version.get_major(), version.get_minor(), version.get_patch()] | ||
113 | ) | ||
114 | |||
115 | # Increase font size in text boxes. | ||
116 | get_node("../Panel/server_box").add_theme_font_size_override("font_size", 36) | ||
117 | get_node("../Panel/player_box").add_theme_font_size_override("font_size", 36) | ||
118 | get_node("../Panel/password_box").add_theme_font_size_override("font_size", 36) | ||
119 | |||
120 | # Set up version mismatch dialog. | ||
121 | get_node("../Panel/VersionMismatch").confirmed.connect(startGame) | ||
122 | get_node("../Panel/VersionMismatch").get_cancel_button().pressed.connect( | ||
123 | versionMismatchDeclined | ||
124 | ) | ||
125 | |||
126 | # Set up buttons. | ||
127 | get_node("../Panel/connect_button").pressed.connect(_connect_pressed) | ||
128 | get_node("../Panel/quit_button").pressed.connect(_back_pressed) | ||
129 | |||
130 | |||
131 | func _connect_pressed(): | ||
132 | get_node("../Panel/connect_button").disabled = true | ||
133 | |||
134 | var ap = global.get_node("Archipelago") | ||
135 | ap.ap_server = get_node("../Panel/server_box").text | ||
136 | ap.ap_user = get_node("../Panel/player_box").text | ||
137 | ap.ap_pass = get_node("../Panel/password_box").text | ||
138 | ap.saveSettings() | ||
139 | |||
140 | ap.connectToServer() | ||
141 | |||
142 | |||
143 | func _back_pressed(): | ||
144 | var ap = global.get_node("Archipelago") | ||
145 | ap.disconnect_from_ap() | ||
146 | ap.client.sendQuit() | ||
147 | |||
148 | get_tree().quit() | ||
149 | |||
150 | |||
151 | # Adapted from https://gitlab.com/Delta-V-Modding/Mods/-/blob/main/game/ModLoader.gd | ||
152 | func installScriptExtension(childScript: Resource): | ||
153 | # Force Godot to compile the script now. | ||
154 | # We need to do this here to ensure that the inheritance chain is | ||
155 | # properly set up, and multiple mods can chain-extend the same | ||
156 | # class multiple times. | ||
157 | # This is also needed to make Godot instantiate the extended class | ||
158 | # when creating singletons. | ||
159 | # The actual instance is thrown away. | ||
160 | childScript.new() | ||
161 | |||
162 | var parentScript = childScript.get_base_script() | ||
163 | var parentScriptPath = parentScript.resource_path | ||
164 | global._print("ModLoader: Installing script extension over %s" % parentScriptPath) | ||
165 | childScript.take_over_path(parentScriptPath) | ||
166 | |||
167 | |||
168 | func connectionStatus(message): | ||
169 | var popup = get_node("../Panel/AcceptDialog") | ||
170 | popup.title = "Connecting to Archipelago" | ||
171 | popup.dialog_text = message | ||
172 | popup.exclusive = true | ||
173 | popup.get_ok_button().visible = false | ||
174 | popup.popup_centered() | ||
175 | |||
176 | |||
177 | func connectionSuccessful(): | ||
178 | var ap = global.get_node("Archipelago") | ||
179 | var gamedata = global.get_node("Gamedata") | ||
180 | |||
181 | # Check for major version mismatch. | ||
182 | if ap.apworld_version[0] != gamedata.objects.get_version().get_major(): | ||
183 | get_node("../Panel/AcceptDialog").exclusive = false | ||
184 | |||
185 | var popup = get_node("../Panel/VersionMismatch") | ||
186 | popup.title = "Version Mismatch!" | ||
187 | popup.dialog_text = ( | ||
188 | "This slot was generated using v%d.%d.%d of the Lingo 2 apworld,\nwhich has a different major version than this client (v%d.%d.%d).\nIt is highly recommended to play using the correct version of the client.\nYou may experience bugs or logic issues if you continue." | ||
189 | % [ | ||
190 | ap.apworld_version[0], | ||
191 | ap.apworld_version[1], | ||
192 | ap.apworld_version[2], | ||
193 | gamedata.objects.get_version().get_major(), | ||
194 | gamedata.objects.get_version().get_minor(), | ||
195 | gamedata.objects.get_version().get_patch() | ||
196 | ] | ||
197 | ) | ||
198 | popup.exclusive = true | ||
199 | popup.popup_centered() | ||
200 | |||
201 | return | ||
202 | |||
203 | startGame() | ||
204 | |||
205 | |||
206 | func startGame(): | ||
207 | var ap = global.get_node("Archipelago") | ||
208 | |||
209 | # Save connection details | ||
210 | var connection_details = [ap.ap_server, ap.ap_user, ap.ap_pass] | ||
211 | if ap.connection_history.has(connection_details): | ||
212 | ap.connection_history.erase(connection_details) | ||
213 | ap.connection_history.push_front(connection_details) | ||
214 | if ap.connection_history.size() > 10: | ||
215 | ap.connection_history.resize(10) | ||
216 | ap.saveSettings() | ||
217 | |||
218 | # Switch to the_entry | ||
219 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | ||
220 | global.user = ap.getSaveFileName() | ||
221 | global.universe = "lingo" | ||
222 | global.map = "the_entry" | ||
223 | |||
224 | unlocks.resetCollectables() | ||
225 | unlocks.resetData() | ||
226 | |||
227 | ap.setup_keys() | ||
228 | |||
229 | unlocks.loadCollectables() | ||
230 | unlocks.loadData() | ||
231 | unlocks.unlockKey("capslock", 1) | ||
232 | |||
233 | if ap.shuffle_worldports: | ||
234 | settings.worldport_fades = "default" | ||
235 | else: | ||
236 | settings.worldport_fades = "never" | ||
237 | |||
238 | clearResourceCache("res://objects/meshes/gridDoor.tscn") | ||
239 | clearResourceCache("res://objects/nodes/collectable.tscn") | ||
240 | clearResourceCache("res://objects/nodes/door.tscn") | ||
241 | clearResourceCache("res://objects/nodes/keyHolder.tscn") | ||
242 | clearResourceCache("res://objects/nodes/listeners/animationListener.tscn") | ||
243 | clearResourceCache("res://objects/nodes/listeners/keyHolderChecker.tscn") | ||
244 | clearResourceCache("res://objects/nodes/listeners/keyHolderResetterListener.tscn") | ||
245 | clearResourceCache("res://objects/nodes/listeners/teleportListener.tscn") | ||
246 | clearResourceCache("res://objects/nodes/listeners/visibilityListener.tscn") | ||
247 | clearResourceCache("res://objects/nodes/listeners/worldportListener.tscn") | ||
248 | clearResourceCache("res://objects/nodes/panel.tscn") | ||
249 | clearResourceCache("res://objects/nodes/player.tscn") | ||
250 | clearResourceCache("res://objects/nodes/saver.tscn") | ||
251 | clearResourceCache("res://objects/nodes/teleport.tscn") | ||
252 | clearResourceCache("res://objects/nodes/worldport.tscn") | ||
253 | clearResourceCache("res://objects/scenes/menus/pause_menu.tscn") | ||
254 | |||
255 | var paintings_dir = DirAccess.open("res://objects/meshes/paintings") | ||
256 | if paintings_dir: | ||
257 | paintings_dir.list_dir_begin() | ||
258 | var file_name = paintings_dir.get_next() | ||
259 | while file_name != "": | ||
260 | if not paintings_dir.current_is_dir() and file_name.ends_with(".tscn"): | ||
261 | clearResourceCache("res://objects/meshes/paintings/" + file_name) | ||
262 | file_name = paintings_dir.get_next() | ||
263 | |||
264 | switcher.switch_map.call_deferred("res://objects/scenes/the_entry.tscn") | ||
265 | |||
266 | |||
267 | func connectionUnsuccessful(error_message): | ||
268 | get_node("../Panel/connect_button").disabled = false | ||
269 | |||
270 | var popup = get_node("../Panel/AcceptDialog") | ||
271 | popup.title = "Could not connect to Archipelago" | ||
272 | popup.dialog_text = error_message | ||
273 | popup.exclusive = true | ||
274 | popup.get_ok_button().visible = true | ||
275 | popup.popup_centered() | ||
276 | |||
277 | |||
278 | func versionMismatchDeclined(): | ||
279 | get_node("../Panel/AcceptDialog").hide() | ||
280 | get_node("../Panel/connect_button").disabled = false | ||
281 | |||
282 | var ap = global.get_node("Archipelago") | ||
283 | ap.disconnect_from_ap() | ||
284 | |||
285 | |||
286 | func historySelected(index): | ||
287 | var ap = global.get_node("Archipelago") | ||
288 | var details = ap.connection_history[index] | ||
289 | |||
290 | get_node("../Panel/server_box").text = details[0] | ||
291 | get_node("../Panel/player_box").text = details[1] | ||
292 | get_node("../Panel/password_box").text = details[2] | ||
293 | |||
294 | |||
295 | func clearResourceCache(path): | ||
296 | ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_REPLACE) | ||
diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd new file mode 100644 index 0000000..dac09b2 --- /dev/null +++ b/apworld/client/manager.gd | |||
@@ -0,0 +1,651 @@ | |||
1 | extends Node | ||
2 | |||
3 | var SCRIPT_client | ||
4 | var SCRIPT_keyboard | ||
5 | var SCRIPT_locationListener | ||
6 | var SCRIPT_minimap | ||
7 | var SCRIPT_victoryListener | ||
8 | var SCRIPT_websocketserver | ||
9 | |||
10 | var ap_server = "" | ||
11 | var ap_user = "" | ||
12 | var ap_pass = "" | ||
13 | var connection_history = [] | ||
14 | var show_compass = false | ||
15 | var show_locations = false | ||
16 | var show_minimap = false | ||
17 | |||
18 | var client | ||
19 | var keyboard | ||
20 | |||
21 | var _localdata_file = "" | ||
22 | var _last_new_item = -1 | ||
23 | var _batch_locations = false | ||
24 | var _held_locations = [] | ||
25 | var _held_location_scouts = [] | ||
26 | var _location_scouts = {} | ||
27 | var _item_locks = {} | ||
28 | var _inverse_item_locks = {} | ||
29 | var _held_letters = {} | ||
30 | var _letters_setup = false | ||
31 | var _already_connected = false | ||
32 | |||
33 | const kSHUFFLE_LETTERS_VANILLA = 0 | ||
34 | const kSHUFFLE_LETTERS_UNLOCKED = 1 | ||
35 | const kSHUFFLE_LETTERS_PROGRESSIVE = 2 | ||
36 | const kSHUFFLE_LETTERS_VANILLA_CYAN = 3 | ||
37 | const kSHUFFLE_LETTERS_ITEM_CYAN = 4 | ||
38 | |||
39 | const kLETTER_BEHAVIOR_VANILLA = 0 | ||
40 | const kLETTER_BEHAVIOR_ITEM = 1 | ||
41 | const kLETTER_BEHAVIOR_UNLOCKED = 2 | ||
42 | |||
43 | const kCYAN_DOOR_BEHAVIOR_H2 = 0 | ||
44 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 | ||
45 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 | ||
46 | |||
47 | const kEndingNameByVictoryValue = { | ||
48 | 0: "GRAY", | ||
49 | 1: "PURPLE", | ||
50 | 2: "MINT", | ||
51 | 3: "BLACK", | ||
52 | 4: "BLUE", | ||
53 | 5: "CYAN", | ||
54 | 6: "RED", | ||
55 | 7: "PLUM", | ||
56 | 8: "ORANGE", | ||
57 | 9: "GOLD", | ||
58 | 10: "YELLOW", | ||
59 | 11: "GREEN", | ||
60 | 12: "WHITE", | ||
61 | } | ||
62 | |||
63 | var apworld_version = [0, 0, 0] | ||
64 | var cyan_door_behavior = kCYAN_DOOR_BEHAVIOR_H2 | ||
65 | var daedalus_roof_access = false | ||
66 | var keyholder_sanity = false | ||
67 | var port_pairings = {} | ||
68 | var shuffle_control_center_colors = false | ||
69 | var shuffle_doors = false | ||
70 | var shuffle_gallery_paintings = false | ||
71 | var shuffle_letters = kSHUFFLE_LETTERS_VANILLA | ||
72 | var shuffle_symbols = false | ||
73 | var shuffle_worldports = false | ||
74 | var strict_cyan_ending = false | ||
75 | var strict_purple_ending = false | ||
76 | var victory_condition = -1 | ||
77 | |||
78 | var color_by_material_path = {} | ||
79 | |||
80 | signal could_not_connect | ||
81 | signal connect_status | ||
82 | signal ap_connected | ||
83 | |||
84 | |||
85 | func _init(): | ||
86 | # Read AP settings from file, if there are any | ||
87 | if FileAccess.file_exists("user://ap_settings"): | ||
88 | var file = FileAccess.open("user://ap_settings", FileAccess.READ) | ||
89 | var data = file.get_var(true) | ||
90 | file.close() | ||
91 | |||
92 | if typeof(data) != TYPE_ARRAY: | ||
93 | global._print("AP settings file is corrupted") | ||
94 | data = [] | ||
95 | |||
96 | if data.size() > 0: | ||
97 | ap_server = data[0] | ||
98 | |||
99 | if data.size() > 1: | ||
100 | ap_user = data[1] | ||
101 | |||
102 | if data.size() > 2: | ||
103 | ap_pass = data[2] | ||
104 | |||
105 | if data.size() > 3: | ||
106 | connection_history = data[3] | ||
107 | |||
108 | if data.size() > 4: | ||
109 | show_compass = data[4] | ||
110 | |||
111 | if data.size() > 5: | ||
112 | show_locations = data[5] | ||
113 | |||
114 | if data.size() > 6: | ||
115 | show_minimap = data[6] | ||
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 | |||
131 | |||
132 | func _ready(): | ||
133 | client = SCRIPT_client.new() | ||
134 | client.SCRIPT_websocketserver = SCRIPT_websocketserver | ||
135 | |||
136 | client.item_received.connect(_process_item) | ||
137 | client.location_scout_received.connect(_process_location_scout) | ||
138 | client.text_message_received.connect(_process_text_message) | ||
139 | client.item_sent_notification.connect(_process_item_sent_notification) | ||
140 | client.hint_received.connect(_process_hint_received) | ||
141 | client.accessible_locations_updated.connect(_on_accessible_locations_updated) | ||
142 | client.checked_locations_updated.connect(_on_checked_locations_updated) | ||
143 | client.checked_worldports_updated.connect(_on_checked_worldports_updated) | ||
144 | |||
145 | client.could_not_connect.connect(_client_could_not_connect) | ||
146 | client.connect_status.connect(_client_connect_status) | ||
147 | client.client_connected.connect(_client_connected) | ||
148 | |||
149 | add_child(client) | ||
150 | |||
151 | keyboard = SCRIPT_keyboard.new() | ||
152 | add_child(keyboard) | ||
153 | client.keyboard_update_received.connect(keyboard.remote_keyboard_updated) | ||
154 | |||
155 | |||
156 | func saveSettings(): | ||
157 | # Save the AP settings to disk. | ||
158 | var path = "user://ap_settings" | ||
159 | var file = FileAccess.open(path, FileAccess.WRITE) | ||
160 | |||
161 | var data = [ | ||
162 | ap_server, | ||
163 | ap_user, | ||
164 | ap_pass, | ||
165 | connection_history, | ||
166 | show_compass, | ||
167 | show_locations, | ||
168 | show_minimap, | ||
169 | ] | ||
170 | file.store_var(data, true) | ||
171 | file.close() | ||
172 | |||
173 | |||
174 | func saveLocaldata(): | ||
175 | # Save the MW/slot specific settings to disk. | ||
176 | var dir = DirAccess.open("user://") | ||
177 | var folder = "archipelago_data" | ||
178 | if not dir.dir_exists(folder): | ||
179 | dir.make_dir(folder) | ||
180 | |||
181 | var file = FileAccess.open(_localdata_file, FileAccess.WRITE) | ||
182 | |||
183 | var data = [ | ||
184 | _last_new_item, | ||
185 | ] | ||
186 | file.store_var(data, true) | ||
187 | file.close() | ||
188 | |||
189 | |||
190 | func connectToServer(): | ||
191 | _last_new_item = -1 | ||
192 | _batch_locations = false | ||
193 | _held_locations = [] | ||
194 | _held_location_scouts = [] | ||
195 | _location_scouts = {} | ||
196 | _letters_setup = false | ||
197 | _held_letters = {} | ||
198 | _already_connected = false | ||
199 | |||
200 | client.connectToServer(ap_server, ap_user, ap_pass) | ||
201 | |||
202 | |||
203 | func getSaveFileName(): | ||
204 | return "zzAP_%s_%d" % [client._seed, client._slot] | ||
205 | |||
206 | |||
207 | func disconnect_from_ap(): | ||
208 | _already_connected = false | ||
209 | |||
210 | var effects = global.get_node("Effects") | ||
211 | effects.set_connection_lost(false) | ||
212 | |||
213 | client.disconnect_from_ap() | ||
214 | |||
215 | |||
216 | func get_item_id_for_door(door_id): | ||
217 | return _item_locks.get(door_id, null) | ||
218 | |||
219 | |||
220 | func _process_item(item, amount): | ||
221 | var gamedata = global.get_node("Gamedata") | ||
222 | |||
223 | var item_id = int(item["id"]) | ||
224 | var prog_id = null | ||
225 | if _inverse_item_locks.has(item_id): | ||
226 | for lock in _inverse_item_locks.get(item_id): | ||
227 | if lock[1] != amount: | ||
228 | continue | ||
229 | |||
230 | if gamedata.progressive_id_by_ap_id.has(item_id): | ||
231 | prog_id = lock[0] | ||
232 | |||
233 | if gamedata.get_door_map_name(lock[0]) != global.map: | ||
234 | continue | ||
235 | |||
236 | # TODO: fix doors opening from door groups | ||
237 | var receivers = gamedata.get_door_receivers(lock[0]) | ||
238 | var scene = get_tree().get_root().get_node_or_null("scene") | ||
239 | if scene != null: | ||
240 | for receiver in receivers: | ||
241 | var rnode = scene.get_node_or_null(receiver) | ||
242 | if rnode != null: | ||
243 | rnode.handleTriggered() | ||
244 | |||
245 | var letter_id = gamedata.letter_id_by_ap_id.get(item_id, null) | ||
246 | if letter_id != null: | ||
247 | var letter = gamedata.objects.get_letters()[letter_id] | ||
248 | if not letter.has_level2() or not letter.get_level2(): | ||
249 | _process_key_item(letter.get_key(), amount) | ||
250 | |||
251 | if gamedata.symbol_item_ids.has(item_id): | ||
252 | var player = get_tree().get_root().get_node_or_null("scene/player") | ||
253 | if player != null: | ||
254 | player.evaluate_solvability.emit() | ||
255 | |||
256 | if item_id == gamedata.objects.get_special_ids()["A Job Well Done"]: | ||
257 | update_job_well_done_sign() | ||
258 | |||
259 | # Show a message about the item if it's new. | ||
260 | if int(item["index"]) > _last_new_item: | ||
261 | _last_new_item = int(item["index"]) | ||
262 | saveLocaldata() | ||
263 | |||
264 | var full_item_name = item["text"] | ||
265 | if prog_id != null: | ||
266 | var door = gamedata.objects.get_doors()[prog_id] | ||
267 | full_item_name = "%s (%s)" % [full_item_name, door.get_name()] | ||
268 | |||
269 | var message | ||
270 | if "sender" in item: | ||
271 | message = ( | ||
272 | "Received %s from %s" | ||
273 | % [wrapInItemColorTags(full_item_name, item["flags"]), item["sender"]] | ||
274 | ) | ||
275 | else: | ||
276 | message = "Found %s" % wrapInItemColorTags(full_item_name, item["flags"]) | ||
277 | |||
278 | if gamedata.anti_trap_ids.has(item): | ||
279 | keyboard.block_letter(gamedata.anti_trap_ids[item]) | ||
280 | |||
281 | global._print(message) | ||
282 | |||
283 | global.get_node("Messages").showMessage(message) | ||
284 | |||
285 | |||
286 | func _process_item_sent_notification(message): | ||
287 | var sentMsg = ( | ||
288 | "Sent %s to %s" | ||
289 | % [ | ||
290 | wrapInItemColorTags(message["item_name"], message["item_flags"]), | ||
291 | message["receiver_name"] | ||
292 | ] | ||
293 | ) | ||
294 | #if _hinted_locations.has(message["item"]["location"]): | ||
295 | # sentMsg += " ([color=#fafad2]Hinted![/color])" | ||
296 | global.get_node("Messages").showMessage(sentMsg) | ||
297 | |||
298 | |||
299 | func _process_hint_received(message): | ||
300 | var is_for = "" | ||
301 | if message["self"] == 0: | ||
302 | is_for = " for %s" % message["receiver_name"] | ||
303 | |||
304 | global.get_node("Messages").showMessage( | ||
305 | ( | ||
306 | "Hint: %s%s is on %s" | ||
307 | % [ | ||
308 | wrapInItemColorTags(message["item_name"], message["item_flags"]), | ||
309 | is_for, | ||
310 | message["location_name"] | ||
311 | ] | ||
312 | ) | ||
313 | ) | ||
314 | |||
315 | |||
316 | func _process_text_message(message): | ||
317 | var parts = [] | ||
318 | for message_part in message: | ||
319 | if message_part["type"] == "text": | ||
320 | parts.append(message_part["text"]) | ||
321 | elif message_part["type"] == "player": | ||
322 | if message_part["self"] == 1: | ||
323 | parts.append("[color=#ee00ee]%s[/color]" % message_part["text"]) | ||
324 | else: | ||
325 | parts.append("[color=#fafad2]%s[/color]" % message_part["text"]) | ||
326 | elif message_part["type"] == "item": | ||
327 | parts.append(wrapInItemColorTags(message_part["text"], int(message_part["flags"]))) | ||
328 | elif message_part["type"] == "location": | ||
329 | parts.append("[color=#00ff7f]%s[/color]" % message_part["text"]) | ||
330 | |||
331 | var textclient_node = global.get_node("Textclient") | ||
332 | if textclient_node != null: | ||
333 | textclient_node.parse_printjson("".join(parts)) | ||
334 | |||
335 | |||
336 | func _process_location_scout(location_id, item_name, player_name, flags, for_self): | ||
337 | _location_scouts[location_id] = { | ||
338 | "item": item_name, "player": player_name, "flags": flags, "for_self": for_self | ||
339 | } | ||
340 | |||
341 | if for_self and flags & 4 != 0: | ||
342 | # This is a trap for us, so let's not display it. | ||
343 | return | ||
344 | |||
345 | var gamedata = global.get_node("Gamedata") | ||
346 | var map_id = gamedata.map_id_by_name.get(global.map) | ||
347 | |||
348 | var letter_id = gamedata.letter_id_by_ap_id.get(location_id, null) | ||
349 | if letter_id != null: | ||
350 | var letter = gamedata.objects.get_letters()[letter_id] | ||
351 | var room = gamedata.objects.get_rooms()[letter.get_room_id()] | ||
352 | if room.get_map_id() == map_id: | ||
353 | var collectable = get_tree().get_root().get_node("scene").get_node_or_null( | ||
354 | letter.get_path() | ||
355 | ) | ||
356 | if collectable != null: | ||
357 | collectable.setScoutedText(item_name) | ||
358 | |||
359 | |||
360 | func _on_accessible_locations_updated(): | ||
361 | var textclient_node = global.get_node("Textclient") | ||
362 | if textclient_node != null: | ||
363 | textclient_node.update_locations() | ||
364 | |||
365 | |||
366 | func _on_checked_locations_updated(): | ||
367 | var textclient_node = global.get_node("Textclient") | ||
368 | if textclient_node != null: | ||
369 | textclient_node.update_locations(false) | ||
370 | |||
371 | |||
372 | func _on_checked_worldports_updated(): | ||
373 | var textclient_node = global.get_node("Textclient") | ||
374 | if textclient_node != null: | ||
375 | textclient_node.update_locations() | ||
376 | textclient_node.update_worldports() | ||
377 | |||
378 | |||
379 | func _client_could_not_connect(message): | ||
380 | could_not_connect.emit(message) | ||
381 | |||
382 | if global.loaded: | ||
383 | var effects = global.get_node("Effects") | ||
384 | effects.set_connection_lost(true) | ||
385 | |||
386 | var messages = global.get_node("Messages") | ||
387 | messages.showMessage("Connection to multiworld lost.") | ||
388 | |||
389 | |||
390 | func _client_connect_status(message): | ||
391 | connect_status.emit(message) | ||
392 | |||
393 | |||
394 | func _client_connected(slot_data): | ||
395 | var effects = global.get_node("Effects") | ||
396 | effects.set_connection_lost(false) | ||
397 | |||
398 | if _already_connected: | ||
399 | var messages = global.get_node("Messages") | ||
400 | messages.showMessage("Reconnected to multiworld!") | ||
401 | return | ||
402 | |||
403 | _already_connected = true | ||
404 | |||
405 | var gamedata = global.get_node("Gamedata") | ||
406 | |||
407 | _localdata_file = "user://archipelago_data/%s_%d" % [client._seed, client._slot] | ||
408 | _last_new_item = -1 | ||
409 | |||
410 | if FileAccess.file_exists(_localdata_file): | ||
411 | var ap_file = FileAccess.open(_localdata_file, FileAccess.READ) | ||
412 | var localdata = [] | ||
413 | if ap_file != null: | ||
414 | localdata = ap_file.get_var(true) | ||
415 | ap_file.close() | ||
416 | |||
417 | if typeof(localdata) != TYPE_ARRAY: | ||
418 | print("AP localdata file is corrupted") | ||
419 | localdata = [] | ||
420 | |||
421 | if localdata.size() > 0: | ||
422 | _last_new_item = localdata[0] | ||
423 | |||
424 | # Read slot data. | ||
425 | cyan_door_behavior = int(slot_data.get("cyan_door_behavior", 0)) | ||
426 | daedalus_roof_access = bool(slot_data.get("daedalus_roof_access", false)) | ||
427 | keyholder_sanity = bool(slot_data.get("keyholder_sanity", false)) | ||
428 | shuffle_control_center_colors = bool(slot_data.get("shuffle_control_center_colors", false)) | ||
429 | shuffle_doors = bool(slot_data.get("shuffle_doors", false)) | ||
430 | shuffle_gallery_paintings = bool(slot_data.get("shuffle_gallery_paintings", false)) | ||
431 | shuffle_letters = int(slot_data.get("shuffle_letters", 0)) | ||
432 | shuffle_symbols = bool(slot_data.get("shuffle_symbols", false)) | ||
433 | shuffle_worldports = bool(slot_data.get("shuffle_worldports", false)) | ||
434 | strict_cyan_ending = bool(slot_data.get("strict_cyan_ending", false)) | ||
435 | strict_purple_ending = bool(slot_data.get("strict_purple_ending", false)) | ||
436 | victory_condition = int(slot_data.get("victory_condition", 0)) | ||
437 | |||
438 | if slot_data.has("version"): | ||
439 | var version_msg = slot_data["version"] | ||
440 | apworld_version = [int(version_msg[0]), int(version_msg[1]), 0] | ||
441 | if version_msg.size() > 2: | ||
442 | apworld_version[2] = int(version_msg[2]) | ||
443 | |||
444 | port_pairings.clear() | ||
445 | if slot_data.has("port_pairings"): | ||
446 | var raw_pp = slot_data.get("port_pairings") | ||
447 | |||
448 | for p1 in raw_pp.keys(): | ||
449 | port_pairings[int(p1)] = int(raw_pp[p1]) | ||
450 | |||
451 | # Set up item locks. | ||
452 | _item_locks = {} | ||
453 | |||
454 | if shuffle_doors: | ||
455 | for door in gamedata.objects.get_doors(): | ||
456 | if ( | ||
457 | door.get_type() == gamedata.SCRIPT_proto.DoorType.STANDARD | ||
458 | or door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY | ||
459 | ): | ||
460 | _item_locks[door.get_id()] = [door.get_ap_id(), 1] | ||
461 | |||
462 | for progressive in gamedata.objects.get_progressives(): | ||
463 | for i in range(0, progressive.get_doors().size()): | ||
464 | var door = gamedata.objects.get_doors()[progressive.get_doors()[i]] | ||
465 | _item_locks[door.get_id()] = [progressive.get_ap_id(), i + 1] | ||
466 | |||
467 | for door_group in gamedata.objects.get_door_groups(): | ||
468 | if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CONNECTOR: | ||
469 | if shuffle_worldports: | ||
470 | continue | ||
471 | elif door_group.get_type() != gamedata.SCRIPT_proto.DoorGroupType.SHUFFLE_GROUP: | ||
472 | continue | ||
473 | |||
474 | for door in door_group.get_doors(): | ||
475 | _item_locks[door] = [door_group.get_ap_id(), 1] | ||
476 | |||
477 | if shuffle_control_center_colors: | ||
478 | for door in gamedata.objects.get_doors(): | ||
479 | if door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR: | ||
480 | _item_locks[door.get_id()] = [door.get_ap_id(), 1] | ||
481 | |||
482 | for door_group in gamedata.objects.get_door_groups(): | ||
483 | if ( | ||
484 | door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.COLOR_CONNECTOR | ||
485 | and not shuffle_worldports | ||
486 | ): | ||
487 | for door in door_group.get_doors(): | ||
488 | _item_locks[door] = [door_group.get_ap_id(), 1] | ||
489 | |||
490 | if shuffle_gallery_paintings: | ||
491 | for door in gamedata.objects.get_doors(): | ||
492 | if door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING: | ||
493 | _item_locks[door.get_id()] = [door.get_ap_id(), 1] | ||
494 | |||
495 | if cyan_door_behavior == kCYAN_DOOR_BEHAVIOR_ITEM: | ||
496 | for door_group in gamedata.objects.get_door_groups(): | ||
497 | if door_group.get_type() == gamedata.SCRIPT_proto.DoorGroupType.CYAN_DOORS: | ||
498 | for door in door_group.get_doors(): | ||
499 | if not _item_locks.has(door): | ||
500 | _item_locks[door] = [door_group.get_ap_id(), 1] | ||
501 | |||
502 | # Create a reverse item locks map for processing items. | ||
503 | _inverse_item_locks = {} | ||
504 | |||
505 | for door_id in _item_locks.keys(): | ||
506 | var lock = _item_locks.get(door_id) | ||
507 | |||
508 | if not _inverse_item_locks.has(lock[0]): | ||
509 | _inverse_item_locks[lock[0]] = [] | ||
510 | |||
511 | _inverse_item_locks[lock[0]].append([door_id, lock[1]]) | ||
512 | |||
513 | if shuffle_worldports: | ||
514 | var textclient = global.get_node("Textclient") | ||
515 | textclient.setup_worldports() | ||
516 | |||
517 | ap_connected.emit() | ||
518 | |||
519 | |||
520 | func start_batching_locations(): | ||
521 | _batch_locations = true | ||
522 | |||
523 | |||
524 | func send_location(loc_id): | ||
525 | if client._checked_locations.has(loc_id): | ||
526 | return | ||
527 | |||
528 | if _batch_locations: | ||
529 | _held_locations.append(loc_id) | ||
530 | else: | ||
531 | client.sendLocation(loc_id) | ||
532 | |||
533 | |||
534 | func scout_location(loc_id): | ||
535 | if _location_scouts.has(loc_id): | ||
536 | return _location_scouts.get(loc_id) | ||
537 | |||
538 | if _batch_locations: | ||
539 | _held_location_scouts.append(loc_id) | ||
540 | else: | ||
541 | client.scoutLocation(loc_id) | ||
542 | |||
543 | return null | ||
544 | |||
545 | |||
546 | func stop_batching_locations(): | ||
547 | _batch_locations = false | ||
548 | |||
549 | if not _held_locations.is_empty(): | ||
550 | client.sendLocations(_held_locations) | ||
551 | _held_locations.clear() | ||
552 | |||
553 | if not _held_location_scouts.is_empty(): | ||
554 | client.scoutLocations(_held_location_scouts) | ||
555 | _held_location_scouts.clear() | ||
556 | |||
557 | |||
558 | func colorForItemType(flags): | ||
559 | var int_flags = int(flags) | ||
560 | if int_flags & 1: # progression | ||
561 | if int_flags & 2: # proguseful | ||
562 | return "#f0d200" | ||
563 | else: | ||
564 | return "#bc51e0" | ||
565 | elif int_flags & 2: # useful | ||
566 | return "#2b67ff" | ||
567 | elif int_flags & 4: # trap | ||
568 | return "#d63a22" | ||
569 | else: # filler | ||
570 | return "#14de9e" | ||
571 | |||
572 | |||
573 | func wrapInItemColorTags(text, flags): | ||
574 | var int_flags = int(flags) | ||
575 | if int_flags & 1 and int_flags & 2: # proguseful | ||
576 | return "[rainbow]%s[/rainbow]" % text | ||
577 | else: | ||
578 | return "[color=%s]%s[/color]" % [colorForItemType(flags), text] | ||
579 | |||
580 | |||
581 | func get_letter_behavior(key, level2): | ||
582 | if shuffle_letters == kSHUFFLE_LETTERS_UNLOCKED: | ||
583 | return kLETTER_BEHAVIOR_UNLOCKED | ||
584 | |||
585 | if [kSHUFFLE_LETTERS_VANILLA_CYAN, kSHUFFLE_LETTERS_ITEM_CYAN].has(shuffle_letters): | ||
586 | if level2: | ||
587 | if shuffle_letters == kSHUFFLE_LETTERS_VANILLA_CYAN: | ||
588 | return kLETTER_BEHAVIOR_VANILLA | ||
589 | else: | ||
590 | return kLETTER_BEHAVIOR_ITEM | ||
591 | else: | ||
592 | return kLETTER_BEHAVIOR_UNLOCKED | ||
593 | |||
594 | if not level2 and ["h", "i", "n", "t"].has(key): | ||
595 | # This differs from the equivalent function in the apworld. Logically it is | ||
596 | # the same as UNLOCKED since they are in the starting room, but VANILLA | ||
597 | # means the player still has to actually pick up the letters. | ||
598 | return kLETTER_BEHAVIOR_VANILLA | ||
599 | |||
600 | if shuffle_letters == kSHUFFLE_LETTERS_PROGRESSIVE: | ||
601 | return kLETTER_BEHAVIOR_ITEM | ||
602 | |||
603 | return kLETTER_BEHAVIOR_VANILLA | ||
604 | |||
605 | |||
606 | func setup_keys(): | ||
607 | keyboard.load_seed() | ||
608 | |||
609 | _letters_setup = true | ||
610 | |||
611 | for k in _held_letters.keys(): | ||
612 | _process_key_item(k, _held_letters[k]) | ||
613 | |||
614 | _held_letters.clear() | ||
615 | |||
616 | |||
617 | func _process_key_item(key, level): | ||
618 | if not _letters_setup: | ||
619 | _held_letters[key] = max(_held_letters.get(key, 0), level) | ||
620 | return | ||
621 | |||
622 | if shuffle_letters == kSHUFFLE_LETTERS_ITEM_CYAN: | ||
623 | level += 1 | ||
624 | |||
625 | keyboard.collect_remote_letter(key, level) | ||
626 | |||
627 | |||
628 | func update_job_well_done_sign(): | ||
629 | if global.map != "daedalus": | ||
630 | return | ||
631 | |||
632 | var gamedata = global.get_node("Gamedata") | ||
633 | var job_item = gamedata.objects.get_special_ids()["A Job Well Done"] | ||
634 | var jobs_done = client.getItemAmount(job_item) | ||
635 | |||
636 | var sign2 = get_tree().get_root().get_node_or_null("scene/Meshes/Miscellaneous/sign2") | ||
637 | var sign3 = get_tree().get_root().get_node_or_null("scene/Meshes/Miscellaneous/sign3") | ||
638 | |||
639 | if sign2 != null and sign3 != null: | ||
640 | if jobs_done == 0: | ||
641 | sign2.text = "what are you doing" | ||
642 | sign3.text = "?" | ||
643 | elif jobs_done == 1: | ||
644 | sign2.text = "a job well done" | ||
645 | sign3.text = "is its own reward" | ||
646 | else: | ||
647 | sign2.text = "%d jobs well done" % jobs_done | ||
648 | sign3.text = "are their own reward" | ||
649 | |||
650 | sign2.get_node("MeshInstance3D").mesh.text = sign2.text | ||
651 | sign3.get_node("MeshInstance3D").mesh.text = sign3.text | ||
diff --git a/apworld/client/messages.gd b/apworld/client/messages.gd new file mode 100644 index 0000000..ab4f071 --- /dev/null +++ b/apworld/client/messages.gd | |||
@@ -0,0 +1,74 @@ | |||
1 | extends CanvasLayer | ||
2 | |||
3 | var SCRIPT_rainbowText | ||
4 | |||
5 | var _message_queue = [] | ||
6 | var _font | ||
7 | var _container | ||
8 | var _ordered_labels = [] | ||
9 | |||
10 | |||
11 | func _ready(): | ||
12 | _container = VBoxContainer.new() | ||
13 | _container.set_name("Container") | ||
14 | _container.anchor_bottom = 1 | ||
15 | _container.offset_left = 20.0 | ||
16 | _container.offset_right = 1920.0 | ||
17 | _container.offset_top = 0.0 | ||
18 | _container.offset_bottom = -20.0 | ||
19 | _container.alignment = BoxContainer.ALIGNMENT_END | ||
20 | _container.mouse_filter = Control.MOUSE_FILTER_IGNORE | ||
21 | self.add_child(_container) | ||
22 | |||
23 | _font = load("res://assets/fonts/Lingo2.ttf") | ||
24 | |||
25 | |||
26 | func _add_message(text): | ||
27 | var new_label = RichTextLabel.new() | ||
28 | new_label.install_effect(SCRIPT_rainbowText.new()) | ||
29 | new_label.push_font(_font) | ||
30 | new_label.push_font_size(36) | ||
31 | new_label.push_outline_color(Color(0, 0, 0, 1)) | ||
32 | new_label.push_outline_size(2) | ||
33 | new_label.append_text(text) | ||
34 | new_label.fit_content = true | ||
35 | |||
36 | _container.add_child(new_label) | ||
37 | _ordered_labels.push_back(new_label) | ||
38 | |||
39 | |||
40 | func showMessage(text): | ||
41 | if _ordered_labels.size() >= 9: | ||
42 | _message_queue.append(text) | ||
43 | return | ||
44 | |||
45 | _add_message(text) | ||
46 | |||
47 | if _ordered_labels.size() > 1: | ||
48 | return | ||
49 | |||
50 | var timeout = 10.0 | ||
51 | while !_ordered_labels.is_empty(): | ||
52 | await get_tree().create_timer(timeout).timeout | ||
53 | |||
54 | if !_ordered_labels.is_empty(): | ||
55 | var to_remove = _ordered_labels.pop_front() | ||
56 | var to_tween = get_tree().create_tween().bind_node(to_remove) | ||
57 | to_tween.tween_property(to_remove, "modulate:a", 0.0, 0.5) | ||
58 | to_tween.tween_callback(to_remove.queue_free) | ||
59 | |||
60 | if !_message_queue.is_empty(): | ||
61 | var next_msg = _message_queue.pop_front() | ||
62 | _add_message(next_msg) | ||
63 | |||
64 | if timeout > 4: | ||
65 | timeout -= 3 | ||
66 | |||
67 | |||
68 | func clear(): | ||
69 | _message_queue.clear() | ||
70 | |||
71 | for message_label in _ordered_labels: | ||
72 | message_label.queue_free() | ||
73 | |||
74 | _ordered_labels.clear() | ||
diff --git a/apworld/client/minimap.gd b/apworld/client/minimap.gd new file mode 100644 index 0000000..bf70114 --- /dev/null +++ b/apworld/client/minimap.gd | |||
@@ -0,0 +1,178 @@ | |||
1 | extends CanvasLayer | ||
2 | |||
3 | var player | ||
4 | var drawer | ||
5 | var sprite | ||
6 | var label | ||
7 | |||
8 | var cell_left | ||
9 | var cell_top | ||
10 | var cell_right | ||
11 | var cell_bottom | ||
12 | var cell_width | ||
13 | var cell_height | ||
14 | var center_x_min | ||
15 | var center_x_max | ||
16 | var center_y_min | ||
17 | var center_y_max | ||
18 | |||
19 | |||
20 | func _ready(): | ||
21 | player = get_tree().get_root().get_node("scene/player") | ||
22 | |||
23 | var svc = PanelContainer.new() | ||
24 | svc.anchor_left = 1.0 | ||
25 | svc.anchor_top = 1.0 | ||
26 | svc.anchor_right = 1.0 | ||
27 | svc.anchor_bottom = 1.0 | ||
28 | svc.offset_left = -320.0 | ||
29 | svc.offset_top = -320.0 | ||
30 | svc.offset_right = -64.0 | ||
31 | svc.offset_bottom = -64.0 | ||
32 | svc.clip_contents = true | ||
33 | add_child(svc) | ||
34 | |||
35 | var background_color = Color.WHITE | ||
36 | |||
37 | var world_env = get_tree().get_root().get_node("scene/WorldEnvironment") | ||
38 | if world_env != null and world_env.environment != null: | ||
39 | if world_env.environment.background_mode == Environment.BG_COLOR: | ||
40 | background_color = world_env.environment.background_color | ||
41 | elif ( | ||
42 | world_env.environment.background_mode == Environment.BG_SKY | ||
43 | and world_env.environment.sky != null | ||
44 | and world_env.environment.sky.sky_material != null | ||
45 | ): | ||
46 | var sky = world_env.environment.sky.sky_material | ||
47 | if sky is PhysicalSkyMaterial: | ||
48 | background_color = sky.ground_color | ||
49 | elif sky is ProceduralSkyMaterial: | ||
50 | background_color = sky.sky_top_color | ||
51 | |||
52 | var stylebox = StyleBoxFlat.new() | ||
53 | stylebox.bg_color = Color(background_color, 0.6) | ||
54 | svc.add_theme_stylebox_override("panel", stylebox) | ||
55 | |||
56 | drawer = Node2D.new() | ||
57 | svc.add_child(drawer) | ||
58 | |||
59 | var gridmap = get_tree().get_root().get_node("scene/GridMap") | ||
60 | if gridmap == null: | ||
61 | visible = false | ||
62 | return | ||
63 | |||
64 | cell_left = 0 | ||
65 | cell_top = 0 | ||
66 | cell_right = 0 | ||
67 | cell_bottom = 0 | ||
68 | |||
69 | for pos in gridmap.get_used_cells(): | ||
70 | if pos.x < cell_left: | ||
71 | cell_left = pos.x | ||
72 | if pos.x > cell_right: | ||
73 | cell_right = pos.x | ||
74 | if pos.z < cell_top: | ||
75 | cell_top = pos.z | ||
76 | if pos.z > cell_bottom: | ||
77 | cell_bottom = pos.z | ||
78 | |||
79 | cell_width = cell_right - cell_left + 1 | ||
80 | cell_height = cell_bottom - cell_top + 1 | ||
81 | |||
82 | var rendered = _renderMap(gridmap) | ||
83 | |||
84 | var image_texture = ImageTexture.create_from_image(rendered) | ||
85 | sprite = Sprite2D.new() | ||
86 | sprite.texture = image_texture | ||
87 | sprite.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST | ||
88 | sprite.scale = Vector2(2, 2) | ||
89 | sprite.centered = false | ||
90 | drawer.add_child(sprite) | ||
91 | |||
92 | label = Label.new() | ||
93 | label.theme = preload("res://assets/themes/baseUI.tres") | ||
94 | label.add_theme_font_size_override("font_size", 32) | ||
95 | label.text = "@" | ||
96 | drawer.add_child(label) | ||
97 | |||
98 | #var local_tl = gridmap.map_to_local(Vector3i(cell_left, 0, cell_top)) | ||
99 | #var global_tl = gridmap.to_global(local_tl) | ||
100 | #var local_br = gridmap.map_to_local(Vector3i(cell_right, 0, cell_bottom)) | ||
101 | #var global_br = gridmap.to_global(local_br) | ||
102 | |||
103 | center_x_min = 0 | ||
104 | center_x_max = cell_width - 128 | ||
105 | center_y_min = 0 | ||
106 | center_y_max = cell_height - 128 | ||
107 | |||
108 | if center_x_max < center_x_min: | ||
109 | center_x_min = (center_x_min + center_x_max) / 2 | ||
110 | center_x_max = center_x_min | ||
111 | |||
112 | if center_y_max < center_y_min: | ||
113 | center_y_min = (center_y_min + center_y_max) / 2 | ||
114 | center_y_max = center_y_min | ||
115 | |||
116 | |||
117 | func _process(_delta): | ||
118 | if visible == false: | ||
119 | return | ||
120 | |||
121 | drawer.position.x = clamp(player.position.x - cell_left - 64, center_x_min, center_x_max) * -2 | ||
122 | drawer.position.y = clamp(player.position.z - cell_top - 64, center_y_min, center_y_max) * -2 | ||
123 | |||
124 | label.position.x = (player.position.x - cell_left) * 2 - 16 | ||
125 | label.position.y = (player.position.z - cell_top) * 2 - 16 | ||
126 | |||
127 | |||
128 | func _renderMap(gridmap): | ||
129 | var ap = global.get_node("Archipelago") | ||
130 | var heights = {} | ||
131 | |||
132 | var rendered = Image.create_empty(cell_width, cell_height, false, Image.FORMAT_RGBA8) | ||
133 | rendered.fill(Color.TRANSPARENT) | ||
134 | |||
135 | var meshes_node = get_tree().get_root().get_node("scene/Meshes") | ||
136 | if meshes_node != null: | ||
137 | _renderMeshNode(ap, gridmap, meshes_node, rendered) | ||
138 | |||
139 | for pos in gridmap.get_used_cells(): | ||
140 | var in_plane = Vector2i(pos.x, pos.z) | ||
141 | |||
142 | if in_plane in heights and heights[in_plane] > pos.y: | ||
143 | continue | ||
144 | |||
145 | heights[in_plane] = pos.y | ||
146 | |||
147 | var cell_item = gridmap.get_cell_item(pos) | ||
148 | var mesh = gridmap.mesh_library.get_item_mesh(cell_item) | ||
149 | var material = mesh.surface_get_material(0) | ||
150 | var color = ap.color_by_material_path.get(material.resource_path, Color.TRANSPARENT) | ||
151 | |||
152 | rendered.set_pixel(pos.x - cell_left, pos.z - cell_top, color) | ||
153 | |||
154 | return rendered | ||
155 | |||
156 | |||
157 | func _renderMeshNode(ap, gridmap, mesh, rendered): | ||
158 | if mesh is MeshInstance3D: | ||
159 | var local_tl = gridmap.map_to_local(Vector3i(cell_left, 0, cell_top)) | ||
160 | var global_tl = gridmap.to_global(local_tl) | ||
161 | var mesh_material = mesh.get_surface_override_material(0) | ||
162 | if mesh_material != null: | ||
163 | var mesh_color = ap.color_by_material_path.get( | ||
164 | mesh_material.resource_path, Color.TRANSPARENT | ||
165 | ) | ||
166 | |||
167 | for y in range( | ||
168 | max(mesh.position.z - mesh.scale.z / 2 - global_tl.z, 0), | ||
169 | min(mesh.position.z + mesh.scale.z / 2 - global_tl.z, cell_height) | ||
170 | ): | ||
171 | for x in range( | ||
172 | max(mesh.position.x - mesh.scale.x / 2 - global_tl.x, 0), | ||
173 | min(mesh.position.x + mesh.scale.x / 2 - global_tl.x, cell_width) | ||
174 | ): | ||
175 | rendered.set_pixel(x, y, mesh_color) | ||
176 | |||
177 | for child in mesh.get_children(): | ||
178 | _renderMeshNode(ap, gridmap, child, rendered) | ||
diff --git a/apworld/client/painting.gd b/apworld/client/painting.gd new file mode 100644 index 0000000..276d4eb --- /dev/null +++ b/apworld/client/painting.gd | |||
@@ -0,0 +1,38 @@ | |||
1 | extends "res://scripts/nodes/painting.gd" | ||
2 | |||
3 | var item_id | ||
4 | var item_amount | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var node_path = String( | ||
9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
10 | ) | ||
11 | |||
12 | var gamedata = global.get_node("Gamedata") | ||
13 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | ||
14 | if door_id != null: | ||
15 | var ap = global.get_node("Archipelago") | ||
16 | var item_lock = ap.get_item_id_for_door(door_id) | ||
17 | |||
18 | if item_lock != null: | ||
19 | item_id = item_lock[0] | ||
20 | item_amount = item_lock[1] | ||
21 | |||
22 | self.senders = [] | ||
23 | self.senderGroup = [] | ||
24 | self.nested = false | ||
25 | self.complete_at = 0 | ||
26 | self.max_length = 0 | ||
27 | self.excludeSenders = [] | ||
28 | |||
29 | call_deferred("_readier") | ||
30 | |||
31 | super._ready() | ||
32 | |||
33 | |||
34 | func _readier(): | ||
35 | var ap = global.get_node("Archipelago") | ||
36 | |||
37 | if ap.client.getItemAmount(item_id) >= item_amount: | ||
38 | handleTriggered() | ||
diff --git a/apworld/client/panel.gd b/apworld/client/panel.gd new file mode 100644 index 0000000..2cef28e --- /dev/null +++ b/apworld/client/panel.gd | |||
@@ -0,0 +1,101 @@ | |||
1 | extends "res://scripts/nodes/panel.gd" | ||
2 | |||
3 | var panel_logic = null | ||
4 | var symbol_solvable = true | ||
5 | |||
6 | var black = load("res://assets/materials/black.material") | ||
7 | |||
8 | |||
9 | func _ready(): | ||
10 | super._ready() | ||
11 | |||
12 | var node_path = String( | ||
13 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
14 | ) | ||
15 | |||
16 | var gamedata = global.get_node("Gamedata") | ||
17 | var panel_id = gamedata.get_panel_for_map_node_path(global.map, node_path) | ||
18 | if panel_id != null: | ||
19 | var ap = global.get_node("Archipelago") | ||
20 | if ap.shuffle_symbols: | ||
21 | if global.map == "the_entry" and node_path == "Panels/Entry/front_1": | ||
22 | clue = "i" | ||
23 | symbol = "" | ||
24 | |||
25 | setField("clue", clue) | ||
26 | setField("symbol", symbol) | ||
27 | |||
28 | panel_logic = gamedata.objects.get_panels()[panel_id] | ||
29 | checkSymbolSolvable() | ||
30 | |||
31 | if not symbol_solvable: | ||
32 | get_tree().get_root().get_node("scene/player").evaluate_solvability.connect( | ||
33 | evaluateSolvability | ||
34 | ) | ||
35 | |||
36 | |||
37 | func checkSymbolSolvable(): | ||
38 | var old_solvable = symbol_solvable | ||
39 | symbol_solvable = true | ||
40 | |||
41 | if panel_logic == null: | ||
42 | # There's no logic for this panel. | ||
43 | return | ||
44 | |||
45 | var ap = global.get_node("Archipelago") | ||
46 | if not ap.shuffle_symbols: | ||
47 | # Symbols aren't item-locked. | ||
48 | return | ||
49 | |||
50 | var gamedata = global.get_node("Gamedata") | ||
51 | for symbol in panel_logic.get_symbols(): | ||
52 | var item_name = gamedata.kSYMBOL_ITEMS.get(symbol) | ||
53 | var item_id = gamedata.objects.get_special_ids()[item_name] | ||
54 | if ap.client.getItemAmount(item_id) < 1: | ||
55 | symbol_solvable = false | ||
56 | break | ||
57 | |||
58 | if symbol_solvable != old_solvable: | ||
59 | if symbol_solvable: | ||
60 | setField("clue", clue) | ||
61 | setField("symbol", symbol) | ||
62 | setField("answer", answer) | ||
63 | else: | ||
64 | quad_mesh.surface_set_material(0, black) | ||
65 | get_node("Hinge/clue").text = "missing" | ||
66 | get_node("Hinge/answer").text = "symbols" | ||
67 | |||
68 | |||
69 | func checkSolvable(key): | ||
70 | checkSymbolSolvable() | ||
71 | if not symbol_solvable: | ||
72 | return false | ||
73 | |||
74 | return super.checkSolvable(key) | ||
75 | |||
76 | |||
77 | func evaluateSolvability(): | ||
78 | checkSolvable("") | ||
79 | |||
80 | |||
81 | func passedInput(key, skip_focus_check = false): | ||
82 | if not symbol_solvable: | ||
83 | return | ||
84 | |||
85 | super.passedInput(key, skip_focus_check) | ||
86 | |||
87 | |||
88 | func focus(): | ||
89 | if not symbol_solvable: | ||
90 | has_focus = false | ||
91 | return | ||
92 | |||
93 | super.focus() | ||
94 | |||
95 | |||
96 | func unfocus(): | ||
97 | if not symbol_solvable: | ||
98 | has_focus = false | ||
99 | return | ||
100 | |||
101 | super.unfocus() | ||
diff --git a/apworld/client/pauseMenu.gd b/apworld/client/pauseMenu.gd new file mode 100644 index 0000000..72b45e8 --- /dev/null +++ b/apworld/client/pauseMenu.gd | |||
@@ -0,0 +1,91 @@ | |||
1 | extends "res://scripts/ui/pauseMenu.gd" | ||
2 | |||
3 | var compass_button | ||
4 | var locations_button | ||
5 | var minimap_button | ||
6 | |||
7 | |||
8 | func _ready(): | ||
9 | var ap_panel = Panel.new() | ||
10 | ap_panel.name = "Archipelago" | ||
11 | get_node("menu/settings/settingsInner/TabContainer").add_child(ap_panel) | ||
12 | |||
13 | var ap = global.get_node("Archipelago") | ||
14 | |||
15 | compass_button = CheckBox.new() | ||
16 | compass_button.text = "show compass" | ||
17 | compass_button.button_pressed = ap.show_compass | ||
18 | compass_button.position = Vector2(65, 100) | ||
19 | compass_button.theme = preload("res://assets/themes/baseUI.tres") | ||
20 | compass_button.add_theme_font_size_override("font_size", 60) | ||
21 | compass_button.pressed.connect(_toggle_compass) | ||
22 | ap_panel.add_child(compass_button) | ||
23 | |||
24 | locations_button = CheckBox.new() | ||
25 | locations_button.text = "show locations overlay" | ||
26 | locations_button.button_pressed = ap.show_locations | ||
27 | locations_button.position = Vector2(65, 200) | ||
28 | locations_button.theme = preload("res://assets/themes/baseUI.tres") | ||
29 | locations_button.add_theme_font_size_override("font_size", 60) | ||
30 | locations_button.pressed.connect(_toggle_locations) | ||
31 | ap_panel.add_child(locations_button) | ||
32 | |||
33 | minimap_button = CheckBox.new() | ||
34 | minimap_button.text = "show minimap" | ||
35 | minimap_button.button_pressed = ap.show_minimap | ||
36 | minimap_button.position = Vector2(65, 300) | ||
37 | minimap_button.theme = preload("res://assets/themes/baseUI.tres") | ||
38 | minimap_button.add_theme_font_size_override("font_size", 60) | ||
39 | minimap_button.pressed.connect(_toggle_minimap) | ||
40 | ap_panel.add_child(minimap_button) | ||
41 | |||
42 | super._ready() | ||
43 | |||
44 | |||
45 | func _pause_game(): | ||
46 | global.get_node("Textclient").dismiss() | ||
47 | super._pause_game() | ||
48 | |||
49 | |||
50 | func _main_menu(): | ||
51 | global.loaded = false | ||
52 | global.get_node("Archipelago").disconnect_from_ap() | ||
53 | global.get_node("Messages").clear() | ||
54 | global.get_node("Compass").visible = false | ||
55 | global.get_node("Textclient").reset() | ||
56 | |||
57 | autosplitter.reset() | ||
58 | _unpause_game() | ||
59 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | ||
60 | musicPlayer.stop() | ||
61 | |||
62 | var runtime = global.get_node("Runtime") | ||
63 | runtime.load_script_as_scene.call_deferred("settings_screen.gd", "settings_screen") | ||
64 | |||
65 | |||
66 | func _toggle_compass(): | ||
67 | var ap = global.get_node("Archipelago") | ||
68 | ap.show_compass = compass_button.button_pressed | ||
69 | ap.saveSettings() | ||
70 | |||
71 | var compass = global.get_node("Compass") | ||
72 | compass.visible = compass_button.button_pressed | ||
73 | |||
74 | |||
75 | func _toggle_locations(): | ||
76 | var ap = global.get_node("Archipelago") | ||
77 | ap.show_locations = locations_button.button_pressed | ||
78 | ap.saveSettings() | ||
79 | |||
80 | var textclient = global.get_node("Textclient") | ||
81 | textclient.update_locations_visibility() | ||
82 | |||
83 | |||
84 | func _toggle_minimap(): | ||
85 | var ap = global.get_node("Archipelago") | ||
86 | ap.show_minimap = minimap_button.button_pressed | ||
87 | ap.saveSettings() | ||
88 | |||
89 | var minimap = get_tree().get_root().get_node("scene/Minimap") | ||
90 | if minimap != null: | ||
91 | minimap.visible = ap.show_minimap | ||
diff --git a/apworld/client/player.gd b/apworld/client/player.gd new file mode 100644 index 0000000..b73f61e --- /dev/null +++ b/apworld/client/player.gd | |||
@@ -0,0 +1,349 @@ | |||
1 | extends "res://scripts/nodes/player.gd" | ||
2 | |||
3 | signal evaluate_solvability | ||
4 | |||
5 | var compass | ||
6 | |||
7 | |||
8 | func _ready(): | ||
9 | var khl_script = load("res://scripts/nodes/keyHolderListener.gd") | ||
10 | |||
11 | var pause_menu = get_node("pause_menu") | ||
12 | pause_menu.layer = 3 | ||
13 | |||
14 | var ap = global.get_node("Archipelago") | ||
15 | var gamedata = global.get_node("Gamedata") | ||
16 | |||
17 | compass = global.get_node("Compass") | ||
18 | compass.visible = ap.show_compass | ||
19 | |||
20 | ap.start_batching_locations() | ||
21 | |||
22 | # Set up door locations. | ||
23 | var map_id = gamedata.map_id_by_name.get(global.map) | ||
24 | for door in gamedata.objects.get_doors(): | ||
25 | if door.get_map_id() != map_id: | ||
26 | continue | ||
27 | |||
28 | if not door.has_ap_id(): | ||
29 | continue | ||
30 | |||
31 | if ( | ||
32 | door.get_type() == gamedata.SCRIPT_proto.DoorType.ITEM_ONLY | ||
33 | or door.get_type() == gamedata.SCRIPT_proto.DoorType.GALLERY_PAINTING | ||
34 | or door.get_type() == gamedata.SCRIPT_proto.DoorType.CONTROL_CENTER_COLOR | ||
35 | ): | ||
36 | continue | ||
37 | |||
38 | var locationListener = ap.SCRIPT_locationListener.new() | ||
39 | locationListener.location_id = door.get_ap_id() | ||
40 | locationListener.name = "locationListener_%d" % door.get_ap_id() | ||
41 | |||
42 | for panel_ref in door.get_panels(): | ||
43 | var panel_data = gamedata.objects.get_panels()[panel_ref.get_panel()] | ||
44 | var panel_path = panel_data.get_path() | ||
45 | |||
46 | if panel_ref.has_answer(): | ||
47 | for proxy in panel_data.get_proxies(): | ||
48 | if proxy.get_answer() == panel_ref.get_answer(): | ||
49 | panel_path = proxy.get_path() | ||
50 | break | ||
51 | |||
52 | locationListener.senders.append(NodePath("/root/scene/" + panel_path)) | ||
53 | |||
54 | for keyholder_ref in door.get_keyholders(): | ||
55 | var keyholder_data = gamedata.objects.get_keyholders()[keyholder_ref.get_keyholder()] | ||
56 | |||
57 | var khl = khl_script.new() | ||
58 | khl.name = ( | ||
59 | "location_%d_keyholder_%d" % [door.get_ap_id(), keyholder_ref.get_keyholder()] | ||
60 | ) | ||
61 | khl.answer = keyholder_ref.get_key() | ||
62 | khl.senders.append(NodePath("/root/scene/" + keyholder_data.get_path())) | ||
63 | get_parent().add_child.call_deferred(khl) | ||
64 | |||
65 | locationListener.senders.append(NodePath("../" + khl.name)) | ||
66 | |||
67 | for sender in door.get_senders(): | ||
68 | locationListener.senders.append(NodePath("/root/scene/" + sender)) | ||
69 | |||
70 | if door.has_complete_at(): | ||
71 | locationListener.complete_at = door.get_complete_at() | ||
72 | |||
73 | get_parent().add_child.call_deferred(locationListener) | ||
74 | |||
75 | # Set up letter locations. | ||
76 | for letter in gamedata.objects.get_letters(): | ||
77 | var room = gamedata.objects.get_rooms()[letter.get_room_id()] | ||
78 | if room.get_map_id() != map_id: | ||
79 | continue | ||
80 | |||
81 | var locationListener = ap.SCRIPT_locationListener.new() | ||
82 | locationListener.location_id = letter.get_ap_id() | ||
83 | locationListener.name = "locationListener_%d" % letter.get_ap_id() | ||
84 | locationListener.senders.append(NodePath("/root/scene/" + letter.get_path())) | ||
85 | |||
86 | get_parent().add_child.call_deferred(locationListener) | ||
87 | |||
88 | if ( | ||
89 | ap.get_letter_behavior(letter.get_key(), letter.has_level2() and letter.get_level2()) | ||
90 | != ap.kLETTER_BEHAVIOR_VANILLA | ||
91 | ): | ||
92 | var scout = ap.scout_location(letter.get_ap_id()) | ||
93 | if scout != null and not (scout["for_self"] and scout["flags"] & 4 != 0): | ||
94 | var collectable = get_tree().get_root().get_node("scene").get_node_or_null( | ||
95 | letter.get_path() | ||
96 | ) | ||
97 | if collectable != null: | ||
98 | collectable.setScoutedText.call_deferred(scout["item"]) | ||
99 | |||
100 | # Set up mastery locations. | ||
101 | for mastery in gamedata.objects.get_masteries(): | ||
102 | var room = gamedata.objects.get_rooms()[mastery.get_room_id()] | ||
103 | if room.get_map_id() != map_id: | ||
104 | continue | ||
105 | |||
106 | var locationListener = ap.SCRIPT_locationListener.new() | ||
107 | locationListener.location_id = mastery.get_ap_id() | ||
108 | locationListener.name = "locationListener_%d" % mastery.get_ap_id() | ||
109 | locationListener.senders.append(NodePath("/root/scene/" + mastery.get_path())) | ||
110 | |||
111 | get_parent().add_child.call_deferred(locationListener) | ||
112 | |||
113 | # Set up ending locations. | ||
114 | for ending in gamedata.objects.get_endings(): | ||
115 | var room = gamedata.objects.get_rooms()[ending.get_room_id()] | ||
116 | if room.get_map_id() != map_id: | ||
117 | continue | ||
118 | |||
119 | var locationListener = ap.SCRIPT_locationListener.new() | ||
120 | locationListener.location_id = ending.get_ap_id() | ||
121 | locationListener.name = "locationListener_%d" % ending.get_ap_id() | ||
122 | locationListener.senders.append(NodePath("/root/scene/" + ending.get_path())) | ||
123 | |||
124 | get_parent().add_child.call_deferred(locationListener) | ||
125 | |||
126 | if ap.kEndingNameByVictoryValue.get(ap.victory_condition, null) == ending.get_name(): | ||
127 | var victoryListener = ap.SCRIPT_victoryListener.new() | ||
128 | victoryListener.name = "victoryListener" | ||
129 | victoryListener.senders.append(NodePath("/root/scene/" + ending.get_path())) | ||
130 | |||
131 | get_parent().add_child.call_deferred(victoryListener) | ||
132 | |||
133 | # Set up keyholder locations, in keyholder sanity. | ||
134 | if ap.keyholder_sanity: | ||
135 | for keyholder in gamedata.objects.get_keyholders(): | ||
136 | if not keyholder.has_key(): | ||
137 | continue | ||
138 | |||
139 | var room = gamedata.objects.get_rooms()[keyholder.get_room_id()] | ||
140 | if room.get_map_id() != map_id: | ||
141 | continue | ||
142 | |||
143 | var locationListener = ap.SCRIPT_locationListener.new() | ||
144 | locationListener.location_id = keyholder.get_ap_id() | ||
145 | locationListener.name = "locationListener_%d" % keyholder.get_ap_id() | ||
146 | |||
147 | var khl = khl_script.new() | ||
148 | khl.name = "location_%d_keyholder" % keyholder.get_ap_id() | ||
149 | khl.answer = keyholder.get_key() | ||
150 | khl.senders.append(NodePath("/root/scene/" + keyholder.get_path())) | ||
151 | get_parent().add_child.call_deferred(khl) | ||
152 | |||
153 | locationListener.senders.append(NodePath("../" + khl.name)) | ||
154 | |||
155 | get_parent().add_child.call_deferred(locationListener) | ||
156 | |||
157 | # Block off roof access in Daedalus. | ||
158 | if global.map == "daedalus" and not ap.daedalus_roof_access: | ||
159 | _set_up_invis_wall(75.5, 11, -24.5, 1, 10, 49) | ||
160 | _set_up_invis_wall(51.5, 11, -17, 16, 10, 1) | ||
161 | _set_up_invis_wall(46, 10, -9.5, 1, 10, 10) | ||
162 | _set_up_invis_wall(67.5, 11, 17, 16, 10, 1) | ||
163 | _set_up_invis_wall(50.5, 11, 14, 10, 10, 1) | ||
164 | _set_up_invis_wall(39, 10, 18.5, 1, 10, 22) | ||
165 | _set_up_invis_wall(20, 15, 18.5, 1, 10, 16) | ||
166 | _set_up_invis_wall(11.5, 15, 3, 32, 10, 1) | ||
167 | _set_up_invis_wall(11.5, 16, -20, 14, 20, 1) | ||
168 | _set_up_invis_wall(14, 16, -26.5, 1, 20, 4) | ||
169 | _set_up_invis_wall(28.5, 20.5, -26.5, 1, 15, 25) | ||
170 | _set_up_invis_wall(40.5, 20.5, -11, 30, 15, 1) | ||
171 | _set_up_invis_wall(50.5, 15, 5.5, 7, 10, 1) | ||
172 | _set_up_invis_wall(83.5, 33.5, 5.5, 1, 7, 11) | ||
173 | _set_up_invis_wall(83.5, 33.5, -5.5, 1, 7, 11) | ||
174 | |||
175 | var warp_exit_prefab = preload("res://objects/nodes/exit.tscn") | ||
176 | var warp_exit = warp_exit_prefab.instantiate() | ||
177 | warp_exit.name = "roof_access_blocker_warp_exit" | ||
178 | warp_exit.position = Vector3(58, 10, 0) | ||
179 | warp_exit.rotation_degrees.y = 90 | ||
180 | get_parent().add_child.call_deferred(warp_exit) | ||
181 | |||
182 | var warp_enter_prefab = preload("res://objects/nodes/teleportAuto.tscn") | ||
183 | var warp_enter = warp_enter_prefab.instantiate() | ||
184 | warp_enter.target = warp_exit | ||
185 | warp_enter.position = Vector3(76.5, 30, 1) | ||
186 | warp_enter.scale = Vector3(4, 1.5, 1) | ||
187 | warp_enter.rotation_degrees.y = 90 | ||
188 | get_parent().add_child.call_deferred(warp_enter) | ||
189 | |||
190 | if global.map == "the_entry": | ||
191 | # Remove door behind X1. | ||
192 | var door_node = get_tree().get_root().get_node("/root/scene/Components/Doors/exit_1") | ||
193 | door_node.handleTriggered() | ||
194 | |||
195 | # Display win condition. | ||
196 | var sign_prefab = preload("res://objects/nodes/sign.tscn") | ||
197 | var sign1 = sign_prefab.instantiate() | ||
198 | sign1.position = Vector3(-7, 5, -15.01) | ||
199 | sign1.text = "victory" | ||
200 | get_parent().add_child.call_deferred(sign1) | ||
201 | |||
202 | var sign2 = sign_prefab.instantiate() | ||
203 | sign2.position = Vector3(-7, 4, -15.01) | ||
204 | sign2.text = "%s ending" % ap.kEndingNameByVictoryValue.get(ap.victory_condition, "?") | ||
205 | |||
206 | var sign2_color = ap.kEndingNameByVictoryValue.get(ap.victory_condition, "coral").to_lower() | ||
207 | if sign2_color == "white": | ||
208 | sign2_color = "silver" | ||
209 | |||
210 | sign2.material = load("res://assets/materials/%s.material" % sign2_color) | ||
211 | get_parent().add_child.call_deferred(sign2) | ||
212 | |||
213 | # Add the strict purple ending validation. | ||
214 | if global.map == "the_sun_temple" and ap.strict_purple_ending: | ||
215 | var panel_prefab = preload("res://objects/nodes/panel.tscn") | ||
216 | var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") | ||
217 | var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") | ||
218 | |||
219 | var previous_panel = null | ||
220 | var next_y = -100 | ||
221 | var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] | ||
222 | for word in words: | ||
223 | var panel = panel_prefab.instantiate() | ||
224 | panel.position = Vector3(0, next_y, 0) | ||
225 | next_y -= 10 | ||
226 | panel.clue = word | ||
227 | panel.symbol = "" | ||
228 | panel.answer = word | ||
229 | panel.name = "EndCheck_%s" % word | ||
230 | |||
231 | var tpl = tpl_prefab.instantiate() | ||
232 | tpl.teleport_point = Vector3(0, 1, 0) | ||
233 | tpl.teleport_rotate = Vector3(-45, 180, 0) | ||
234 | tpl.target_path = panel | ||
235 | tpl.name = "Teleport" | ||
236 | |||
237 | if previous_panel == null: | ||
238 | tpl.senders.append(NodePath("/root/scene/Panels/End/panel_24")) | ||
239 | else: | ||
240 | tpl.senders.append(NodePath("../../%s" % previous_panel.name)) | ||
241 | |||
242 | var reversing = reverse_prefab.instantiate() | ||
243 | reversing.senders.append(NodePath("..")) | ||
244 | reversing.name = "Reversing" | ||
245 | tpl.senders.append(NodePath("../Reversing")) | ||
246 | |||
247 | panel.add_child.call_deferred(tpl) | ||
248 | panel.add_child.call_deferred(reversing) | ||
249 | get_parent().get_node("Panels").add_child.call_deferred(panel) | ||
250 | |||
251 | previous_panel = panel | ||
252 | |||
253 | # Duplicate the doors that usually wait on EQUINOX. We can't set the senders | ||
254 | # here for some reason so we actually set them in the door ready function. | ||
255 | var endplat = get_node("/root/scene/Components/Doors/EndPlatform") | ||
256 | var endplat2 = endplat.duplicate() | ||
257 | endplat2.name = "spe_EndPlatform" | ||
258 | endplat.get_parent().add_child.call_deferred(endplat2) | ||
259 | endplat.queue_free() | ||
260 | |||
261 | var entry2 = get_node("/root/scene/Components/Doors/entry_2") | ||
262 | var entry22 = entry2.duplicate() | ||
263 | entry22.name = "spe_entry_2" | ||
264 | entry2.get_parent().add_child.call_deferred(entry22) | ||
265 | entry2.queue_free() | ||
266 | |||
267 | # Add the strict cyan ending validation. | ||
268 | if global.map == "the_parthenon" and ap.strict_cyan_ending: | ||
269 | var panel_prefab = preload("res://objects/nodes/panel.tscn") | ||
270 | var tpl_prefab = preload("res://objects/nodes/listeners/teleportListener.tscn") | ||
271 | var reverse_prefab = preload("res://objects/nodes/listeners/reversingListener.tscn") | ||
272 | |||
273 | var previous_panel = null | ||
274 | var next_y = -100 | ||
275 | var words = ["quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"] | ||
276 | for word in words: | ||
277 | var panel = panel_prefab.instantiate() | ||
278 | panel.position = Vector3(0, next_y, 0) | ||
279 | next_y -= 10 | ||
280 | panel.clue = word | ||
281 | panel.symbol = "." | ||
282 | panel.answer = "%s%s" % [word, word] | ||
283 | panel.name = "EndCheck_%s" % word | ||
284 | |||
285 | var tpl = tpl_prefab.instantiate() | ||
286 | tpl.teleport_point = Vector3(0, 1, -11) | ||
287 | tpl.teleport_rotate = Vector3(-45, 0, 0) | ||
288 | tpl.target_path = panel | ||
289 | tpl.name = "Teleport" | ||
290 | |||
291 | if previous_panel == null: | ||
292 | tpl.senderGroup.append(NodePath("/root/scene/Panels/Rulers")) | ||
293 | else: | ||
294 | tpl.senders.append(NodePath("../../%s" % previous_panel.name)) | ||
295 | |||
296 | var reversing = reverse_prefab.instantiate() | ||
297 | reversing.senders.append(NodePath("..")) | ||
298 | reversing.name = "Reversing" | ||
299 | tpl.senders.append(NodePath("../Reversing")) | ||
300 | |||
301 | panel.add_child.call_deferred(tpl) | ||
302 | panel.add_child.call_deferred(reversing) | ||
303 | get_parent().get_node("Panels").add_child.call_deferred(panel) | ||
304 | |||
305 | previous_panel = panel | ||
306 | |||
307 | # Duplicate the door that usually waits on the rulers. We can't set the | ||
308 | # senders here for some reason so we actually set them in the door ready | ||
309 | # function. | ||
310 | var entry1 = get_node("/root/scene/Components/Doors/entry_1") | ||
311 | var entry12 = entry1.duplicate() | ||
312 | entry12.name = "spe_entry_1" | ||
313 | entry1.get_parent().add_child.call_deferred(entry12) | ||
314 | entry1.queue_free() | ||
315 | |||
316 | ap.update_job_well_done_sign() | ||
317 | |||
318 | var minimap = ap.SCRIPT_minimap.new() | ||
319 | minimap.name = "Minimap" | ||
320 | minimap.visible = ap.show_minimap | ||
321 | get_parent().add_child.call_deferred(minimap) | ||
322 | |||
323 | super._ready() | ||
324 | |||
325 | await get_tree().process_frame | ||
326 | await get_tree().process_frame | ||
327 | |||
328 | ap.stop_batching_locations() | ||
329 | |||
330 | |||
331 | func _set_up_invis_wall(x, y, z, sx, sy, sz): | ||
332 | var prefab = preload("res://objects/nodes/block.tscn") | ||
333 | var newwall = prefab.instantiate() | ||
334 | newwall.position.x = x | ||
335 | newwall.position.y = y | ||
336 | newwall.position.z = z | ||
337 | newwall.scale.x = sz | ||
338 | newwall.scale.y = sy | ||
339 | newwall.scale.z = sx | ||
340 | newwall.set_surface_override_material(0, preload("res://assets/materials/blackMatte.material")) | ||
341 | newwall.visibility_range_end = 3 | ||
342 | newwall.visibility_range_end_margin = 1 | ||
343 | newwall.visibility_range_fade_mode = RenderingServer.VISIBILITY_RANGE_FADE_SELF | ||
344 | newwall.skeleton = ".." | ||
345 | get_parent().add_child.call_deferred(newwall) | ||
346 | |||
347 | |||
348 | func _process(_dt): | ||
349 | compass.update_rotation(global_rotation.y) | ||
diff --git a/apworld/client/rainbowText.gd b/apworld/client/rainbowText.gd new file mode 100644 index 0000000..9a4c1d0 --- /dev/null +++ b/apworld/client/rainbowText.gd | |||
@@ -0,0 +1,10 @@ | |||
1 | extends RichTextEffect | ||
2 | |||
3 | var bbcode = "rainbow" | ||
4 | |||
5 | |||
6 | func _process_custom_fx(char_fx: CharFXTransform): | ||
7 | char_fx.color = Color.from_hsv( | ||
8 | char_fx.elapsed_time - floor(char_fx.elapsed_time), 1.0, 1.0, 1.0 | ||
9 | ) | ||
10 | return true | ||
diff --git a/apworld/client/run_from_apworld.tscn b/apworld/client/run_from_apworld.tscn new file mode 100644 index 0000000..11373e0 --- /dev/null +++ b/apworld/client/run_from_apworld.tscn | |||
@@ -0,0 +1,30 @@ | |||
1 | [gd_scene load_steps=11 format=2] | ||
2 | |||
3 | [sub_resource id=2 type="GDScript"] | ||
4 | script/source = "extends Node2D | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var args = OS.get_cmdline_user_args() | ||
9 | var apworld_path = args[0] | ||
10 | |||
11 | var zip_reader = ZIPReader.new() | ||
12 | zip_reader.open(apworld_path) | ||
13 | |||
14 | var runtime_script = GDScript.new() | ||
15 | runtime_script.source_code = zip_reader.read_file(\"lingo2/client/apworld_runtime.gd\").get_string_from_utf8() | ||
16 | runtime_script.reload() | ||
17 | |||
18 | zip_reader.close() | ||
19 | |||
20 | var runtime = runtime_script.new(apworld_path) | ||
21 | runtime.name = \"Runtime\" | ||
22 | |||
23 | global.add_child(runtime) | ||
24 | |||
25 | runtime.load_script_as_scene.call_deferred(\"settings_screen.gd\", \"settings_screen\") | ||
26 | |||
27 | " | ||
28 | |||
29 | [node name="loader" type="Node2D"] | ||
30 | script = SubResource( 2 ) | ||
diff --git a/apworld/client/run_from_source.tscn b/apworld/client/run_from_source.tscn new file mode 100644 index 0000000..59a914d --- /dev/null +++ b/apworld/client/run_from_source.tscn | |||
@@ -0,0 +1,22 @@ | |||
1 | [gd_scene load_steps=11 format=2] | ||
2 | |||
3 | [sub_resource id=2 type="GDScript"] | ||
4 | script/source = "extends Node2D | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var args = OS.get_cmdline_user_args() | ||
9 | var source_path = args[0] | ||
10 | |||
11 | var runtime_script = ResourceLoader.load(\"%s/source_runtime.gd\" % source_path) | ||
12 | var runtime = runtime_script.new(source_path) | ||
13 | runtime.name = \"Runtime\" | ||
14 | |||
15 | global.add_child(runtime) | ||
16 | |||
17 | runtime.load_script_as_scene.call_deferred(\"settings_screen.gd\", \"settings_screen\") | ||
18 | |||
19 | " | ||
20 | |||
21 | [node name="loader" type="Node2D"] | ||
22 | script = SubResource( 2 ) | ||
diff --git a/apworld/client/saver.gd b/apworld/client/saver.gd new file mode 100644 index 0000000..44bc179 --- /dev/null +++ b/apworld/client/saver.gd | |||
@@ -0,0 +1,23 @@ | |||
1 | extends "res://scripts/nodes/saver.gd" | ||
2 | |||
3 | |||
4 | func levelLoaded(): | ||
5 | if type == "keyholders": | ||
6 | var ap = global.get_node("Archipelago") | ||
7 | ap.keyboard.load_keyholders.call_deferred(global.map) | ||
8 | else: | ||
9 | reload.call_deferred() | ||
10 | |||
11 | |||
12 | func reload(): | ||
13 | # Just rewriting this whole thing so I can remove Chris's safeguard. | ||
14 | var file = FileAccess.open(path + type + ".save", FileAccess.READ) | ||
15 | if file: | ||
16 | var data = file.get_var(true) | ||
17 | file.close() | ||
18 | for datum in data: | ||
19 | var saveable = get_node_or_null(datum[0]) | ||
20 | if saveable != null: | ||
21 | saveable.is_complete = datum[1] | ||
22 | if saveable.is_complete: | ||
23 | saveable.loadData(saveable.is_complete) | ||
diff --git a/apworld/client/settings_screen.gd b/apworld/client/settings_screen.gd new file mode 100644 index 0000000..89e8b68 --- /dev/null +++ b/apworld/client/settings_screen.gd | |||
@@ -0,0 +1,149 @@ | |||
1 | extends Node | ||
2 | |||
3 | |||
4 | func _ready(): | ||
5 | var theme = preload("res://assets/themes/baseUI.tres") | ||
6 | |||
7 | var simple_style_box = StyleBoxFlat.new() | ||
8 | simple_style_box.bg_color = Color(0, 0, 0, 0) | ||
9 | |||
10 | var panel = Panel.new() | ||
11 | panel.name = "Panel" | ||
12 | panel.offset_right = 1920.0 | ||
13 | panel.offset_bottom = 1080.0 | ||
14 | add_child(panel) | ||
15 | |||
16 | var title = Label.new() | ||
17 | title.name = "title" | ||
18 | title.offset_left = 0.0 | ||
19 | title.offset_top = 75.0 | ||
20 | title.offset_right = 1920.0 | ||
21 | title.offset_bottom = 225.0 | ||
22 | title.text = "ARCHIPELAGO" | ||
23 | title.vertical_alignment = VERTICAL_ALIGNMENT_CENTER | ||
24 | title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER | ||
25 | title.theme = theme | ||
26 | panel.add_child(title) | ||
27 | |||
28 | var connect_button = Button.new() | ||
29 | connect_button.name = "connect_button" | ||
30 | connect_button.offset_left = 255.0 | ||
31 | connect_button.offset_top = 875.0 | ||
32 | connect_button.offset_right = 891.0 | ||
33 | connect_button.offset_bottom = 1025.0 | ||
34 | connect_button.add_theme_color_override("font_color_hover", Color(1, 0.501961, 0, 1)) | ||
35 | connect_button.text = "CONNECT" | ||
36 | connect_button.theme = theme | ||
37 | panel.add_child(connect_button) | ||
38 | |||
39 | var quit_button = Button.new() | ||
40 | quit_button.name = "quit_button" | ||
41 | quit_button.offset_left = 1102.0 | ||
42 | quit_button.offset_top = 875.0 | ||
43 | quit_button.offset_right = 1738.0 | ||
44 | quit_button.offset_bottom = 1025.0 | ||
45 | quit_button.add_theme_color_override("font_color_hover", Color(1, 0, 0, 1)) | ||
46 | quit_button.text = "QUIT" | ||
47 | quit_button.theme = theme | ||
48 | panel.add_child(quit_button) | ||
49 | |||
50 | var credit2 = Label.new() | ||
51 | credit2.name = "credit2" | ||
52 | credit2.offset_left = -105.0 | ||
53 | credit2.offset_top = 346.0 | ||
54 | credit2.offset_right = 485.0 | ||
55 | credit2.offset_bottom = 410.0 | ||
56 | credit2.add_theme_stylebox_override("normal", simple_style_box) | ||
57 | credit2.text = "SERVER" | ||
58 | credit2.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT | ||
59 | credit2.theme = theme | ||
60 | panel.add_child(credit2) | ||
61 | |||
62 | var credit3 = Label.new() | ||
63 | credit3.name = "credit3" | ||
64 | credit3.offset_left = -105.0 | ||
65 | credit3.offset_top = 519.0 | ||
66 | credit3.offset_right = 485.0 | ||
67 | credit3.offset_bottom = 583.0 | ||
68 | credit3.add_theme_stylebox_override("normal", simple_style_box) | ||
69 | credit3.text = "PLAYER" | ||
70 | credit3.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT | ||
71 | credit3.theme = theme | ||
72 | panel.add_child(credit3) | ||
73 | |||
74 | var credit4 = Label.new() | ||
75 | credit4.name = "credit4" | ||
76 | credit4.offset_left = -105.0 | ||
77 | credit4.offset_top = 704.0 | ||
78 | credit4.offset_right = 485.0 | ||
79 | credit4.offset_bottom = 768.0 | ||
80 | credit4.add_theme_stylebox_override("normal", simple_style_box) | ||
81 | credit4.text = "PASSWORD" | ||
82 | credit4.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT | ||
83 | credit4.theme = theme | ||
84 | panel.add_child(credit4) | ||
85 | |||
86 | var credit5 = Label.new() | ||
87 | credit5.name = "credit5" | ||
88 | credit5.offset_left = 1239.0 | ||
89 | credit5.offset_top = 422.0 | ||
90 | credit5.offset_right = 1829.0 | ||
91 | credit5.offset_bottom = 486.0 | ||
92 | credit5.add_theme_stylebox_override("normal", simple_style_box) | ||
93 | credit5.text = "OPTIONS" | ||
94 | credit5.theme = theme | ||
95 | panel.add_child(credit5) | ||
96 | |||
97 | var server_box = LineEdit.new() | ||
98 | server_box.name = "server_box" | ||
99 | server_box.offset_left = 502.0 | ||
100 | server_box.offset_top = 295.0 | ||
101 | server_box.offset_right = 1144.0 | ||
102 | server_box.offset_bottom = 445.0 | ||
103 | server_box.alignment = HORIZONTAL_ALIGNMENT_CENTER | ||
104 | server_box.caret_blink = true | ||
105 | panel.add_child(server_box) | ||
106 | |||
107 | var player_box = LineEdit.new() | ||
108 | player_box.name = "player_box" | ||
109 | player_box.offset_left = 502.0 | ||
110 | player_box.offset_top = 477.0 | ||
111 | player_box.offset_right = 1144.0 | ||
112 | player_box.offset_bottom = 627.0 | ||
113 | player_box.alignment = HORIZONTAL_ALIGNMENT_CENTER | ||
114 | player_box.caret_blink = true | ||
115 | panel.add_child(player_box) | ||
116 | |||
117 | var password_box = LineEdit.new() | ||
118 | password_box.name = "password_box" | ||
119 | password_box.offset_left = 502.0 | ||
120 | password_box.offset_top = 659.0 | ||
121 | password_box.offset_right = 1144.0 | ||
122 | password_box.offset_bottom = 809.0 | ||
123 | password_box.alignment = HORIZONTAL_ALIGNMENT_CENTER | ||
124 | password_box.caret_blink = true | ||
125 | panel.add_child(password_box) | ||
126 | |||
127 | var accept_dialog = AcceptDialog.new() | ||
128 | accept_dialog.name = "AcceptDialog" | ||
129 | panel.add_child(accept_dialog) | ||
130 | |||
131 | var version_mismatch = ConfirmationDialog.new() | ||
132 | version_mismatch.name = "VersionMismatch" | ||
133 | panel.add_child(version_mismatch) | ||
134 | |||
135 | var connection_history = MenuButton.new() | ||
136 | connection_history.name = "connection_history" | ||
137 | connection_history.offset_left = 1239.0 | ||
138 | connection_history.offset_top = 276.0 | ||
139 | connection_history.offset_right = 1829.0 | ||
140 | connection_history.offset_bottom = 372.0 | ||
141 | connection_history.text = "connection history" | ||
142 | connection_history.flat = false | ||
143 | panel.add_child(connection_history) | ||
144 | |||
145 | var runtime = global.get_node("Runtime") | ||
146 | var main_script = runtime.load_script("main.gd") | ||
147 | var main_node = main_script.new() | ||
148 | main_node.name = "Main" | ||
149 | add_child(main_node) | ||
diff --git a/apworld/client/source_runtime.gd b/apworld/client/source_runtime.gd new file mode 100644 index 0000000..35428ea --- /dev/null +++ b/apworld/client/source_runtime.gd | |||
@@ -0,0 +1,29 @@ | |||
1 | extends Node | ||
2 | |||
3 | var source_path | ||
4 | |||
5 | |||
6 | func _init(path): | ||
7 | source_path = path | ||
8 | |||
9 | |||
10 | func load_script(path): | ||
11 | return ResourceLoader.load("%s/%s" % [source_path, path]) | ||
12 | |||
13 | |||
14 | func read_path(path): | ||
15 | return FileAccess.get_file_as_bytes("%s/%s" % [source_path, path]) | ||
16 | |||
17 | |||
18 | func load_script_as_scene(path, scene_name): | ||
19 | var script = load_script(path) | ||
20 | var instance = script.new() | ||
21 | instance.name = scene_name | ||
22 | |||
23 | get_tree().unload_current_scene() | ||
24 | _load_scene.call_deferred(instance) | ||
25 | |||
26 | |||
27 | func _load_scene(instance): | ||
28 | get_tree().get_root().add_child(instance) | ||
29 | get_tree().current_scene = instance | ||
diff --git a/apworld/client/teleport.gd b/apworld/client/teleport.gd new file mode 100644 index 0000000..428d50b --- /dev/null +++ b/apworld/client/teleport.gd | |||
@@ -0,0 +1,38 @@ | |||
1 | extends "res://scripts/nodes/teleport.gd" | ||
2 | |||
3 | var item_id | ||
4 | var item_amount | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var node_path = String( | ||
9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
10 | ) | ||
11 | |||
12 | var gamedata = global.get_node("Gamedata") | ||
13 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | ||
14 | if door_id != null: | ||
15 | var ap = global.get_node("Archipelago") | ||
16 | var item_lock = ap.get_item_id_for_door(door_id) | ||
17 | |||
18 | if item_lock != null: | ||
19 | item_id = item_lock[0] | ||
20 | item_amount = item_lock[1] | ||
21 | |||
22 | self.senders = [] | ||
23 | self.senderGroup = [] | ||
24 | self.nested = false | ||
25 | self.complete_at = 0 | ||
26 | self.max_length = 0 | ||
27 | self.excludeSenders = [] | ||
28 | |||
29 | call_deferred("_readier") | ||
30 | |||
31 | super._ready() | ||
32 | |||
33 | |||
34 | func _readier(): | ||
35 | var ap = global.get_node("Archipelago") | ||
36 | |||
37 | if ap.client.getItemAmount(item_id) >= item_amount: | ||
38 | handleTriggered() | ||
diff --git a/apworld/client/teleportListener.gd b/apworld/client/teleportListener.gd new file mode 100644 index 0000000..6f363af --- /dev/null +++ b/apworld/client/teleportListener.gd | |||
@@ -0,0 +1,49 @@ | |||
1 | extends "res://scripts/nodes/listeners/teleportListener.gd" | ||
2 | |||
3 | var item_id | ||
4 | var item_amount | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var node_path = String( | ||
9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
10 | ) | ||
11 | |||
12 | if ( | ||
13 | global.map == "daedalus" | ||
14 | and ( | ||
15 | node_path == "Components/Triggers/teleportListenerConnections" | ||
16 | or node_path == "Components/Triggers/teleportListenerConnections2" | ||
17 | ) | ||
18 | ): | ||
19 | # Effectively disable these. | ||
20 | teleport_point = target_path.position | ||
21 | return | ||
22 | |||
23 | var gamedata = global.get_node("Gamedata") | ||
24 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | ||
25 | if door_id != null: | ||
26 | var ap = global.get_node("Archipelago") | ||
27 | var item_lock = ap.get_item_id_for_door(door_id) | ||
28 | |||
29 | if item_lock != null: | ||
30 | item_id = item_lock[0] | ||
31 | item_amount = item_lock[1] | ||
32 | |||
33 | self.senders = [] | ||
34 | self.senderGroup = [] | ||
35 | self.nested = false | ||
36 | self.complete_at = 0 | ||
37 | self.max_length = 0 | ||
38 | self.excludeSenders = [] | ||
39 | |||
40 | call_deferred("_readier") | ||
41 | |||
42 | super._ready() | ||
43 | |||
44 | |||
45 | func _readier(): | ||
46 | var ap = global.get_node("Archipelago") | ||
47 | |||
48 | if ap.client.getItemAmount(item_id) >= item_amount: | ||
49 | handleTriggered() | ||
diff --git a/apworld/client/textclient.gd b/apworld/client/textclient.gd new file mode 100644 index 0000000..f785a03 --- /dev/null +++ b/apworld/client/textclient.gd | |||
@@ -0,0 +1,438 @@ | |||
1 | extends CanvasLayer | ||
2 | |||
3 | var tabs | ||
4 | var panel | ||
5 | var label | ||
6 | var entry | ||
7 | var is_open = false | ||
8 | |||
9 | var locations_overlay | ||
10 | var location_texture | ||
11 | var worldport_texture | ||
12 | var goal_texture | ||
13 | |||
14 | var tracker_tree | ||
15 | var tracker_loc_tree_item_by_id = {} | ||
16 | var tracker_port_tree_item_by_id = {} | ||
17 | var tracker_goal_tree_item = null | ||
18 | var tracker_object_by_index = {} | ||
19 | |||
20 | var worldports_tab | ||
21 | var worldports_tree | ||
22 | var port_tree_item_by_map = {} | ||
23 | var port_tree_item_by_map_port = {} | ||
24 | |||
25 | const kLocation = 0 | ||
26 | const kWorldport = 1 | ||
27 | const kGoal = 2 | ||
28 | |||
29 | |||
30 | func _ready(): | ||
31 | process_mode = ProcessMode.PROCESS_MODE_ALWAYS | ||
32 | layer = 2 | ||
33 | |||
34 | locations_overlay = RichTextLabel.new() | ||
35 | locations_overlay.name = "LocationsOverlay" | ||
36 | locations_overlay.offset_top = 220 | ||
37 | locations_overlay.offset_bottom = 720 | ||
38 | locations_overlay.offset_left = 20 | ||
39 | locations_overlay.anchor_right = 1.0 | ||
40 | locations_overlay.offset_right = -10 | ||
41 | locations_overlay.scroll_active = false | ||
42 | locations_overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE | ||
43 | locations_overlay.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST | ||
44 | add_child(locations_overlay) | ||
45 | update_locations_visibility() | ||
46 | |||
47 | tabs = TabContainer.new() | ||
48 | tabs.name = "Tabs" | ||
49 | tabs.offset_left = 100 | ||
50 | tabs.offset_right = 1820 | ||
51 | tabs.offset_top = 100 | ||
52 | tabs.offset_bottom = 980 | ||
53 | tabs.visible = false | ||
54 | tabs.theme = preload("res://assets/themes/baseUI.tres") | ||
55 | tabs.add_theme_font_size_override("font_size", 36) | ||
56 | add_child(tabs) | ||
57 | |||
58 | panel = MarginContainer.new() | ||
59 | panel.name = "Text Client" | ||
60 | panel.add_theme_constant_override("margin_top", 60) | ||
61 | panel.add_theme_constant_override("margin_left", 60) | ||
62 | panel.add_theme_constant_override("margin_right", 60) | ||
63 | panel.add_theme_constant_override("margin_bottom", 60) | ||
64 | tabs.add_child(panel) | ||
65 | |||
66 | label = RichTextLabel.new() | ||
67 | label.set_name("Label") | ||
68 | label.scroll_following = true | ||
69 | label.selection_enabled = true | ||
70 | label.size_flags_horizontal = Control.SIZE_EXPAND_FILL | ||
71 | label.size_flags_vertical = Control.SIZE_EXPAND_FILL | ||
72 | label.push_font(preload("res://assets/fonts/Lingo2.ttf")) | ||
73 | label.push_font_size(30) | ||
74 | |||
75 | var entry_style = StyleBoxFlat.new() | ||
76 | entry_style.bg_color = Color(0.9, 0.9, 0.9, 1) | ||
77 | |||
78 | entry = LineEdit.new() | ||
79 | entry.set_name("Entry") | ||
80 | entry.add_theme_font_override("font", preload("res://assets/fonts/Lingo2.ttf")) | ||
81 | entry.add_theme_font_size_override("font_size", 36) | ||
82 | entry.add_theme_color_override("font_color", Color(0, 0, 0, 1)) | ||
83 | entry.add_theme_color_override("cursor_color", Color(0, 0, 0, 1)) | ||
84 | entry.add_theme_stylebox_override("focus", entry_style) | ||
85 | entry.text_submitted.connect(text_entered) | ||
86 | |||
87 | var tc_arranger = VBoxContainer.new() | ||
88 | tc_arranger.add_child(label) | ||
89 | tc_arranger.add_child(entry) | ||
90 | tc_arranger.add_theme_constant_override("separation", 40) | ||
91 | panel.add_child(tc_arranger) | ||
92 | |||
93 | var tracker_margins = MarginContainer.new() | ||
94 | tracker_margins.name = "Locations" | ||
95 | tracker_margins.add_theme_constant_override("margin_top", 60) | ||
96 | tracker_margins.add_theme_constant_override("margin_left", 60) | ||
97 | tracker_margins.add_theme_constant_override("margin_right", 60) | ||
98 | tracker_margins.add_theme_constant_override("margin_bottom", 60) | ||
99 | tabs.add_child(tracker_margins) | ||
100 | |||
101 | tracker_tree = Tree.new() | ||
102 | tracker_tree.columns = 3 | ||
103 | tracker_tree.hide_root = true | ||
104 | tracker_tree.add_theme_font_size_override("font_size", 24) | ||
105 | tracker_tree.add_theme_color_override("font_color", Color(0.8, 0.8, 0.8, 1)) | ||
106 | tracker_tree.add_theme_constant_override("v_separation", 1) | ||
107 | tracker_tree.item_edited.connect(_on_tracker_button_clicked) | ||
108 | tracker_tree.set_column_expand(0, false) | ||
109 | tracker_tree.set_column_expand(1, true) | ||
110 | tracker_tree.set_column_expand(2, false) | ||
111 | tracker_tree.set_column_custom_minimum_width(2, 200) | ||
112 | tracker_margins.add_child(tracker_tree) | ||
113 | |||
114 | worldports_tab = MarginContainer.new() | ||
115 | worldports_tab.name = "Worldports" | ||
116 | worldports_tab.add_theme_constant_override("margin_top", 60) | ||
117 | worldports_tab.add_theme_constant_override("margin_left", 60) | ||
118 | worldports_tab.add_theme_constant_override("margin_right", 60) | ||
119 | worldports_tab.add_theme_constant_override("margin_bottom", 60) | ||
120 | tabs.add_child(worldports_tab) | ||
121 | tabs.set_tab_hidden(2, true) | ||
122 | |||
123 | worldports_tree = Tree.new() | ||
124 | worldports_tree.columns = 2 | ||
125 | worldports_tree.hide_root = true | ||
126 | worldports_tree.theme = preload("res://assets/themes/baseUI.tres") | ||
127 | worldports_tree.add_theme_font_size_override("font_size", 24) | ||
128 | worldports_tab.add_child(worldports_tree) | ||
129 | |||
130 | var runtime = global.get_node("Runtime") | ||
131 | var location_image = Image.new() | ||
132 | location_image.load_png_from_buffer(runtime.read_path("assets/location.png")) | ||
133 | location_texture = ImageTexture.create_from_image(location_image) | ||
134 | |||
135 | var worldport_image = Image.new() | ||
136 | worldport_image.load_png_from_buffer(runtime.read_path("assets/worldport.png")) | ||
137 | worldport_texture = ImageTexture.create_from_image(worldport_image) | ||
138 | |||
139 | var goal_image = Image.new() | ||
140 | goal_image.load_png_from_buffer(runtime.read_path("assets/goal.png")) | ||
141 | goal_texture = ImageTexture.create_from_image(goal_image) | ||
142 | |||
143 | |||
144 | func _input(event): | ||
145 | if global.loaded and event is InputEventKey and event.pressed: | ||
146 | if event.keycode == KEY_TAB and !Input.is_key_pressed(KEY_SHIFT): | ||
147 | if !get_tree().paused: | ||
148 | is_open = true | ||
149 | get_tree().paused = true | ||
150 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | ||
151 | tabs.visible = true | ||
152 | entry.grab_focus() | ||
153 | get_viewport().set_input_as_handled() | ||
154 | else: | ||
155 | dismiss() | ||
156 | elif event.keycode == KEY_ESCAPE: | ||
157 | if is_open: | ||
158 | dismiss() | ||
159 | get_viewport().set_input_as_handled() | ||
160 | |||
161 | |||
162 | func dismiss(): | ||
163 | if is_open: | ||
164 | get_tree().paused = false | ||
165 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | ||
166 | tabs.visible = false | ||
167 | is_open = false | ||
168 | |||
169 | |||
170 | func parse_printjson(text): | ||
171 | label.append_text("[p]" + text + "[/p]") | ||
172 | |||
173 | |||
174 | func text_entered(text): | ||
175 | var ap = global.get_node("Archipelago") | ||
176 | var cmd = text.trim_suffix("\n") | ||
177 | entry.text = "" | ||
178 | if OS.is_debug_build(): | ||
179 | if cmd.begins_with("/tp_map "): | ||
180 | var new_map = cmd.substr(8) | ||
181 | global.map = new_map | ||
182 | global.sets_entry_point = false | ||
183 | switcher.switch_map("res://objects/scenes/%s.tscn" % new_map) | ||
184 | return | ||
185 | |||
186 | ap.client.say(cmd) | ||
187 | |||
188 | |||
189 | func update_locations(reset_locations = true): | ||
190 | var ap = global.get_node("Archipelago") | ||
191 | var gamedata = global.get_node("Gamedata") | ||
192 | |||
193 | locations_overlay.clear() | ||
194 | locations_overlay.push_font(preload("res://assets/fonts/Lingo2.ttf")) | ||
195 | locations_overlay.push_font_size(24) | ||
196 | locations_overlay.push_color(Color(0.9, 0.9, 0.9, 1)) | ||
197 | locations_overlay.push_outline_color(Color(0, 0, 0, 1)) | ||
198 | locations_overlay.push_outline_size(2) | ||
199 | |||
200 | var locations = [] | ||
201 | for location_id in ap.client._accessible_locations: | ||
202 | if not ap.client._checked_locations.has(location_id): | ||
203 | var location_name = gamedata.location_name_by_id.get(location_id, "(Unknown)") | ||
204 | ( | ||
205 | locations | ||
206 | . append( | ||
207 | { | ||
208 | "name": location_name, | ||
209 | "type": kLocation, | ||
210 | "id": location_id, | ||
211 | } | ||
212 | ) | ||
213 | ) | ||
214 | |||
215 | for port_id in ap.client._accessible_worldports: | ||
216 | if not ap.client._checked_worldports.has(port_id): | ||
217 | var port_name = gamedata.get_worldport_display_name(port_id) | ||
218 | ( | ||
219 | locations | ||
220 | . append( | ||
221 | { | ||
222 | "name": port_name, | ||
223 | "type": kWorldport, | ||
224 | "id": port_id, | ||
225 | } | ||
226 | ) | ||
227 | ) | ||
228 | |||
229 | locations.sort_custom(func(a, b): return a["name"] < b["name"]) | ||
230 | |||
231 | if ap.client._goal_accessible: | ||
232 | var location_name = gamedata.ending_display_name_by_name[ap.kEndingNameByVictoryValue[ | ||
233 | ap.victory_condition | ||
234 | ]] | ||
235 | ( | ||
236 | locations | ||
237 | . push_front( | ||
238 | { | ||
239 | "name": location_name, | ||
240 | "type": kGoal, | ||
241 | } | ||
242 | ) | ||
243 | ) | ||
244 | |||
245 | var count = 0 | ||
246 | for location in locations: | ||
247 | if count < 18: | ||
248 | locations_overlay.push_paragraph(HORIZONTAL_ALIGNMENT_RIGHT) | ||
249 | locations_overlay.append_text(location["name"]) | ||
250 | locations_overlay.append_text(" ") | ||
251 | if location["type"] == kLocation: | ||
252 | locations_overlay.add_image(location_texture) | ||
253 | elif location["type"] == kWorldport: | ||
254 | locations_overlay.add_image(worldport_texture) | ||
255 | elif location["type"] == kGoal: | ||
256 | locations_overlay.add_image(goal_texture) | ||
257 | locations_overlay.pop() | ||
258 | count += 1 | ||
259 | |||
260 | if count > 18: | ||
261 | locations_overlay.append_text("[p align=right][lb]...[rb][/p]") | ||
262 | |||
263 | if reset_locations: | ||
264 | reset_tracker_tab() | ||
265 | |||
266 | var root_ti = tracker_tree.create_item(null) | ||
267 | |||
268 | for location in locations: | ||
269 | var loc_row = root_ti.create_child() | ||
270 | loc_row.set_cell_mode(0, TreeItem.CELL_MODE_ICON) | ||
271 | loc_row.set_selectable(0, false) | ||
272 | loc_row.set_text(1, location["name"]) | ||
273 | loc_row.set_selectable(1, false) | ||
274 | loc_row.set_cell_mode(2, TreeItem.CELL_MODE_CUSTOM) | ||
275 | loc_row.set_text(2, "Show Path") | ||
276 | loc_row.set_custom_as_button(2, true) | ||
277 | loc_row.set_editable(2, true) | ||
278 | loc_row.set_selectable(2, false) | ||
279 | loc_row.set_text_alignment(2, HORIZONTAL_ALIGNMENT_CENTER) | ||
280 | |||
281 | if location["type"] == kLocation: | ||
282 | loc_row.set_icon(0, location_texture) | ||
283 | tracker_loc_tree_item_by_id[location["id"]] = loc_row | ||
284 | elif location["type"] == kWorldport: | ||
285 | loc_row.set_icon(0, worldport_texture) | ||
286 | tracker_port_tree_item_by_id[location["id"]] = loc_row | ||
287 | elif location["type"] == kGoal: | ||
288 | loc_row.set_icon(0, goal_texture) | ||
289 | tracker_goal_tree_item = loc_row | ||
290 | |||
291 | tracker_object_by_index[loc_row.get_index()] = location | ||
292 | else: | ||
293 | for loc_row in tracker_tree.get_root().get_children(): | ||
294 | loc_row.visible = false | ||
295 | |||
296 | for location_id in tracker_loc_tree_item_by_id.keys(): | ||
297 | if ( | ||
298 | ap.client._accessible_locations.has(location_id) | ||
299 | and not ap.client._checked_locations.has(location_id) | ||
300 | ): | ||
301 | tracker_loc_tree_item_by_id[location_id].visible = true | ||
302 | |||
303 | for port_id in tracker_port_tree_item_by_id.keys(): | ||
304 | if ( | ||
305 | ap.client._accessible_worldports.has(port_id) | ||
306 | and not ap.client._checked_worldports.has(port_id) | ||
307 | ): | ||
308 | tracker_port_tree_item_by_id[port_id].visible = true | ||
309 | |||
310 | if tracker_goal_tree_item != null and ap.client._goal_accessible: | ||
311 | tracker_goal_tree_item.visible = true | ||
312 | |||
313 | |||
314 | func update_locations_visibility(): | ||
315 | var ap = global.get_node("Archipelago") | ||
316 | locations_overlay.visible = ap.show_locations | ||
317 | |||
318 | |||
319 | func _on_tracker_button_clicked(): | ||
320 | var edited_item = tracker_tree.get_edited() | ||
321 | var edited_index = edited_item.get_index() | ||
322 | |||
323 | if tracker_object_by_index.has(edited_index): | ||
324 | var tracker_object = tracker_object_by_index[edited_index] | ||
325 | var ap = global.get_node("Archipelago") | ||
326 | var type_str = "" | ||
327 | if tracker_object["type"] == kLocation: | ||
328 | type_str = "location" | ||
329 | elif tracker_object["type"] == kWorldport: | ||
330 | type_str = "worldport" | ||
331 | elif tracker_object["type"] == kGoal: | ||
332 | type_str = "goal" | ||
333 | ap.client.getLogicalPath(type_str, tracker_object.get("id", null)) | ||
334 | |||
335 | |||
336 | func display_logical_path(object_type, object_id, paths): | ||
337 | var ap = global.get_node("Archipelago") | ||
338 | var gamedata = global.get_node("Gamedata") | ||
339 | |||
340 | var location_name = "(Unknown)" | ||
341 | if object_type == "location" and object_id != null: | ||
342 | location_name = gamedata.location_name_by_id.get(object_id, "(Unknown)") | ||
343 | elif object_type == "worldport" and object_id != null: | ||
344 | location_name = gamedata.get_worldport_display_name(object_id) | ||
345 | elif object_type == "goal": | ||
346 | location_name = gamedata.ending_display_name_by_name[ap.kEndingNameByVictoryValue[ | ||
347 | ap.victory_condition | ||
348 | ]] | ||
349 | |||
350 | label.append_text("[p]Path to %s:[/p]" % location_name) | ||
351 | label.append_text("[ol]" + "\n".join(paths) + "[/ol]") | ||
352 | |||
353 | panel.visible = true | ||
354 | |||
355 | |||
356 | func setup_worldports(): | ||
357 | tabs.set_tab_hidden(2, false) | ||
358 | |||
359 | var root_ti = worldports_tree.create_item(null) | ||
360 | |||
361 | var ports_by_map_id = {} | ||
362 | var display_names_by_map_id = {} | ||
363 | var display_names_by_port_id = {} | ||
364 | |||
365 | var ap = global.get_node("Archipelago") | ||
366 | var gamedata = global.get_node("Gamedata") | ||
367 | for fpid in ap.port_pairings: | ||
368 | var port = gamedata.objects.get_ports()[fpid] | ||
369 | var room = gamedata.objects.get_rooms()[port.get_room_id()] | ||
370 | |||
371 | if not ports_by_map_id.has(room.get_map_id()): | ||
372 | ports_by_map_id[room.get_map_id()] = [] | ||
373 | |||
374 | var map = gamedata.objects.get_maps()[room.get_map_id()] | ||
375 | display_names_by_map_id[map.get_id()] = map.get_display_name() | ||
376 | |||
377 | ports_by_map_id[room.get_map_id()].append(fpid) | ||
378 | display_names_by_port_id[fpid] = port.get_display_name() | ||
379 | |||
380 | var sorted_map_ids = ports_by_map_id.keys().duplicate() | ||
381 | sorted_map_ids.sort_custom( | ||
382 | func(a, b): return display_names_by_map_id[a] < display_names_by_map_id[b] | ||
383 | ) | ||
384 | |||
385 | for map_id in sorted_map_ids: | ||
386 | var map_ti = root_ti.create_child() | ||
387 | map_ti.set_text(0, display_names_by_map_id[map_id]) | ||
388 | map_ti.visible = false | ||
389 | map_ti.collapsed = true | ||
390 | port_tree_item_by_map[map_id] = map_ti | ||
391 | port_tree_item_by_map_port[map_id] = {} | ||
392 | |||
393 | var port_ids = ports_by_map_id[map_id] | ||
394 | port_ids.sort_custom( | ||
395 | func(a, b): return display_names_by_port_id[a] < display_names_by_port_id[b] | ||
396 | ) | ||
397 | |||
398 | for port_id in port_ids: | ||
399 | var port_ti = map_ti.create_child() | ||
400 | port_ti.set_text(0, display_names_by_port_id[port_id]) | ||
401 | port_ti.set_text(1, gamedata.get_worldport_display_name(ap.port_pairings[port_id])) | ||
402 | port_ti.visible = false | ||
403 | port_tree_item_by_map_port[map_id][port_id] = port_ti | ||
404 | |||
405 | update_worldports() | ||
406 | |||
407 | |||
408 | func update_worldports(): | ||
409 | var ap = global.get_node("Archipelago") | ||
410 | |||
411 | for map_id in port_tree_item_by_map_port.keys(): | ||
412 | var map_visible = false | ||
413 | |||
414 | for port_id in port_tree_item_by_map_port[map_id].keys(): | ||
415 | var ti = port_tree_item_by_map_port[map_id][port_id] | ||
416 | ti.visible = ap.client._checked_worldports.has(port_id) | ||
417 | |||
418 | if ti.visible: | ||
419 | map_visible = true | ||
420 | |||
421 | port_tree_item_by_map[map_id].visible = map_visible | ||
422 | |||
423 | |||
424 | func reset(): | ||
425 | locations_overlay.clear() | ||
426 | tabs.set_tab_hidden(2, true) | ||
427 | port_tree_item_by_map.clear() | ||
428 | port_tree_item_by_map_port.clear() | ||
429 | worldports_tree.clear() | ||
430 | reset_tracker_tab() | ||
431 | |||
432 | |||
433 | func reset_tracker_tab(): | ||
434 | tracker_loc_tree_item_by_id.clear() | ||
435 | tracker_port_tree_item_by_id.clear() | ||
436 | tracker_goal_tree_item = null | ||
437 | tracker_object_by_index.clear() | ||
438 | tracker_tree.clear() | ||
diff --git a/apworld/client/vendor/LICENSE b/apworld/client/vendor/LICENSE new file mode 100644 index 0000000..12763b1 --- /dev/null +++ b/apworld/client/vendor/LICENSE | |||
@@ -0,0 +1,21 @@ | |||
1 | WebSocketServer.gd: | ||
2 | |||
3 | Copyright (c) 2014-present Godot Engine contributors. Copyright (c) 2007-2014 | ||
4 | Juan Linietsky, Ariel Manzur. | ||
5 | |||
6 | Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
7 | this software and associated documentation files (the "Software"), to deal in | ||
8 | the Software without restriction, including without limitation the rights to | ||
9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
10 | the Software, and to permit persons to whom the Software is furnished to do so, | ||
11 | subject to the following conditions: | ||
12 | |||
13 | The above copyright notice and this permission notice shall be included in all | ||
14 | copies or substantial portions of the Software. | ||
15 | |||
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/apworld/client/vendor/WebSocketServer.gd b/apworld/client/vendor/WebSocketServer.gd new file mode 100644 index 0000000..2cee494 --- /dev/null +++ b/apworld/client/vendor/WebSocketServer.gd | |||
@@ -0,0 +1,173 @@ | |||
1 | class_name WebSocketServer | ||
2 | extends Node | ||
3 | |||
4 | signal message_received(peer_id: int, message: String) | ||
5 | signal client_connected(peer_id: int) | ||
6 | signal client_disconnected(peer_id: int) | ||
7 | |||
8 | @export var handshake_headers := PackedStringArray() | ||
9 | @export var supported_protocols := PackedStringArray() | ||
10 | @export var handshake_timout := 3000 | ||
11 | @export var use_tls := false | ||
12 | @export var tls_cert: X509Certificate | ||
13 | @export var tls_key: CryptoKey | ||
14 | @export var refuse_new_connections := false: | ||
15 | set(refuse): | ||
16 | if refuse: | ||
17 | pending_peers.clear() | ||
18 | |||
19 | |||
20 | class PendingPeer: | ||
21 | var connect_time: int | ||
22 | var tcp: StreamPeerTCP | ||
23 | var connection: StreamPeer | ||
24 | var ws: WebSocketPeer | ||
25 | |||
26 | func _init(p_tcp: StreamPeerTCP) -> void: | ||
27 | tcp = p_tcp | ||
28 | connection = p_tcp | ||
29 | connect_time = Time.get_ticks_msec() | ||
30 | |||
31 | |||
32 | var tcp_server := TCPServer.new() | ||
33 | var pending_peers: Array[PendingPeer] = [] | ||
34 | var peers: Dictionary | ||
35 | |||
36 | |||
37 | func listen(port: int) -> int: | ||
38 | assert(not tcp_server.is_listening()) | ||
39 | return tcp_server.listen(port) | ||
40 | |||
41 | |||
42 | func stop() -> void: | ||
43 | tcp_server.stop() | ||
44 | pending_peers.clear() | ||
45 | peers.clear() | ||
46 | |||
47 | |||
48 | func send(peer_id: int, message: String) -> int: | ||
49 | var type := typeof(message) | ||
50 | if peer_id <= 0: | ||
51 | # Send to multiple peers, (zero = broadcast, negative = exclude one). | ||
52 | for id: int in peers: | ||
53 | if id == -peer_id: | ||
54 | continue | ||
55 | if type == TYPE_STRING: | ||
56 | peers[id].send_text(message) | ||
57 | else: | ||
58 | peers[id].put_packet(message) | ||
59 | return OK | ||
60 | |||
61 | assert(peers.has(peer_id)) | ||
62 | var socket: WebSocketPeer = peers[peer_id] | ||
63 | if type == TYPE_STRING: | ||
64 | return socket.send_text(message) | ||
65 | return socket.send(var_to_bytes(message)) | ||
66 | |||
67 | |||
68 | func get_message(peer_id: int) -> Variant: | ||
69 | assert(peers.has(peer_id)) | ||
70 | var socket: WebSocketPeer = peers[peer_id] | ||
71 | if socket.get_available_packet_count() < 1: | ||
72 | return null | ||
73 | var pkt: PackedByteArray = socket.get_packet() | ||
74 | if socket.was_string_packet(): | ||
75 | return pkt.get_string_from_utf8() | ||
76 | return bytes_to_var(pkt) | ||
77 | |||
78 | |||
79 | func has_message(peer_id: int) -> bool: | ||
80 | assert(peers.has(peer_id)) | ||
81 | return peers[peer_id].get_available_packet_count() > 0 | ||
82 | |||
83 | |||
84 | func _create_peer() -> WebSocketPeer: | ||
85 | var ws := WebSocketPeer.new() | ||
86 | ws.supported_protocols = supported_protocols | ||
87 | ws.handshake_headers = handshake_headers | ||
88 | return ws | ||
89 | |||
90 | |||
91 | func poll() -> void: | ||
92 | if not tcp_server.is_listening(): | ||
93 | return | ||
94 | |||
95 | while not refuse_new_connections and tcp_server.is_connection_available(): | ||
96 | var conn: StreamPeerTCP = tcp_server.take_connection() | ||
97 | assert(conn != null) | ||
98 | pending_peers.append(PendingPeer.new(conn)) | ||
99 | |||
100 | var to_remove := [] | ||
101 | |||
102 | for p in pending_peers: | ||
103 | if not _connect_pending(p): | ||
104 | if p.connect_time + handshake_timout < Time.get_ticks_msec(): | ||
105 | # Timeout. | ||
106 | to_remove.append(p) | ||
107 | continue # Still pending. | ||
108 | |||
109 | to_remove.append(p) | ||
110 | |||
111 | for r: RefCounted in to_remove: | ||
112 | pending_peers.erase(r) | ||
113 | |||
114 | to_remove.clear() | ||
115 | |||
116 | for id: int in peers: | ||
117 | var p: WebSocketPeer = peers[id] | ||
118 | p.poll() | ||
119 | |||
120 | if p.get_ready_state() != WebSocketPeer.STATE_OPEN: | ||
121 | client_disconnected.emit(id) | ||
122 | to_remove.append(id) | ||
123 | continue | ||
124 | |||
125 | while p.get_available_packet_count(): | ||
126 | message_received.emit(id, get_message(id)) | ||
127 | |||
128 | for r: int in to_remove: | ||
129 | peers.erase(r) | ||
130 | to_remove.clear() | ||
131 | |||
132 | |||
133 | func _connect_pending(p: PendingPeer) -> bool: | ||
134 | if p.ws != null: | ||
135 | # Poll websocket client if doing handshake. | ||
136 | p.ws.poll() | ||
137 | var state := p.ws.get_ready_state() | ||
138 | if state == WebSocketPeer.STATE_OPEN: | ||
139 | var id := randi_range(2, 1 << 30) | ||
140 | peers[id] = p.ws | ||
141 | client_connected.emit(id) | ||
142 | return true # Success. | ||
143 | elif state != WebSocketPeer.STATE_CONNECTING: | ||
144 | return true # Failure. | ||
145 | return false # Still connecting. | ||
146 | elif p.tcp.get_status() != StreamPeerTCP.STATUS_CONNECTED: | ||
147 | return true # TCP disconnected. | ||
148 | elif not use_tls: | ||
149 | # TCP is ready, create WS peer. | ||
150 | p.ws = _create_peer() | ||
151 | p.ws.accept_stream(p.tcp) | ||
152 | return false # WebSocketPeer connection is pending. | ||
153 | |||
154 | else: | ||
155 | if p.connection == p.tcp: | ||
156 | assert(tls_key != null and tls_cert != null) | ||
157 | var tls := StreamPeerTLS.new() | ||
158 | tls.accept_stream(p.tcp, TLSOptions.server(tls_key, tls_cert)) | ||
159 | p.connection = tls | ||
160 | p.connection.poll() | ||
161 | var status: StreamPeerTLS.Status = p.connection.get_status() | ||
162 | if status == StreamPeerTLS.STATUS_CONNECTED: | ||
163 | p.ws = _create_peer() | ||
164 | p.ws.accept_stream(p.connection) | ||
165 | return false # WebSocketPeer connection is pending. | ||
166 | if status != StreamPeerTLS.STATUS_HANDSHAKING: | ||
167 | return true # Failure. | ||
168 | |||
169 | return false | ||
170 | |||
171 | |||
172 | func _process(_delta: float) -> void: | ||
173 | poll() | ||
diff --git a/apworld/client/victoryListener.gd b/apworld/client/victoryListener.gd new file mode 100644 index 0000000..e9089d7 --- /dev/null +++ b/apworld/client/victoryListener.gd | |||
@@ -0,0 +1,20 @@ | |||
1 | extends Receiver | ||
2 | |||
3 | |||
4 | func _ready(): | ||
5 | super._ready() | ||
6 | |||
7 | |||
8 | func handleTriggered(): | ||
9 | triggered += 1 | ||
10 | if triggered >= total: | ||
11 | var ap = global.get_node("Archipelago") | ||
12 | ap.client.completedGoal() | ||
13 | |||
14 | global.get_node("Messages").showMessage("You have completed your goal!") | ||
15 | |||
16 | |||
17 | func handleUntriggered(): | ||
18 | triggered -= 1 | ||
19 | if triggered < total: | ||
20 | pass | ||
diff --git a/apworld/client/visibilityListener.gd b/apworld/client/visibilityListener.gd new file mode 100644 index 0000000..5ea17a0 --- /dev/null +++ b/apworld/client/visibilityListener.gd | |||
@@ -0,0 +1,38 @@ | |||
1 | extends "res://scripts/nodes/listeners/visibilityListener.gd" | ||
2 | |||
3 | var item_id | ||
4 | var item_amount | ||
5 | |||
6 | |||
7 | func _ready(): | ||
8 | var node_path = String( | ||
9 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
10 | ) | ||
11 | |||
12 | var gamedata = global.get_node("Gamedata") | ||
13 | var door_id = gamedata.get_door_for_map_node_path(global.map, node_path) | ||
14 | if door_id != null: | ||
15 | var ap = global.get_node("Archipelago") | ||
16 | var item_lock = ap.get_item_id_for_door(door_id) | ||
17 | |||
18 | if item_lock != null: | ||
19 | item_id = item_lock[0] | ||
20 | item_amount = item_lock[1] | ||
21 | |||
22 | self.senders = [] | ||
23 | self.senderGroup = [] | ||
24 | self.nested = false | ||
25 | self.complete_at = 0 | ||
26 | self.max_length = 0 | ||
27 | self.excludeSenders = [] | ||
28 | |||
29 | call_deferred("_readier") | ||
30 | |||
31 | super._ready() | ||
32 | |||
33 | |||
34 | func _readier(): | ||
35 | var ap = global.get_node("Archipelago") | ||
36 | |||
37 | if ap.client.getItemAmount(item_id) >= item_amount: | ||
38 | handleTriggered() | ||
diff --git a/apworld/client/worldport.gd b/apworld/client/worldport.gd new file mode 100644 index 0000000..ed9891e --- /dev/null +++ b/apworld/client/worldport.gd | |||
@@ -0,0 +1,61 @@ | |||
1 | extends "res://scripts/nodes/worldport.gd" | ||
2 | |||
3 | var absolute_rotation = false | ||
4 | var target_rotation = 0 | ||
5 | |||
6 | var port_id = null | ||
7 | |||
8 | |||
9 | func _ready(): | ||
10 | var node_path = String( | ||
11 | get_tree().get_root().get_node("scene").get_path_to(self).get_concatenated_names() | ||
12 | ) | ||
13 | |||
14 | var ap = global.get_node("Archipelago") | ||
15 | |||
16 | if ap.shuffle_worldports: | ||
17 | var gamedata = global.get_node("Gamedata") | ||
18 | port_id = gamedata.get_port_for_map_node_path(global.map, node_path) | ||
19 | if port_id != null: | ||
20 | if port_id in ap.port_pairings: | ||
21 | var target_port = gamedata.objects.get_ports()[ap.port_pairings[port_id]] | ||
22 | var target_room = gamedata.objects.get_rooms()[target_port.get_room_id()] | ||
23 | var target_map = gamedata.objects.get_maps()[target_room.get_map_id()] | ||
24 | |||
25 | exit = target_map.get_name() | ||
26 | entry_point.x = target_port.get_destination().get_x() | ||
27 | entry_point.y = target_port.get_destination().get_y() | ||
28 | entry_point.z = target_port.get_destination().get_z() | ||
29 | absolute_rotation = true | ||
30 | target_rotation = target_port.get_rotation() | ||
31 | sets_entry_point = true | ||
32 | invisible = false | ||
33 | fades = true | ||
34 | else: | ||
35 | port_id = null | ||
36 | |||
37 | if global.map == "icarus" and exit == "daedalus": | ||
38 | if not ap.daedalus_roof_access: | ||
39 | entry_point = Vector3(58, 10, 0) | ||
40 | |||
41 | super._ready() | ||
42 | |||
43 | |||
44 | func bodyEntered(body): | ||
45 | if body.is_in_group("player"): | ||
46 | if port_id != null: | ||
47 | var ap = global.get_node("Archipelago") | ||
48 | ap.client.checkWorldport(port_id) | ||
49 | |||
50 | if absolute_rotation: | ||
51 | entry_rotate.y = target_rotation - body.rotation_degrees.y | ||
52 | |||
53 | super.bodyEntered(body) | ||
54 | |||
55 | |||
56 | func changeScene(): | ||
57 | var player = get_tree().get_root().get_node("scene/player") | ||
58 | if player != null: | ||
59 | player.playable = false | ||
60 | |||
61 | super.changeScene() | ||
diff --git a/apworld/client/worldportListener.gd b/apworld/client/worldportListener.gd new file mode 100644 index 0000000..4cff8e9 --- /dev/null +++ b/apworld/client/worldportListener.gd | |||
@@ -0,0 +1,8 @@ | |||
1 | extends "res://scripts/nodes/listeners/worldportListener.gd" | ||
2 | |||
3 | |||
4 | func handleTriggered(): | ||
5 | if exit.begins_with("menus/credits"): | ||
6 | return | ||
7 | |||
8 | super.handleTriggered() | ||
diff --git a/apworld/context.py b/apworld/context.py new file mode 100644 index 0000000..a0ee34d --- /dev/null +++ b/apworld/context.py | |||
@@ -0,0 +1,654 @@ | |||
1 | import asyncio | ||
2 | import os | ||
3 | import pkgutil | ||
4 | import subprocess | ||
5 | import sys | ||
6 | from typing import Any | ||
7 | |||
8 | import websockets | ||
9 | |||
10 | import Utils | ||
11 | import settings | ||
12 | from BaseClasses import ItemClassification | ||
13 | from CommonClient import CommonContext, server_loop, gui_enabled, logger, get_base_parser, handle_url_arg | ||
14 | from NetUtils import Endpoint, decode, encode, ClientStatus | ||
15 | from Utils import async_start | ||
16 | from . import Lingo2World | ||
17 | from .tracker import Tracker | ||
18 | |||
19 | ALL_LETTERS = "abcdefghijklmnopqrstuvwxyz" | ||
20 | MESSAGE_MAX_SIZE = 16*1024*1024 | ||
21 | PORT = 43182 | ||
22 | |||
23 | KEY_STORAGE_MAPPING = { | ||
24 | "a": (1, 0), "b": (1, 1), "c": (1, 2), "d": (1, 3), "e": (1, 4), "f": (1, 5), "g": (1, 6), "h": (1, 7), "i": (1, 8), | ||
25 | "j": (1, 9), "k": (1, 10), "l": (1, 11), "m": (1, 12), "n": (2, 0), "o": (2, 1), "p": (2, 2), "q": (2, 3), | ||
26 | "r": (2, 4), "s": (2, 5), "t": (2, 6), "u": (2, 7), "v": (2, 8), "w": (2, 9), "x": (2, 10), "y": (2, 11), | ||
27 | "z": (2, 12), | ||
28 | } | ||
29 | |||
30 | REVERSE_KEY_STORAGE_MAPPING = {t: k for k, t in KEY_STORAGE_MAPPING.items()} | ||
31 | |||
32 | |||
33 | class Lingo2Manager: | ||
34 | game_ctx: "Lingo2GameContext" | ||
35 | client_ctx: "Lingo2ClientContext" | ||
36 | tracker: Tracker | ||
37 | |||
38 | keyboard: dict[str, int] | ||
39 | worldports: set[int] | ||
40 | goaled: bool | ||
41 | |||
42 | def __init__(self, game_ctx: "Lingo2GameContext", client_ctx: "Lingo2ClientContext"): | ||
43 | self.game_ctx = game_ctx | ||
44 | self.game_ctx.manager = self | ||
45 | self.client_ctx = client_ctx | ||
46 | self.client_ctx.manager = self | ||
47 | self.tracker = Tracker(self) | ||
48 | self.keyboard = {} | ||
49 | self.worldports = set() | ||
50 | |||
51 | self.reset() | ||
52 | |||
53 | def reset(self): | ||
54 | for k in ALL_LETTERS: | ||
55 | self.keyboard[k] = 0 | ||
56 | |||
57 | self.worldports = set() | ||
58 | self.goaled = False | ||
59 | |||
60 | def update_keyboard(self, new_keyboard: dict[str, int]) -> dict[str, int]: | ||
61 | ret: dict[str, int] = {} | ||
62 | |||
63 | for k, v in new_keyboard.items(): | ||
64 | if v > self.keyboard.get(k, 0): | ||
65 | self.keyboard[k] = v | ||
66 | ret[k] = v | ||
67 | |||
68 | if len(ret) > 0: | ||
69 | self.tracker.refresh_state() | ||
70 | self.game_ctx.send_accessible_locations() | ||
71 | |||
72 | return ret | ||
73 | |||
74 | def update_worldports(self, new_worldports: set[int]) -> set[int]: | ||
75 | ret = new_worldports.difference(self.worldports) | ||
76 | self.worldports.update(new_worldports) | ||
77 | |||
78 | if len(ret) > 0: | ||
79 | self.tracker.refresh_state() | ||
80 | self.game_ctx.send_accessible_locations() | ||
81 | |||
82 | return ret | ||
83 | |||
84 | |||
85 | class Lingo2GameContext: | ||
86 | server: Endpoint | None | ||
87 | manager: Lingo2Manager | ||
88 | |||
89 | def __init__(self): | ||
90 | self.server = None | ||
91 | |||
92 | def send_connected(self): | ||
93 | if self.server is None: | ||
94 | return | ||
95 | |||
96 | msg = { | ||
97 | "cmd": "Connected", | ||
98 | "user": self.manager.client_ctx.username, | ||
99 | "seed_name": self.manager.client_ctx.seed_name, | ||
100 | "version": self.manager.client_ctx.server_version, | ||
101 | "generator_version": self.manager.client_ctx.generator_version, | ||
102 | "team": self.manager.client_ctx.team, | ||
103 | "slot": self.manager.client_ctx.slot, | ||
104 | "checked_locations": self.manager.client_ctx.checked_locations, | ||
105 | "slot_data": self.manager.client_ctx.slot_data, | ||
106 | } | ||
107 | |||
108 | async_start(self.send_msgs([msg]), name="game Connected") | ||
109 | |||
110 | def send_connection_refused(self, text): | ||
111 | if self.server is None: | ||
112 | return | ||
113 | |||
114 | msg = { | ||
115 | "cmd": "ConnectionRefused", | ||
116 | "text": text, | ||
117 | } | ||
118 | |||
119 | async_start(self.send_msgs([msg]), name="game ConnectionRefused") | ||
120 | |||
121 | def send_item_sent_notification(self, item_name, receiver_name, item_flags): | ||
122 | if self.server is None: | ||
123 | return | ||
124 | |||
125 | msg = { | ||
126 | "cmd": "ItemSentNotif", | ||
127 | "item_name": item_name, | ||
128 | "receiver_name": receiver_name, | ||
129 | "item_flags": item_flags, | ||
130 | } | ||
131 | |||
132 | async_start(self.send_msgs([msg]), name="item sent notif") | ||
133 | |||
134 | def send_hint_received(self, item_name, location_name, receiver_name, item_flags, for_self): | ||
135 | if self.server is None: | ||
136 | return | ||
137 | |||
138 | msg = { | ||
139 | "cmd": "HintReceived", | ||
140 | "item_name": item_name, | ||
141 | "location_name": location_name, | ||
142 | "receiver_name": receiver_name, | ||
143 | "item_flags": item_flags, | ||
144 | "self": int(for_self), | ||
145 | } | ||
146 | |||
147 | async_start(self.send_msgs([msg]), name="hint received notif") | ||
148 | |||
149 | def send_item_received(self, items): | ||
150 | if self.server is None: | ||
151 | return | ||
152 | |||
153 | msg = { | ||
154 | "cmd": "ItemReceived", | ||
155 | "items": items, | ||
156 | } | ||
157 | |||
158 | async_start(self.send_msgs([msg]), name="item received") | ||
159 | |||
160 | def send_location_info(self, locations): | ||
161 | if self.server is None: | ||
162 | return | ||
163 | |||
164 | msg = { | ||
165 | "cmd": "LocationInfo", | ||
166 | "locations": locations, | ||
167 | } | ||
168 | |||
169 | async_start(self.send_msgs([msg]), name="location info") | ||
170 | |||
171 | def send_text_message(self, parts): | ||
172 | if self.server is None: | ||
173 | return | ||
174 | |||
175 | msg = { | ||
176 | "cmd": "TextMessage", | ||
177 | "data": parts, | ||
178 | } | ||
179 | |||
180 | async_start(self.send_msgs([msg]), name="notif") | ||
181 | |||
182 | def send_accessible_locations(self): | ||
183 | if self.server is None: | ||
184 | return | ||
185 | |||
186 | msg = { | ||
187 | "cmd": "AccessibleLocations", | ||
188 | "locations": list(self.manager.tracker.accessible_locations), | ||
189 | } | ||
190 | |||
191 | if len(self.manager.tracker.accessible_worldports) > 0: | ||
192 | msg["worldports"] = list(self.manager.tracker.accessible_worldports) | ||
193 | |||
194 | if self.manager.tracker.goal_accessible and not self.manager.goaled: | ||
195 | msg["goal"] = True | ||
196 | |||
197 | async_start(self.send_msgs([msg]), name="accessible locations") | ||
198 | |||
199 | def send_update_locations(self, locations): | ||
200 | if self.server is None: | ||
201 | return | ||
202 | |||
203 | msg = { | ||
204 | "cmd": "UpdateLocations", | ||
205 | "locations": locations, | ||
206 | } | ||
207 | |||
208 | async_start(self.send_msgs([msg]), name="update locations") | ||
209 | |||
210 | def send_update_keyboard(self, updates): | ||
211 | if self.server is None: | ||
212 | return | ||
213 | |||
214 | msg = { | ||
215 | "cmd": "UpdateKeyboard", | ||
216 | "updates": updates, | ||
217 | } | ||
218 | |||
219 | async_start(self.send_msgs([msg]), name="update keyboard") | ||
220 | |||
221 | def send_update_worldports(self, worldports): | ||
222 | if self.server is None: | ||
223 | return | ||
224 | |||
225 | msg = { | ||
226 | "cmd": "UpdateWorldports", | ||
227 | "worldports": worldports, | ||
228 | } | ||
229 | |||
230 | async_start(self.send_msgs([msg]), name="update worldports") | ||
231 | |||
232 | def send_path_reply(self, object_type: str, object_id: int | None, path: list[str]): | ||
233 | if self.server is None: | ||
234 | return | ||
235 | |||
236 | msg = { | ||
237 | "cmd": "PathReply", | ||
238 | "type": object_type, | ||
239 | "path": path, | ||
240 | } | ||
241 | |||
242 | if object_id is not None: | ||
243 | msg["id"] = object_id | ||
244 | |||
245 | async_start(self.send_msgs([msg]), name="path reply") | ||
246 | |||
247 | async def send_msgs(self, msgs: list[Any]) -> None: | ||
248 | """ `msgs` JSON serializable """ | ||
249 | if not self.server or not self.server.socket.open or self.server.socket.closed: | ||
250 | return | ||
251 | await self.server.socket.send(encode(msgs)) | ||
252 | |||
253 | |||
254 | class Lingo2ClientContext(CommonContext): | ||
255 | manager: Lingo2Manager | ||
256 | |||
257 | game = "Lingo 2" | ||
258 | items_handling = 0b111 | ||
259 | |||
260 | slot_data: dict[str, Any] | None | ||
261 | victory_data_storage_key: str | ||
262 | |||
263 | def __init__(self, server_address: str | None = None, password: str | None = None): | ||
264 | super().__init__(server_address, password) | ||
265 | |||
266 | def make_gui(self): | ||
267 | ui = super().make_gui() | ||
268 | ui.base_title = "Archipelago Lingo 2 Client" | ||
269 | return ui | ||
270 | |||
271 | async def server_auth(self, password_requested: bool = False): | ||
272 | if password_requested and not self.password: | ||
273 | self.manager.game_ctx.send_connection_refused("Invalid password.") | ||
274 | else: | ||
275 | self.auth = self.username | ||
276 | await self.send_connect() | ||
277 | |||
278 | def handle_connection_loss(self, msg: str): | ||
279 | super().handle_connection_loss(msg) | ||
280 | |||
281 | exc_info = sys.exc_info() | ||
282 | self.manager.game_ctx.send_connection_refused(str(exc_info[1])) | ||
283 | |||
284 | def on_package(self, cmd: str, args: dict): | ||
285 | if cmd == "RoomInfo": | ||
286 | self.seed_name = args.get("seed_name", None) | ||
287 | elif cmd == "Connected": | ||
288 | self.slot_data = args.get("slot_data", None) | ||
289 | |||
290 | self.manager.reset() | ||
291 | |||
292 | self.manager.game_ctx.send_connected() | ||
293 | |||
294 | self.manager.tracker.setup_slot(self.slot_data) | ||
295 | self.manager.tracker.set_checked_locations(self.checked_locations) | ||
296 | self.manager.game_ctx.send_accessible_locations() | ||
297 | |||
298 | self.victory_data_storage_key = f"_read_client_status_{self.team}_{self.slot}" | ||
299 | |||
300 | self.set_notify(self.get_datastorage_key("keyboard1"), self.get_datastorage_key("keyboard2"), | ||
301 | self.victory_data_storage_key) | ||
302 | msg_batch = [{ | ||
303 | "cmd": "Set", | ||
304 | "key": self.get_datastorage_key("keyboard1"), | ||
305 | "default": 0, | ||
306 | "want_reply": True, | ||
307 | "operations": [{"operation": "default", "value": 0}] | ||
308 | }, { | ||
309 | "cmd": "Set", | ||
310 | "key": self.get_datastorage_key("keyboard2"), | ||
311 | "default": 0, | ||
312 | "want_reply": True, | ||
313 | "operations": [{"operation": "default", "value": 0}] | ||
314 | }] | ||
315 | |||
316 | if self.slot_data.get("shuffle_worldports", False): | ||
317 | self.set_notify(self.get_datastorage_key("worldports")) | ||
318 | msg_batch.append({ | ||
319 | "cmd": "Set", | ||
320 | "key": self.get_datastorage_key("worldports"), | ||
321 | "default": [], | ||
322 | "want_reply": True, | ||
323 | "operations": [{"operation": "default", "value": []}] | ||
324 | }) | ||
325 | |||
326 | async_start(self.send_msgs(msg_batch), name="default keys") | ||
327 | elif cmd == "RoomUpdate": | ||
328 | if "checked_locations" in args: | ||
329 | self.manager.tracker.set_checked_locations(self.checked_locations) | ||
330 | self.manager.game_ctx.send_update_locations(args["checked_locations"]) | ||
331 | elif cmd == "ReceivedItems": | ||
332 | self.manager.tracker.set_collected_items(self.items_received) | ||
333 | |||
334 | cur_index = 0 | ||
335 | items = [] | ||
336 | |||
337 | for item in args["items"]: | ||
338 | index = cur_index + args["index"] | ||
339 | cur_index += 1 | ||
340 | |||
341 | item_msg = { | ||
342 | "id": item.item, | ||
343 | "index": index, | ||
344 | "flags": item.flags, | ||
345 | "text": self.item_names.lookup_in_slot(item.item, self.slot), | ||
346 | } | ||
347 | |||
348 | if item.player != self.slot: | ||
349 | item_msg["sender"] = self.player_names.get(item.player) | ||
350 | |||
351 | items.append(item_msg) | ||
352 | |||
353 | self.manager.game_ctx.send_item_received(items) | ||
354 | |||
355 | if any(ItemClassification.progression in ItemClassification(item.flags) for item in args["items"]): | ||
356 | self.manager.game_ctx.send_accessible_locations() | ||
357 | elif cmd == "PrintJSON": | ||
358 | if "receiving" in args and "item" in args and args["item"].player == self.slot: | ||
359 | item_name = self.item_names.lookup_in_slot(args["item"].item, args["receiving"]) | ||
360 | location_name = self.location_names.lookup_in_slot(args["item"].location, args["item"].player) | ||
361 | receiver_name = self.player_names.get(args["receiving"]) | ||
362 | |||
363 | if args["type"] == "Hint" and not args.get("found", False): | ||
364 | self.manager.game_ctx.send_hint_received(item_name, location_name, receiver_name, args["item"].flags, | ||
365 | int(args["receiving"]) == self.slot) | ||
366 | elif args["receiving"] != self.slot: | ||
367 | self.manager.game_ctx.send_item_sent_notification(item_name, receiver_name, args["item"].flags) | ||
368 | |||
369 | parts = [] | ||
370 | for message_part in args["data"]: | ||
371 | if "type" not in message_part and "text" in message_part: | ||
372 | parts.append({"type": "text", "text": message_part["text"]}) | ||
373 | elif message_part["type"] == "player_id": | ||
374 | parts.append({ | ||
375 | "type": "player", | ||
376 | "text": self.player_names.get(int(message_part["text"])), | ||
377 | "self": int(int(message_part["text"]) == self.slot), | ||
378 | }) | ||
379 | elif message_part["type"] == "item_id": | ||
380 | parts.append({ | ||
381 | "type": "item", | ||
382 | "text": self.item_names.lookup_in_slot(int(message_part["text"]), message_part["player"]), | ||
383 | "flags": message_part["flags"], | ||
384 | }) | ||
385 | elif message_part["type"] == "location_id": | ||
386 | parts.append({ | ||
387 | "type": "location", | ||
388 | "text": self.location_names.lookup_in_slot(int(message_part["text"]), | ||
389 | message_part["player"]) | ||
390 | }) | ||
391 | elif "text" in message_part: | ||
392 | parts.append({"type": "text", "text": message_part["text"]}) | ||
393 | |||
394 | self.manager.game_ctx.send_text_message(parts) | ||
395 | elif cmd == "LocationInfo": | ||
396 | locations = [] | ||
397 | |||
398 | for location in args["locations"]: | ||
399 | locations.append({ | ||
400 | "id": location.location, | ||
401 | "item": self.item_names.lookup_in_slot(location.item, location.player), | ||
402 | "player": self.player_names.get(location.player), | ||
403 | "flags": location.flags, | ||
404 | "self": int(location.player) == self.slot, | ||
405 | }) | ||
406 | |||
407 | self.manager.game_ctx.send_location_info(locations) | ||
408 | elif cmd == "Retrieved": | ||
409 | for k, v in args["keys"].items(): | ||
410 | if k == self.victory_data_storage_key: | ||
411 | self.handle_status_update(v) | ||
412 | elif cmd == "SetReply": | ||
413 | if args["key"] == self.get_datastorage_key("keyboard1"): | ||
414 | self.handle_keyboard_update(1, args) | ||
415 | elif args["key"] == self.get_datastorage_key("keyboard2"): | ||
416 | self.handle_keyboard_update(2, args) | ||
417 | elif args["key"] == self.get_datastorage_key("worldports"): | ||
418 | updates = self.manager.update_worldports(set(args["value"])) | ||
419 | if len(updates) > 0: | ||
420 | self.manager.game_ctx.send_update_worldports(updates) | ||
421 | elif args["key"] == self.victory_data_storage_key: | ||
422 | self.handle_status_update(args["value"]) | ||
423 | |||
424 | def get_datastorage_key(self, name: str): | ||
425 | return f"Lingo2_{self.slot}_{name}" | ||
426 | |||
427 | async def update_keyboard(self, updates: dict[str, int]): | ||
428 | kb1 = 0 | ||
429 | kb2 = 0 | ||
430 | |||
431 | for k, v in updates.items(): | ||
432 | if v == 0: | ||
433 | continue | ||
434 | |||
435 | effect = 0 | ||
436 | if v >= 1: | ||
437 | effect |= 1 | ||
438 | if v == 2: | ||
439 | effect |= 2 | ||
440 | |||
441 | pos = KEY_STORAGE_MAPPING[k] | ||
442 | if pos[0] == 1: | ||
443 | kb1 |= (effect << pos[1] * 2) | ||
444 | else: | ||
445 | kb2 |= (effect << pos[1] * 2) | ||
446 | |||
447 | msgs = [] | ||
448 | |||
449 | if kb1 != 0: | ||
450 | msgs.append({ | ||
451 | "cmd": "Set", | ||
452 | "key": self.get_datastorage_key("keyboard1"), | ||
453 | "want_reply": True, | ||
454 | "operations": [{ | ||
455 | "operation": "or", | ||
456 | "value": kb1 | ||
457 | }] | ||
458 | }) | ||
459 | |||
460 | if kb2 != 0: | ||
461 | msgs.append({ | ||
462 | "cmd": "Set", | ||
463 | "key": self.get_datastorage_key("keyboard2"), | ||
464 | "want_reply": True, | ||
465 | "operations": [{ | ||
466 | "operation": "or", | ||
467 | "value": kb2 | ||
468 | }] | ||
469 | }) | ||
470 | |||
471 | if len(msgs) > 0: | ||
472 | await self.send_msgs(msgs) | ||
473 | |||
474 | def handle_keyboard_update(self, field: int, args: dict[str, Any]): | ||
475 | keys = {} | ||
476 | value = args["value"] | ||
477 | |||
478 | for i in range(0, 13): | ||
479 | if (value & (1 << (i * 2))) != 0: | ||
480 | keys[REVERSE_KEY_STORAGE_MAPPING[(field, i)]] = 1 | ||
481 | if (value & (1 << (i * 2 + 1))) != 0: | ||
482 | keys[REVERSE_KEY_STORAGE_MAPPING[(field, i)]] = 2 | ||
483 | |||
484 | updates = self.manager.update_keyboard(keys) | ||
485 | if len(updates) > 0: | ||
486 | self.manager.game_ctx.send_update_keyboard(updates) | ||
487 | |||
488 | async def update_worldports(self, updates: set[int]): | ||
489 | await self.send_msgs([{ | ||
490 | "cmd": "Set", | ||
491 | "key": self.get_datastorage_key("worldports"), | ||
492 | "want_reply": True, | ||
493 | "operations": [{ | ||
494 | "operation": "update", | ||
495 | "value": updates | ||
496 | }] | ||
497 | }]) | ||
498 | |||
499 | def handle_status_update(self, value: int): | ||
500 | self.manager.goaled = (value == ClientStatus.CLIENT_GOAL) | ||
501 | self.manager.tracker.refresh_state() | ||
502 | self.manager.game_ctx.send_accessible_locations() | ||
503 | |||
504 | |||
505 | async def pipe_loop(manager: Lingo2Manager): | ||
506 | while not manager.client_ctx.exit_event.is_set(): | ||
507 | try: | ||
508 | socket = await websockets.connect("ws://localhost", port=PORT, ping_timeout=None, ping_interval=None, | ||
509 | max_size=MESSAGE_MAX_SIZE) | ||
510 | manager.game_ctx.server = Endpoint(socket) | ||
511 | logger.info("Connected to Lingo 2!") | ||
512 | if manager.client_ctx.auth is not None: | ||
513 | manager.game_ctx.send_connected() | ||
514 | manager.game_ctx.send_accessible_locations() | ||
515 | async for data in manager.game_ctx.server.socket: | ||
516 | for msg in decode(data): | ||
517 | await process_game_cmd(manager, msg) | ||
518 | except ConnectionRefusedError: | ||
519 | logger.info("Could not connect to Lingo 2.") | ||
520 | finally: | ||
521 | manager.game_ctx.server = None | ||
522 | |||
523 | |||
524 | async def process_game_cmd(manager: Lingo2Manager, args: dict): | ||
525 | cmd = args["cmd"] | ||
526 | |||
527 | if cmd == "Connect": | ||
528 | manager.client_ctx.seed_name = None | ||
529 | |||
530 | server = args.get("server") | ||
531 | player = args.get("player") | ||
532 | password = args.get("password") | ||
533 | |||
534 | if password != "": | ||
535 | server_address = f"{player}:{password}@{server}" | ||
536 | else: | ||
537 | server_address = f"{player}:None@{server}" | ||
538 | |||
539 | async_start(manager.client_ctx.connect(server_address), name="client connect") | ||
540 | elif cmd == "Disconnect": | ||
541 | manager.client_ctx.seed_name = None | ||
542 | |||
543 | async_start(manager.client_ctx.disconnect(), name="client disconnect") | ||
544 | elif cmd in ["Sync", "LocationChecks", "Say", "StatusUpdate", "LocationScouts"]: | ||
545 | async_start(manager.client_ctx.send_msgs([args]), name="client forward") | ||
546 | elif cmd == "UpdateKeyboard": | ||
547 | updates = manager.update_keyboard(args["keyboard"]) | ||
548 | if len(updates) > 0: | ||
549 | async_start(manager.client_ctx.update_keyboard(updates), name="client update keyboard") | ||
550 | elif cmd == "CheckWorldport": | ||
551 | port_id = args["port_id"] | ||
552 | worldports = {port_id} | ||
553 | if str(port_id) in manager.client_ctx.slot_data["port_pairings"]: | ||
554 | worldports.add(manager.client_ctx.slot_data["port_pairings"][str(port_id)]) | ||
555 | |||
556 | updates = manager.update_worldports(worldports) | ||
557 | if len(updates) > 0: | ||
558 | async_start(manager.client_ctx.update_worldports(updates), name="client update worldports") | ||
559 | manager.game_ctx.send_update_worldports(updates) | ||
560 | elif cmd == "GetPath": | ||
561 | path = None | ||
562 | |||
563 | if args["type"] == "location": | ||
564 | path = manager.tracker.get_path_to_location(args["id"]) | ||
565 | elif args["type"] == "worldport": | ||
566 | path = manager.tracker.get_path_to_port(args["id"]) | ||
567 | elif args["type"] == "goal": | ||
568 | path = manager.tracker.get_path_to_goal() | ||
569 | |||
570 | manager.game_ctx.send_path_reply(args["type"], args.get("id", None), path) | ||
571 | elif cmd == "Quit": | ||
572 | manager.client_ctx.exit_event.set() | ||
573 | |||
574 | |||
575 | async def run_game(): | ||
576 | exe_file = settings.get_settings().lingo2_options.exe_file | ||
577 | |||
578 | # This ensures we can use Steam features without having to open the game | ||
579 | # through steam. | ||
580 | steam_appid_path = os.path.join(os.path.dirname(exe_file), "steam_appid.txt") | ||
581 | with open(steam_appid_path, "w") as said_handle: | ||
582 | said_handle.write("2523310") | ||
583 | |||
584 | if Lingo2World.zip_path is not None: | ||
585 | # This is a packaged apworld. | ||
586 | init_scene = pkgutil.get_data(__name__, "client/run_from_apworld.tscn") | ||
587 | init_path = Utils.local_path("data", "lingo2_init.tscn") | ||
588 | |||
589 | with open(init_path, "wb") as file_handle: | ||
590 | file_handle.write(init_scene) | ||
591 | |||
592 | subprocess.Popen( | ||
593 | [ | ||
594 | exe_file, | ||
595 | "--scene", | ||
596 | init_path, | ||
597 | "--", | ||
598 | str(Lingo2World.zip_path.absolute()), | ||
599 | ], | ||
600 | cwd=os.path.dirname(exe_file), | ||
601 | ) | ||
602 | else: | ||
603 | # The world is unzipped and being run in source. | ||
604 | subprocess.Popen( | ||
605 | [ | ||
606 | exe_file, | ||
607 | "--scene", | ||
608 | Utils.local_path("worlds", "lingo2", "client", "run_from_source.tscn"), | ||
609 | "--", | ||
610 | Utils.local_path("worlds", "lingo2", "client"), | ||
611 | ], | ||
612 | cwd=os.path.dirname(exe_file), | ||
613 | ) | ||
614 | |||
615 | |||
616 | def client_main(*launch_args: str) -> None: | ||
617 | async def main(args): | ||
618 | if settings.get_settings().lingo2_options.start_game: | ||
619 | async_start(run_game()) | ||
620 | |||
621 | client_ctx = Lingo2ClientContext(args.connect, args.password) | ||
622 | game_ctx = Lingo2GameContext() | ||
623 | manager = Lingo2Manager(game_ctx, client_ctx) | ||
624 | |||
625 | client_ctx.server_task = asyncio.create_task(server_loop(client_ctx), name="ServerLoop") | ||
626 | |||
627 | if gui_enabled: | ||
628 | client_ctx.run_gui() | ||
629 | client_ctx.run_cli() | ||
630 | |||
631 | pipe_task = asyncio.create_task(pipe_loop(manager), name="GameWatcher") | ||
632 | |||
633 | try: | ||
634 | await pipe_task | ||
635 | except Exception as e: | ||
636 | logger.exception(e) | ||
637 | |||
638 | await client_ctx.exit_event.wait() | ||
639 | client_ctx.ui.stop() | ||
640 | await client_ctx.shutdown() | ||
641 | |||
642 | Utils.init_logging("Lingo2Client", exception_logger="Client") | ||
643 | import colorama | ||
644 | |||
645 | parser = get_base_parser(description="Lingo 2 Archipelago Client") | ||
646 | parser.add_argument('--name', default=None, help="Slot Name to connect as.") | ||
647 | parser.add_argument("url", nargs="?", help="Archipelago connection url") | ||
648 | args = parser.parse_args(launch_args) | ||
649 | |||
650 | args = handle_url_arg(args, parser=parser) | ||
651 | |||
652 | colorama.just_fix_windows_console() | ||
653 | asyncio.run(main(args)) | ||
654 | colorama.deinit() | ||
diff --git a/apworld/docs/en_Lingo_2.md b/apworld/docs/en_Lingo_2.md new file mode 100644 index 0000000..977795a --- /dev/null +++ b/apworld/docs/en_Lingo_2.md | |||
@@ -0,0 +1,4 @@ | |||
1 | # Lingo 2 | ||
2 | |||
3 | See [the project README](https://code.fourisland.com/lingo2-archipelago/about/) | ||
4 | for installation instructions and frequently asked questions. \ No newline at end of file | ||
diff --git a/apworld/items.py b/apworld/items.py index 971a709..28158c3 100644 --- a/apworld/items.py +++ b/apworld/items.py | |||
@@ -1,5 +1,31 @@ | |||
1 | from .generated import data_pb2 as data_pb2 | ||
1 | from BaseClasses import Item | 2 | from BaseClasses import Item |
2 | 3 | ||
3 | 4 | ||
4 | class Lingo2Item(Item): | 5 | class Lingo2Item(Item): |
5 | game: str = "Lingo 2" | 6 | game: str = "Lingo 2" |
7 | |||
8 | |||
9 | SYMBOL_ITEMS: dict[data_pb2.PuzzleSymbol, str] = { | ||
10 | data_pb2.PuzzleSymbol.SUN: "Sun Symbol", | ||
11 | data_pb2.PuzzleSymbol.SPARKLES: "Sparkles Symbol", | ||
12 | data_pb2.PuzzleSymbol.ZERO: "Zero Symbol", | ||
13 | data_pb2.PuzzleSymbol.EXAMPLE: "Example Symbol", | ||
14 | data_pb2.PuzzleSymbol.BOXES: "Boxes Symbol", | ||
15 | data_pb2.PuzzleSymbol.PLANET: "Planet Symbol", | ||
16 | data_pb2.PuzzleSymbol.PYRAMID: "Pyramid Symbol", | ||
17 | data_pb2.PuzzleSymbol.CROSS: "Cross Symbol", | ||
18 | data_pb2.PuzzleSymbol.SWEET: "Sweet Symbol", | ||
19 | data_pb2.PuzzleSymbol.GENDER: "Gender Symbol", | ||
20 | data_pb2.PuzzleSymbol.AGE: "Age Symbol", | ||
21 | data_pb2.PuzzleSymbol.SOUND: "Sound Symbol", | ||
22 | data_pb2.PuzzleSymbol.ANAGRAM: "Anagram Symbol", | ||
23 | data_pb2.PuzzleSymbol.JOB: "Job Symbol", | ||
24 | data_pb2.PuzzleSymbol.STARS: "Stars Symbol", | ||
25 | data_pb2.PuzzleSymbol.NULL: "Null Symbol", | ||
26 | data_pb2.PuzzleSymbol.EVAL: "Eval Symbol", | ||
27 | data_pb2.PuzzleSymbol.LINGO: "Lingo Symbol", | ||
28 | data_pb2.PuzzleSymbol.QUESTION: "Question Symbol", | ||
29 | } | ||
30 | |||
31 | ANTI_COLLECTABLE_TRAPS: list[str] = [f"Anti {letter}" for letter in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"] | ||
diff --git a/apworld/locations.py b/apworld/locations.py index 108decb..3d619dc 100644 --- a/apworld/locations.py +++ b/apworld/locations.py | |||
@@ -3,3 +3,6 @@ from BaseClasses import Location | |||
3 | 3 | ||
4 | class Lingo2Location(Location): | 4 | class Lingo2Location(Location): |
5 | game: str = "Lingo 2" | 5 | game: str = "Lingo 2" |
6 | |||
7 | port_id: int | ||
8 | goal: bool | ||
diff --git a/apworld/logo.png b/apworld/logo.png new file mode 100644 index 0000000..b9d00ba --- /dev/null +++ b/apworld/logo.png | |||
Binary files differ | |||
diff --git a/apworld/options.py b/apworld/options.py index d984beb..3d7c9a5 100644 --- a/apworld/options.py +++ b/apworld/options.py | |||
@@ -1,15 +1,144 @@ | |||
1 | from dataclasses import dataclass | 1 | from dataclasses import dataclass |
2 | 2 | ||
3 | from Options import PerGameCommonOptions, Toggle, Choice | 3 | from Options import PerGameCommonOptions, Toggle, Choice, DefaultOnToggle, Range |
4 | 4 | ||
5 | 5 | ||
6 | class ShuffleDoors(Toggle): | 6 | class ShuffleDoors(DefaultOnToggle): |
7 | """If enabled, most doors will open from receiving an item rather than fulfilling the in-game requirements.""" | 7 | """If enabled, most doors will open from receiving an item rather than fulfilling the in-game requirements.""" |
8 | display_name = "Shuffle Doors" | 8 | display_name = "Shuffle Doors" |
9 | 9 | ||
10 | 10 | ||
11 | class ShuffleControlCenterColors(Toggle): | ||
12 | """ | ||
13 | Some doors open after solving the COLOR panel in the Control Center. If this option is enabled, these doors will | ||
14 | instead open upon receiving an item. | ||
15 | """ | ||
16 | display_name = "Shuffle Control Center Colors" | ||
17 | |||
18 | |||
19 | class ShuffleGalleryPaintings(Toggle): | ||
20 | """If enabled, gallery paintings will appear from receiving an item rather than by triggering them normally.""" | ||
21 | display_name = "Shuffle Gallery Paintings" | ||
22 | |||
23 | |||
24 | class ShuffleLetters(Choice): | ||
25 | """ | ||
26 | Controls how letter unlocks are handled. Note that H1, I1, N1, and T1 will always be present at their vanilla | ||
27 | locations in the starting room, even if letters are shuffled remotely. | ||
28 | |||
29 | - **Vanilla**: All letters will be present at their vanilla locations. | ||
30 | - **Unlocked**: Players will start with their keyboards fully unlocked. | ||
31 | - **Progressive**: Two items will be added to the pool for every letter (one for H, I, N, and T). Receiving the | ||
32 | first item gives you the corresponding level 1 letter, and the second item gives you the corresponding level 2 | ||
33 | letter. | ||
34 | - **Vanilla Cyan**: Players will start with all level 1 (purple) letters unlocked. Level 2 (cyan) letters will be | ||
35 | present at their vanilla locations. | ||
36 | - **Item Cyan**: Players will start with all level 1 (purple) letters unlocked. One item will be added to the pool | ||
37 | for every level 2 (cyan) letter. | ||
38 | """ | ||
39 | display_name = "Shuffle Letters" | ||
40 | option_vanilla = 0 | ||
41 | option_unlocked = 1 | ||
42 | option_progressive = 2 | ||
43 | option_vanilla_cyan = 3 | ||
44 | option_item_cyan = 4 | ||
45 | |||
46 | |||
47 | class ShuffleSymbols(Toggle): | ||
48 | """ | ||
49 | If enabled, 19 items will be added to the pool, representing the different symbols that can appear on a panel. | ||
50 | Players will be prevented from solving puzzles with symbols on them until all of the required symbols are unlocked. | ||
51 | """ | ||
52 | display_name = "Shuffle Symbols" | ||
53 | |||
54 | |||
55 | class ShuffleWorldports(Toggle): | ||
56 | """ | ||
57 | Randomizes the connections between maps. This affects worldports only, which are the loading zones you walk into in | ||
58 | order to change maps. This does not affect paintings, panels that teleport you, or certain other special connections | ||
59 | like the one between The Shop and Control Center. Connections that depend on placing letters in keyholders are also | ||
60 | currently not shuffled. | ||
61 | |||
62 | NOTE: It is highly recommended that you turn on Shuffle Control Center Colors when using Shuffle Worldports. Not | ||
63 | doing so runs the risk of creating an unfinishable seed. | ||
64 | """ | ||
65 | display_name = "Shuffle Worldports" | ||
66 | |||
67 | |||
68 | class KeyholderSanity(Toggle): | ||
69 | """ | ||
70 | If enabled, 26 locations will be created for placing each key into its respective Green Ending keyholder. | ||
71 | |||
72 | NOTE: This does not apply to the two disappearing keyholders in The Congruent, as they are not part of Green Ending. | ||
73 | """ | ||
74 | display_name = "Keyholder Sanity" | ||
75 | |||
76 | |||
77 | class CyanDoorBehavior(Choice): | ||
78 | """ | ||
79 | Cyan-colored doors usually only open upon unlocking double letters. Some panels also only appear upon unlocking | ||
80 | double letters. This option determines how these unlocks should behave. | ||
81 | |||
82 | - **Collect H2**: In the base game, H2 is the first double letter you are intended to collect, so cyan doors only | ||
83 | open when you collect the H2 pickup in The Repetitive. Collecting the actual pickup is still required even with | ||
84 | remote letter shuffle enabled. | ||
85 | - **Any Double Letter**: Cyan doors will open when you have unlocked any cyan letter on your keyboard. In letter | ||
86 | shuffle, this means receiving a cyan letter, not picking up a cyan letter collectable. | ||
87 | - **Item**: Cyan doors will be grouped together in a single item. | ||
88 | |||
89 | Note that some cyan doors are impacted by door shuffle (e.g. the entrance to The Tower). When door shuffle is | ||
90 | enabled, these doors won't be affected by the value of this option. | ||
91 | """ | ||
92 | display_name = "Cyan Door Behavior" | ||
93 | option_collect_h2 = 0 | ||
94 | option_any_double_letter = 1 | ||
95 | option_item = 2 | ||
96 | |||
97 | |||
98 | class DaedalusRoofAccess(Toggle): | ||
99 | """ | ||
100 | If enabled, the player will be logically expected to be able to go from the castle entrance to any part of Daedalus | ||
101 | that is open to the air. If disabled, the player will only be expected to be able to enter the castle, the moat, | ||
102 | Icarus, and the area at the bottom of the stairs. Invisible walls that become opaque as you approach them are added | ||
103 | to the level to prevent the player from accidentally breaking logic. | ||
104 | """ | ||
105 | display_name = "Allow Daedalus Roof Access" | ||
106 | |||
107 | |||
108 | class StrictPurpleEnding(DefaultOnToggle): | ||
109 | """ | ||
110 | If enabled, the player will be required to have all purple (level 1) letters in order to get Purple Ending. | ||
111 | Otherwise, some of the letters may be skippable depending on the other options. | ||
112 | """ | ||
113 | display_name = "Strict Purple Ending" | ||
114 | |||
115 | |||
116 | class StrictCyanEnding(DefaultOnToggle): | ||
117 | """ | ||
118 | If enabled, the player will be required to have all cyan (level 2) letters in order to get Cyan Ending. Otherwise, | ||
119 | at least J2, Q2, and V2 are skippable. Others may also be skippable depending on the options chosen. | ||
120 | """ | ||
121 | display_name = "Strict Cyan Ending" | ||
122 | |||
123 | |||
11 | class VictoryCondition(Choice): | 124 | class VictoryCondition(Choice): |
12 | """Victory condition.""" | 125 | """ |
126 | This option determines what your goal is. | ||
127 | |||
128 | - **Gray Ending** (The Colorful) | ||
129 | - **Purple Ending** (The Sun Temple). This ordinarily requires all level 1 (purple) letters. | ||
130 | - **Mint Ending** (typing EXIT into the keyholders in Control Center) | ||
131 | - **Black Ending** (The Graveyard) | ||
132 | - **Blue Ending** (The Words) | ||
133 | - **Cyan Ending** (The Parthenon). This ordinarily requires almost all level 2 (cyan) letters. | ||
134 | - **Red Ending** (The Tower) | ||
135 | - **Plum Ending** (The Wondrous / The Door) | ||
136 | - **Orange Ending** (the castle in Daedalus) | ||
137 | - **Gold Ending** (The Gold). This involves going through the color rooms in Daedalus. | ||
138 | - **Yellow Ending** (The Gallery). This requires unlocking all gallery paintings. | ||
139 | - **Green Ending** (The Ancient). This requires filling all keyholders with specific letters. | ||
140 | - **White Ending** (Control Center). This combines every other ending. | ||
141 | """ | ||
13 | display_name = "Victory Condition" | 142 | display_name = "Victory Condition" |
14 | option_gray_ending = 0 | 143 | option_gray_ending = 0 |
15 | option_purple_ending = 1 | 144 | option_purple_ending = 1 |
@@ -26,7 +155,26 @@ class VictoryCondition(Choice): | |||
26 | option_white_ending = 12 | 155 | option_white_ending = 12 |
27 | 156 | ||
28 | 157 | ||
158 | class TrapPercentage(Range): | ||
159 | """Replaces junk items with traps, at the specified rate.""" | ||
160 | display_name = "Trap Percentage" | ||
161 | range_start = 0 | ||
162 | range_end = 100 | ||
163 | default = 0 | ||
164 | |||
165 | |||
29 | @dataclass | 166 | @dataclass |
30 | class Lingo2Options(PerGameCommonOptions): | 167 | class Lingo2Options(PerGameCommonOptions): |
31 | shuffle_doors: ShuffleDoors | 168 | shuffle_doors: ShuffleDoors |
169 | shuffle_control_center_colors: ShuffleControlCenterColors | ||
170 | shuffle_gallery_paintings: ShuffleGalleryPaintings | ||
171 | shuffle_letters: ShuffleLetters | ||
172 | shuffle_symbols: ShuffleSymbols | ||
173 | shuffle_worldports: ShuffleWorldports | ||
174 | keyholder_sanity: KeyholderSanity | ||
175 | cyan_door_behavior: CyanDoorBehavior | ||
176 | daedalus_roof_access: DaedalusRoofAccess | ||
177 | strict_purple_ending: StrictPurpleEnding | ||
178 | strict_cyan_ending: StrictCyanEnding | ||
32 | victory_condition: VictoryCondition | 179 | victory_condition: VictoryCondition |
180 | trap_percentage: TrapPercentage | ||
diff --git a/apworld/player_logic.py b/apworld/player_logic.py index 6feef99..84c93c8 100644 --- a/apworld/player_logic.py +++ b/apworld/player_logic.py | |||
@@ -1,6 +1,11 @@ | |||
1 | from enum import IntEnum, auto | ||
2 | |||
1 | from .generated import data_pb2 as data_pb2 | 3 | from .generated import data_pb2 as data_pb2 |
4 | from .items import SYMBOL_ITEMS | ||
2 | from typing import TYPE_CHECKING, NamedTuple | 5 | from typing import TYPE_CHECKING, NamedTuple |
3 | 6 | ||
7 | from .options import ShuffleLetters, CyanDoorBehavior | ||
8 | |||
4 | if TYPE_CHECKING: | 9 | if TYPE_CHECKING: |
5 | from . import Lingo2World | 10 | from . import Lingo2World |
6 | 11 | ||
@@ -12,64 +17,175 @@ def calculate_letter_histogram(solution: str) -> dict[str, int]: | |||
12 | real_l = l.upper() | 17 | real_l = l.upper() |
13 | histogram[real_l] = min(histogram.get(real_l, 0) + 1, 2) | 18 | histogram[real_l] = min(histogram.get(real_l, 0) + 1, 2) |
14 | 19 | ||
15 | for free_letter in "HINT": | ||
16 | if histogram.get(free_letter, 0) == 1: | ||
17 | del histogram[free_letter] | ||
18 | |||
19 | return histogram | 20 | return histogram |
20 | 21 | ||
21 | 22 | ||
22 | class AccessRequirements: | 23 | class AccessRequirements: |
23 | items: set[str] | 24 | items: set[str] |
25 | progressives: dict[str, int] | ||
24 | rooms: set[str] | 26 | rooms: set[str] |
25 | symbols: set[str] | ||
26 | letters: dict[str, int] | 27 | letters: dict[str, int] |
28 | cyans: bool | ||
27 | 29 | ||
28 | # This is an AND of ORs. | 30 | # This is an AND of ORs. |
29 | or_logic: list[list["AccessRequirements"]] | 31 | or_logic: list[list["AccessRequirements"]] |
30 | 32 | ||
33 | # When complete_at is set, at least that many of the requirements in possibilities must be accessible. This should | ||
34 | # only be used for doors with complete_at > 1, as or_logic is more efficient for complete_at == 1. | ||
35 | complete_at: int | None | ||
36 | possibilities: list["AccessRequirements"] | ||
37 | |||
31 | def __init__(self): | 38 | def __init__(self): |
32 | self.items = set() | 39 | self.items = set() |
40 | self.progressives = dict() | ||
33 | self.rooms = set() | 41 | self.rooms = set() |
34 | self.symbols = set() | ||
35 | self.letters = dict() | 42 | self.letters = dict() |
43 | self.cyans = False | ||
36 | self.or_logic = list() | 44 | self.or_logic = list() |
45 | self.complete_at = None | ||
46 | self.possibilities = list() | ||
37 | 47 | ||
38 | def add_solution(self, solution: str): | 48 | def copy(self) -> "AccessRequirements": |
39 | histogram = calculate_letter_histogram(solution) | 49 | reqs = AccessRequirements() |
40 | 50 | reqs.items = self.items.copy() | |
41 | for l, a in histogram.items(): | 51 | reqs.progressives = self.progressives.copy() |
42 | self.letters[l] = max(self.letters.get(l, 0), histogram.get(l)) | 52 | reqs.rooms = self.rooms.copy() |
53 | reqs.letters = self.letters.copy() | ||
54 | reqs.cyans = self.cyans | ||
55 | reqs.or_logic = [[other_req.copy() for other_req in disjunction] for disjunction in self.or_logic] | ||
56 | reqs.complete_at = self.complete_at | ||
57 | reqs.possibilities = self.possibilities.copy() | ||
58 | return reqs | ||
43 | 59 | ||
44 | def merge(self, other: "AccessRequirements"): | 60 | def merge(self, other: "AccessRequirements"): |
45 | for item in other.items: | 61 | for item in other.items: |
46 | self.items.add(item) | 62 | self.items.add(item) |
47 | 63 | ||
64 | for item, amount in other.progressives.items(): | ||
65 | self.progressives[item] = max(amount, self.progressives.get(item, 0)) | ||
66 | |||
48 | for room in other.rooms: | 67 | for room in other.rooms: |
49 | self.rooms.add(room) | 68 | self.rooms.add(room) |
50 | 69 | ||
51 | for symbol in other.symbols: | ||
52 | self.symbols.add(symbol) | ||
53 | |||
54 | for letter, level in other.letters.items(): | 70 | for letter, level in other.letters.items(): |
55 | self.letters[letter] = max(self.letters.get(letter, 0), level) | 71 | self.letters[letter] = max(self.letters.get(letter, 0), level) |
56 | 72 | ||
73 | self.cyans = self.cyans or other.cyans | ||
74 | |||
57 | for disjunction in other.or_logic: | 75 | for disjunction in other.or_logic: |
58 | self.or_logic.append(disjunction) | 76 | self.or_logic.append(disjunction) |
59 | 77 | ||
78 | if other.complete_at is not None: | ||
79 | # Merging multiple requirements that use complete_at sucks, and is part of why we want to minimize use of | ||
80 | # it. If both requirements use complete_at, we will cheat by using the or_logic field, which supports | ||
81 | # conjunctions of requirements. | ||
82 | if self.complete_at is not None: | ||
83 | print("Merging requirements with complete_at > 1. This is messy and should be avoided!") | ||
84 | |||
85 | left_req = AccessRequirements() | ||
86 | left_req.complete_at = self.complete_at | ||
87 | left_req.possibilities = self.possibilities | ||
88 | self.or_logic.append([left_req]) | ||
89 | |||
90 | self.complete_at = None | ||
91 | self.possibilities = list() | ||
92 | |||
93 | right_req = AccessRequirements() | ||
94 | right_req.complete_at = other.complete_at | ||
95 | right_req.possibilities = other.possibilities | ||
96 | self.or_logic.append([right_req]) | ||
97 | else: | ||
98 | self.complete_at = other.complete_at | ||
99 | self.possibilities = other.possibilities | ||
100 | |||
101 | def is_empty(self) -> bool: | ||
102 | return (len(self.items) == 0 and len(self.progressives) == 0 and len(self.rooms) == 0 and len(self.letters) == 0 | ||
103 | and not self.cyans and len(self.or_logic) == 0 and self.complete_at is None) | ||
104 | |||
105 | def __eq__(self, other: "AccessRequirements"): | ||
106 | return (self.items == other.items and self.progressives == other.progressives and self.rooms == other.rooms and | ||
107 | self.letters == other.letters and self.cyans == other.cyans and self.or_logic == other.or_logic and | ||
108 | self.complete_at == other.complete_at and self.possibilities == other.possibilities) | ||
109 | |||
110 | def simplify(self): | ||
111 | resimplify = False | ||
112 | |||
113 | if len(self.or_logic) > 0: | ||
114 | old_or_logic = self.or_logic | ||
115 | |||
116 | def remove_redundant(sub_reqs: "AccessRequirements"): | ||
117 | new_reqs = sub_reqs.copy() | ||
118 | new_reqs.letters = {l: v for l, v in new_reqs.letters.items() if self.letters.get(l, 0) < v} | ||
119 | if new_reqs != sub_reqs: | ||
120 | return new_reqs | ||
121 | else: | ||
122 | return sub_reqs | ||
123 | |||
124 | self.or_logic = [] | ||
125 | for disjunction in old_or_logic: | ||
126 | new_disjunction = [] | ||
127 | for ssr in disjunction: | ||
128 | new_ssr = remove_redundant(ssr) | ||
129 | if not new_ssr.is_empty(): | ||
130 | new_disjunction.append(new_ssr) | ||
131 | else: | ||
132 | new_disjunction.clear() | ||
133 | break | ||
134 | if len(new_disjunction) == 1: | ||
135 | self.merge(new_disjunction[0]) | ||
136 | resimplify = True | ||
137 | elif len(new_disjunction) > 1: | ||
138 | if all(cjr == new_disjunction[0] for cjr in new_disjunction): | ||
139 | self.merge(new_disjunction[0]) | ||
140 | resimplify = True | ||
141 | else: | ||
142 | self.or_logic.append(new_disjunction) | ||
143 | |||
144 | if resimplify: | ||
145 | self.simplify() | ||
146 | |||
147 | def get_referenced_rooms(self): | ||
148 | result = set(self.rooms) | ||
149 | |||
150 | for disjunction in self.or_logic: | ||
151 | for sub_req in disjunction: | ||
152 | result = result.union(sub_req.get_referenced_rooms()) | ||
153 | |||
154 | for sub_req in self.possibilities: | ||
155 | result = result.union(sub_req.get_referenced_rooms()) | ||
156 | |||
157 | return result | ||
158 | |||
159 | def remove_room(self, room: str): | ||
160 | if room in self.rooms: | ||
161 | self.rooms.remove(room) | ||
162 | |||
163 | for disjunction in self.or_logic: | ||
164 | for sub_req in disjunction: | ||
165 | sub_req.remove_room(room) | ||
166 | |||
167 | for sub_req in self.possibilities: | ||
168 | sub_req.remove_room(room) | ||
169 | |||
60 | def __repr__(self): | 170 | def __repr__(self): |
61 | parts = [] | 171 | parts = [] |
62 | if len(self.items) > 0: | 172 | if len(self.items) > 0: |
63 | parts.append(f"items={self.items}") | 173 | parts.append(f"items={self.items}") |
174 | if len(self.progressives) > 0: | ||
175 | parts.append(f"progressives={self.progressives}") | ||
64 | if len(self.rooms) > 0: | 176 | if len(self.rooms) > 0: |
65 | parts.append(f"rooms={self.rooms}") | 177 | parts.append(f"rooms={self.rooms}") |
66 | if len(self.symbols) > 0: | ||
67 | parts.append(f"symbols={self.symbols}") | ||
68 | if len(self.letters) > 0: | 178 | if len(self.letters) > 0: |
69 | parts.append(f"letters={self.letters}") | 179 | parts.append(f"letters={self.letters}") |
180 | if self.cyans: | ||
181 | parts.append(f"cyans=True") | ||
70 | if len(self.or_logic) > 0: | 182 | if len(self.or_logic) > 0: |
71 | parts.append(f"or_logic={self.or_logic}") | 183 | parts.append(f"or_logic={self.or_logic}") |
72 | return f"AccessRequirements({", ".join(parts)})" | 184 | if self.complete_at is not None: |
185 | parts.append(f"complete_at={self.complete_at}") | ||
186 | if len(self.possibilities) > 0: | ||
187 | parts.append(f"possibilities={self.possibilities}") | ||
188 | return "AccessRequirements(" + ", ".join(parts) + ")" | ||
73 | 189 | ||
74 | 190 | ||
75 | class PlayerLocation(NamedTuple): | 191 | class PlayerLocation(NamedTuple): |
@@ -77,13 +193,19 @@ class PlayerLocation(NamedTuple): | |||
77 | reqs: AccessRequirements | 193 | reqs: AccessRequirements |
78 | 194 | ||
79 | 195 | ||
196 | class LetterBehavior(IntEnum): | ||
197 | VANILLA = auto() | ||
198 | ITEM = auto() | ||
199 | UNLOCKED = auto() | ||
200 | |||
201 | |||
80 | class Lingo2PlayerLogic: | 202 | class Lingo2PlayerLogic: |
81 | world: "Lingo2World" | 203 | world: "Lingo2World" |
82 | 204 | ||
83 | locations_by_room: dict[int, list[PlayerLocation]] | 205 | locations_by_room: dict[int, list[PlayerLocation]] |
84 | event_loc_item_by_room: dict[int, dict[str, str]] | 206 | event_loc_item_by_room: dict[int, dict[str, str]] |
85 | 207 | ||
86 | item_by_door: dict[int, str] | 208 | item_by_door: dict[int, tuple[str, int]] |
87 | 209 | ||
88 | panel_reqs: dict[int, AccessRequirements] | 210 | panel_reqs: dict[int, AccessRequirements] |
89 | proxy_reqs: dict[int, dict[str, AccessRequirements]] | 211 | proxy_reqs: dict[int, dict[str, AccessRequirements]] |
@@ -91,6 +213,9 @@ class Lingo2PlayerLogic: | |||
91 | 213 | ||
92 | real_items: list[str] | 214 | real_items: list[str] |
93 | 215 | ||
216 | double_letter_amount: dict[str, int] | ||
217 | goal_room_id: int | ||
218 | |||
94 | def __init__(self, world: "Lingo2World"): | 219 | def __init__(self, world: "Lingo2World"): |
95 | self.world = world | 220 | self.world = world |
96 | self.locations_by_room = {} | 221 | self.locations_by_room = {} |
@@ -100,14 +225,68 @@ class Lingo2PlayerLogic: | |||
100 | self.proxy_reqs = dict() | 225 | self.proxy_reqs = dict() |
101 | self.door_reqs = dict() | 226 | self.door_reqs = dict() |
102 | self.real_items = list() | 227 | self.real_items = list() |
228 | self.double_letter_amount = dict() | ||
229 | |||
230 | if self.world.options.shuffle_doors: | ||
231 | for progressive in world.static_logic.objects.progressives: | ||
232 | for i in range(0, len(progressive.doors)): | ||
233 | self.item_by_door[progressive.doors[i]] = (progressive.name, i + 1) | ||
234 | self.real_items.append(progressive.name) | ||
235 | |||
236 | for door_group in world.static_logic.objects.door_groups: | ||
237 | if door_group.type == data_pb2.DoorGroupType.CONNECTOR: | ||
238 | if not self.world.options.shuffle_doors or self.world.options.shuffle_worldports: | ||
239 | continue | ||
240 | elif door_group.type == data_pb2.DoorGroupType.COLOR_CONNECTOR: | ||
241 | if not self.world.options.shuffle_control_center_colors or self.world.options.shuffle_worldports: | ||
242 | continue | ||
243 | elif door_group.type == data_pb2.DoorGroupType.SHUFFLE_GROUP: | ||
244 | if not self.world.options.shuffle_doors: | ||
245 | continue | ||
246 | else: | ||
247 | continue | ||
248 | |||
249 | for door in door_group.doors: | ||
250 | self.item_by_door[door] = (door_group.name, 1) | ||
251 | |||
252 | self.real_items.append(door_group.name) | ||
103 | 253 | ||
104 | # We iterate through the doors in two parts because it is essential that we determine which doors are shuffled | 254 | # We iterate through the doors in two parts because it is essential that we determine which doors are shuffled |
105 | # before we calculate any access requirements. | 255 | # before we calculate any access requirements. |
106 | for door in world.static_logic.objects.doors: | 256 | for door in world.static_logic.objects.doors: |
107 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.ITEM_ONLY] and self.world.options.shuffle_doors: | 257 | if door.type in [data_pb2.DoorType.EVENT, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: |
108 | door_item_name = self.world.static_logic.get_door_item_name(door.id) | 258 | continue |
109 | self.item_by_door[door.id] = door_item_name | 259 | |
110 | self.real_items.append(door_item_name) | 260 | if door.id in self.item_by_door: |
261 | continue | ||
262 | |||
263 | if (door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.ITEM_ONLY] and | ||
264 | not self.world.options.shuffle_doors): | ||
265 | continue | ||
266 | |||
267 | if (door.type == data_pb2.DoorType.CONTROL_CENTER_COLOR and | ||
268 | not self.world.options.shuffle_control_center_colors): | ||
269 | continue | ||
270 | |||
271 | if door.type == data_pb2.DoorType.GALLERY_PAINTING and not self.world.options.shuffle_gallery_paintings: | ||
272 | continue | ||
273 | |||
274 | door_item_name = self.world.static_logic.get_door_item_name(door) | ||
275 | self.item_by_door[door.id] = (door_item_name, 1) | ||
276 | self.real_items.append(door_item_name) | ||
277 | |||
278 | # We handle cyan_door_behavior = Item after door shuffle, because cyan doors that are impacted by door shuffle | ||
279 | # should be exempt from cyan_door_behavior. | ||
280 | if world.options.cyan_door_behavior == CyanDoorBehavior.option_item: | ||
281 | for door_group in world.static_logic.objects.door_groups: | ||
282 | if door_group.type != data_pb2.DoorGroupType.CYAN_DOORS: | ||
283 | continue | ||
284 | |||
285 | for door in door_group.doors: | ||
286 | if not door in self.item_by_door: | ||
287 | self.item_by_door[door] = (door_group.name, 1) | ||
288 | |||
289 | self.real_items.append(door_group.name) | ||
111 | 290 | ||
112 | for door in world.static_logic.objects.doors: | 291 | for door in world.static_logic.objects.doors: |
113 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: | 292 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: |
@@ -117,31 +296,57 @@ class Lingo2PlayerLogic: | |||
117 | for letter in world.static_logic.objects.letters: | 296 | for letter in world.static_logic.objects.letters: |
118 | self.locations_by_room.setdefault(letter.room_id, []).append(PlayerLocation(letter.ap_id, | 297 | self.locations_by_room.setdefault(letter.room_id, []).append(PlayerLocation(letter.ap_id, |
119 | AccessRequirements())) | 298 | AccessRequirements())) |
120 | 299 | behavior = self.get_letter_behavior(letter.key, letter.level2) | |
121 | letter_name = f"{letter.key.upper()}{'2' if letter.level2 else '1'}" | 300 | if behavior == LetterBehavior.VANILLA: |
122 | event_name = f"{letter_name} (Collected)" | 301 | if not world.for_tracker: |
123 | self.event_loc_item_by_room.setdefault(letter.room_id, {})[event_name] = letter.key.upper() | 302 | letter_name = f"{letter.key.upper()}{'2' if letter.level2 else '1'}" |
124 | 303 | event_name = f"{letter_name} (Collected)" | |
125 | if letter.level2: | 304 | self.event_loc_item_by_room.setdefault(letter.room_id, {})[event_name] = letter.key.upper() |
126 | event_name = f"{letter_name} (Double Collected)" | 305 | |
127 | self.event_loc_item_by_room.setdefault(letter.room_id, {})[event_name] = letter.key.upper() | 306 | if letter.level2: |
307 | event_name = f"{letter_name} (Double Collected)" | ||
308 | self.event_loc_item_by_room.setdefault(letter.room_id, {})[event_name] = letter.key.upper() | ||
309 | elif behavior == LetterBehavior.ITEM: | ||
310 | self.real_items.append(letter.key.upper()) | ||
311 | |||
312 | if behavior != LetterBehavior.UNLOCKED: | ||
313 | self.double_letter_amount[letter.key.upper()] = self.double_letter_amount.get(letter.key.upper(), 0) + 1 | ||
128 | 314 | ||
129 | for mastery in world.static_logic.objects.masteries: | 315 | for mastery in world.static_logic.objects.masteries: |
130 | self.locations_by_room.setdefault(mastery.room_id, []).append(PlayerLocation(mastery.ap_id, | 316 | self.locations_by_room.setdefault(mastery.room_id, []).append(PlayerLocation(mastery.ap_id, |
131 | AccessRequirements())) | 317 | AccessRequirements())) |
132 | 318 | ||
133 | for ending in world.static_logic.objects.endings: | 319 | for ending in world.static_logic.objects.endings: |
134 | self.locations_by_room.setdefault(ending.room_id, []).append(PlayerLocation(ending.ap_id, | 320 | # Don't create a location for your selected ending, and never create a location for White Ending. |
135 | AccessRequirements())) | 321 | if world.options.victory_condition.current_key.removesuffix("_ending").upper() != ending.name\ |
322 | and ending.name != "WHITE": | ||
323 | self.locations_by_room.setdefault(ending.room_id, []).append(PlayerLocation(ending.ap_id, | ||
324 | AccessRequirements())) | ||
136 | 325 | ||
137 | event_name = f"{ending.name.capitalize()} Ending (Achieved)" | 326 | event_name = f"{ending.name.capitalize()} Ending (Achieved)" |
138 | item_name = event_name | 327 | item_name = event_name |
139 | 328 | ||
140 | if world.options.victory_condition.current_key.removesuffix("_ending").upper() == ending.name: | 329 | if world.options.victory_condition.current_key.removesuffix("_ending").upper() == ending.name: |
141 | item_name = "Victory" | 330 | item_name = "Victory" |
331 | self.goal_room_id = ending.room_id | ||
142 | 332 | ||
143 | self.event_loc_item_by_room.setdefault(ending.room_id, {})[event_name] = item_name | 333 | self.event_loc_item_by_room.setdefault(ending.room_id, {})[event_name] = item_name |
144 | 334 | ||
335 | if self.world.options.keyholder_sanity: | ||
336 | for keyholder in world.static_logic.objects.keyholders: | ||
337 | if keyholder.HasField("key"): | ||
338 | reqs = AccessRequirements() | ||
339 | |||
340 | if self.get_letter_behavior(keyholder.key, False) != LetterBehavior.UNLOCKED: | ||
341 | reqs.letters[keyholder.key.upper()] = 1 | ||
342 | |||
343 | self.locations_by_room.setdefault(keyholder.room_id, []).append(PlayerLocation(keyholder.ap_id, | ||
344 | reqs)) | ||
345 | |||
346 | if self.world.options.shuffle_symbols: | ||
347 | for symbol_name in SYMBOL_ITEMS.values(): | ||
348 | self.real_items.append(symbol_name) | ||
349 | |||
145 | def get_panel_reqs(self, panel_id: int, answer: str | None) -> AccessRequirements: | 350 | def get_panel_reqs(self, panel_id: int, answer: str | None) -> AccessRequirements: |
146 | if answer is None: | 351 | if answer is None: |
147 | if panel_id not in self.panel_reqs: | 352 | if panel_id not in self.panel_reqs: |
@@ -161,28 +366,38 @@ class Lingo2PlayerLogic: | |||
161 | reqs.rooms.add(self.world.static_logic.get_room_region_name(panel.room_id)) | 366 | reqs.rooms.add(self.world.static_logic.get_room_region_name(panel.room_id)) |
162 | 367 | ||
163 | if answer is not None: | 368 | if answer is not None: |
164 | reqs.add_solution(answer) | 369 | self.add_solution_reqs(reqs, answer) |
165 | elif len(panel.proxies) > 0: | 370 | elif len(panel.proxies) > 0: |
166 | possibilities = [] | 371 | possibilities = [] |
372 | already_filled = False | ||
167 | 373 | ||
168 | for proxy in panel.proxies: | 374 | for proxy in panel.proxies: |
169 | proxy_reqs = AccessRequirements() | 375 | proxy_reqs = AccessRequirements() |
170 | proxy_reqs.add_solution(proxy.answer) | 376 | self.add_solution_reqs(proxy_reqs, proxy.answer) |
171 | 377 | ||
172 | possibilities.append(proxy_reqs) | 378 | if not proxy_reqs.is_empty(): |
379 | possibilities.append(proxy_reqs) | ||
380 | else: | ||
381 | already_filled = True | ||
382 | break | ||
173 | 383 | ||
174 | if not any(proxy.answer == panel.answer for proxy in panel.proxies): | 384 | if not already_filled and not any(proxy.answer == panel.answer for proxy in panel.proxies): |
175 | proxy_reqs = AccessRequirements() | 385 | proxy_reqs = AccessRequirements() |
176 | proxy_reqs.add_solution(panel.answer) | 386 | self.add_solution_reqs(proxy_reqs, panel.answer) |
177 | 387 | ||
178 | possibilities.append(proxy_reqs) | 388 | if not proxy_reqs.is_empty(): |
389 | possibilities.append(proxy_reqs) | ||
390 | else: | ||
391 | already_filled = True | ||
179 | 392 | ||
180 | reqs.or_logic.append(possibilities) | 393 | if not already_filled: |
394 | reqs.or_logic.append(possibilities) | ||
181 | else: | 395 | else: |
182 | reqs.add_solution(panel.answer) | 396 | self.add_solution_reqs(reqs, panel.answer) |
183 | 397 | ||
184 | for symbol in panel.symbols: | 398 | if self.world.options.shuffle_symbols: |
185 | reqs.symbols.add(symbol) | 399 | for symbol in panel.symbols: |
400 | reqs.items.add(SYMBOL_ITEMS.get(symbol)) | ||
186 | 401 | ||
187 | if panel.HasField("required_door"): | 402 | if panel.HasField("required_door"): |
188 | door_reqs = self.get_door_open_reqs(panel.required_door) | 403 | door_reqs = self.get_door_open_reqs(panel.required_door) |
@@ -205,22 +420,46 @@ class Lingo2PlayerLogic: | |||
205 | door = self.world.static_logic.objects.doors[door_id] | 420 | door = self.world.static_logic.objects.doors[door_id] |
206 | reqs = AccessRequirements() | 421 | reqs = AccessRequirements() |
207 | 422 | ||
208 | # TODO: control_center_color, switches | ||
209 | if not door.HasField("complete_at") or door.complete_at == 0: | 423 | if not door.HasField("complete_at") or door.complete_at == 0: |
210 | for proxy in door.panels: | 424 | for proxy in door.panels: |
211 | panel_reqs = self.get_panel_reqs(proxy.panel, proxy.answer if proxy.HasField("answer") else None) | 425 | panel_reqs = self.get_panel_reqs(proxy.panel, proxy.answer if proxy.HasField("answer") else None) |
212 | reqs.merge(panel_reqs) | 426 | reqs.merge(panel_reqs) |
213 | elif door.complete_at == 1: | 427 | elif door.complete_at == 1: |
214 | reqs.or_logic.append([self.get_panel_reqs(proxy.panel, | 428 | disjunction = [] |
215 | proxy.answer if proxy.HasField("answer") else None) | 429 | for proxy in door.panels: |
216 | for proxy in door.panels]) | 430 | proxy_reqs = self.get_panel_reqs(proxy.panel, proxy.answer if proxy.HasField("answer") else None) |
431 | if proxy_reqs.is_empty(): | ||
432 | disjunction.clear() | ||
433 | break | ||
434 | else: | ||
435 | disjunction.append(proxy_reqs) | ||
436 | if len(disjunction) > 0: | ||
437 | reqs.or_logic.append(disjunction) | ||
217 | else: | 438 | else: |
218 | # TODO: Handle complete_at > 1 | 439 | reqs.complete_at = door.complete_at |
219 | pass | 440 | for proxy in door.panels: |
441 | panel_reqs = self.get_panel_reqs(proxy.panel, proxy.answer if proxy.HasField("answer") else None) | ||
442 | reqs.possibilities.append(panel_reqs) | ||
443 | |||
444 | if door.HasField("control_center_color"): | ||
445 | # TODO: Logic for ensuring two CC states aren't needed at once. | ||
446 | reqs.rooms.add("Control Center - Main Area") | ||
447 | self.add_solution_reqs(reqs, door.control_center_color) | ||
448 | |||
449 | if door.double_letters: | ||
450 | if self.world.options.cyan_door_behavior == CyanDoorBehavior.option_collect_h2: | ||
451 | reqs.rooms.add("The Repetitive - Main Room") | ||
452 | elif self.world.options.cyan_door_behavior == CyanDoorBehavior.option_any_double_letter: | ||
453 | if self.world.options.shuffle_letters != ShuffleLetters.option_unlocked: | ||
454 | reqs.cyans = True | ||
455 | elif self.world.options.cyan_door_behavior == CyanDoorBehavior.option_item: | ||
456 | # There shouldn't be any locations that are cyan doors. | ||
457 | pass | ||
220 | 458 | ||
221 | for keyholder_uses in door.keyholders: | 459 | for keyholder_uses in door.keyholders: |
222 | key_name = keyholder_uses.key.upper() | 460 | key_name = keyholder_uses.key.upper() |
223 | if key_name not in reqs.letters: | 461 | if (self.get_letter_behavior(keyholder_uses.key, False) != LetterBehavior.UNLOCKED |
462 | and key_name not in reqs.letters): | ||
224 | reqs.letters[key_name] = 1 | 463 | reqs.letters[key_name] = 1 |
225 | 464 | ||
226 | keyholder = self.world.static_logic.objects.keyholders[keyholder_uses.keyholder] | 465 | keyholder = self.world.static_logic.objects.keyholders[keyholder_uses.keyholder] |
@@ -229,10 +468,20 @@ class Lingo2PlayerLogic: | |||
229 | for room in door.rooms: | 468 | for room in door.rooms: |
230 | reqs.rooms.add(self.world.static_logic.get_room_region_name(room)) | 469 | reqs.rooms.add(self.world.static_logic.get_room_region_name(room)) |
231 | 470 | ||
471 | for ending_id in door.endings: | ||
472 | ending = self.world.static_logic.objects.endings[ending_id] | ||
473 | |||
474 | if self.world.options.victory_condition.current_key.removesuffix("_ending").upper() == ending.name: | ||
475 | reqs.items.add("Victory") | ||
476 | else: | ||
477 | reqs.items.add(f"{ending.name.capitalize()} Ending (Achieved)") | ||
478 | |||
232 | for sub_door_id in door.doors: | 479 | for sub_door_id in door.doors: |
233 | sub_reqs = self.get_door_open_reqs(sub_door_id) | 480 | sub_reqs = self.get_door_open_reqs(sub_door_id) |
234 | reqs.merge(sub_reqs) | 481 | reqs.merge(sub_reqs) |
235 | 482 | ||
483 | reqs.simplify() | ||
484 | |||
236 | return reqs | 485 | return reqs |
237 | 486 | ||
238 | # This gets the requirements to open a door within the world. When a door is shuffled, this means having the item | 487 | # This gets the requirements to open a door within the world. When a door is shuffled, this means having the item |
@@ -240,8 +489,50 @@ class Lingo2PlayerLogic: | |||
240 | def get_door_open_reqs(self, door_id: int) -> AccessRequirements: | 489 | def get_door_open_reqs(self, door_id: int) -> AccessRequirements: |
241 | if door_id in self.item_by_door: | 490 | if door_id in self.item_by_door: |
242 | reqs = AccessRequirements() | 491 | reqs = AccessRequirements() |
243 | reqs.items.add(self.item_by_door.get(door_id)) | 492 | |
493 | item_name, amount = self.item_by_door.get(door_id) | ||
494 | if amount == 1: | ||
495 | reqs.items.add(item_name) | ||
496 | else: | ||
497 | reqs.progressives[item_name] = amount | ||
244 | 498 | ||
245 | return reqs | 499 | return reqs |
246 | else: | 500 | else: |
247 | return self.get_door_reqs(door_id) | 501 | return self.get_door_reqs(door_id) |
502 | |||
503 | def get_letter_behavior(self, letter: str, level2: bool) -> LetterBehavior: | ||
504 | if self.world.options.shuffle_letters == ShuffleLetters.option_unlocked: | ||
505 | return LetterBehavior.UNLOCKED | ||
506 | |||
507 | if self.world.options.shuffle_letters in [ShuffleLetters.option_vanilla_cyan, ShuffleLetters.option_item_cyan]: | ||
508 | if level2: | ||
509 | if self.world.options.shuffle_letters == ShuffleLetters.option_vanilla_cyan: | ||
510 | return LetterBehavior.VANILLA | ||
511 | else: | ||
512 | return LetterBehavior.ITEM | ||
513 | else: | ||
514 | return LetterBehavior.UNLOCKED | ||
515 | |||
516 | if not level2 and letter in ["h", "i", "n", "t"]: | ||
517 | return LetterBehavior.UNLOCKED | ||
518 | |||
519 | if self.world.options.shuffle_letters == ShuffleLetters.option_progressive: | ||
520 | return LetterBehavior.ITEM | ||
521 | |||
522 | return LetterBehavior.VANILLA | ||
523 | |||
524 | def add_solution_reqs(self, reqs: AccessRequirements, solution: str): | ||
525 | histogram = calculate_letter_histogram(solution) | ||
526 | |||
527 | for l, a in histogram.items(): | ||
528 | needed = min(a, 2) | ||
529 | level2 = (needed == 2) | ||
530 | |||
531 | if level2 and self.get_letter_behavior(l.lower(), True) == LetterBehavior.UNLOCKED: | ||
532 | needed = 1 | ||
533 | |||
534 | if self.get_letter_behavior(l.lower(), False) == LetterBehavior.UNLOCKED: | ||
535 | needed = needed - 1 | ||
536 | |||
537 | if needed > 0: | ||
538 | reqs.letters[l] = max(reqs.letters.get(l, 0), needed) | ||
diff --git a/apworld/regions.py b/apworld/regions.py index fe2c99b..0c3858d 100644 --- a/apworld/regions.py +++ b/apworld/regions.py | |||
@@ -1,6 +1,8 @@ | |||
1 | from typing import TYPE_CHECKING | 1 | from typing import TYPE_CHECKING |
2 | 2 | ||
3 | import BaseClasses | ||
3 | from BaseClasses import Region, ItemClassification, Entrance | 4 | from BaseClasses import Region, ItemClassification, Entrance |
5 | from entrance_rando import randomize_entrances | ||
4 | from .items import Lingo2Item | 6 | from .items import Lingo2Item |
5 | from .locations import Lingo2Location | 7 | from .locations import Lingo2Location |
6 | from .player_logic import AccessRequirements | 8 | from .player_logic import AccessRequirements |
@@ -11,21 +13,42 @@ if TYPE_CHECKING: | |||
11 | 13 | ||
12 | 14 | ||
13 | def create_region(room, world: "Lingo2World") -> Region: | 15 | def create_region(room, world: "Lingo2World") -> Region: |
14 | new_region = Region(world.static_logic.get_room_region_name(room.id), world.player, world.multiworld) | 16 | return Region(world.static_logic.get_room_region_name(room.id), world.player, world.multiworld) |
15 | 17 | ||
18 | |||
19 | def create_locations(room, new_region: Region, world: "Lingo2World", regions: dict[str, Region]): | ||
16 | for location in world.player_logic.locations_by_room.get(room.id, {}): | 20 | for location in world.player_logic.locations_by_room.get(room.id, {}): |
21 | reqs = location.reqs.copy() | ||
22 | reqs.remove_room(new_region.name) | ||
23 | |||
17 | new_location = Lingo2Location(world.player, world.static_logic.location_id_to_name[location.code], | 24 | new_location = Lingo2Location(world.player, world.static_logic.location_id_to_name[location.code], |
18 | location.code, new_region) | 25 | location.code, new_region) |
19 | new_location.access_rule = make_location_lambda(location.reqs, world) | 26 | new_location.access_rule = make_location_lambda(reqs, world, regions) |
20 | new_region.locations.append(new_location) | 27 | new_region.locations.append(new_location) |
21 | 28 | ||
22 | for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items(): | 29 | for event_name, item_name in world.player_logic.event_loc_item_by_room.get(room.id, {}).items(): |
23 | new_location = Lingo2Location(world.player, event_name, None, new_region) | 30 | new_location = Lingo2Location(world.player, event_name, None, new_region) |
31 | if world.for_tracker and item_name == "Victory": | ||
32 | new_location.goal = True | ||
33 | |||
24 | event_item = Lingo2Item(item_name, ItemClassification.progression, None, world.player) | 34 | event_item = Lingo2Item(item_name, ItemClassification.progression, None, world.player) |
25 | new_location.place_locked_item(event_item) | 35 | new_location.place_locked_item(event_item) |
26 | new_region.locations.append(new_location) | 36 | new_region.locations.append(new_location) |
27 | 37 | ||
28 | return new_region | 38 | if world.for_tracker and world.options.shuffle_worldports: |
39 | for port_id in room.ports: | ||
40 | port = world.static_logic.objects.ports[port_id] | ||
41 | if port.no_shuffle: | ||
42 | continue | ||
43 | |||
44 | new_location = Lingo2Location(world.player, f"Worldport {port.id} Entered", None, new_region) | ||
45 | new_location.port_id = port.id | ||
46 | |||
47 | if port.HasField("required_door"): | ||
48 | new_location.access_rule = \ | ||
49 | make_location_lambda(world.player_logic.get_door_open_reqs(port.required_door), world, regions) | ||
50 | |||
51 | new_region.locations.append(new_location) | ||
29 | 52 | ||
30 | 53 | ||
31 | def create_regions(world: "Lingo2World"): | 54 | def create_regions(world: "Lingo2World"): |
@@ -33,16 +56,34 @@ def create_regions(world: "Lingo2World"): | |||
33 | "Menu": Region("Menu", world.player, world.multiworld) | 56 | "Menu": Region("Menu", world.player, world.multiworld) |
34 | } | 57 | } |
35 | 58 | ||
59 | region_and_room = [] | ||
60 | |||
61 | # Create the regions in two stages. First, make the actual region objects and memoize them. Then, add all of the | ||
62 | # locations. This allows us to reference the actual region objects in the access rules for the locations, which is | ||
63 | # faster than having to look them up during access checking. | ||
36 | for room in world.static_logic.objects.rooms: | 64 | for room in world.static_logic.objects.rooms: |
37 | region = create_region(room, world) | 65 | region = create_region(room, world) |
38 | regions[region.name] = region | 66 | regions[region.name] = region |
67 | region_and_room.append((region, room)) | ||
68 | |||
69 | for (region, room) in region_and_room: | ||
70 | create_locations(room, region, world, regions) | ||
39 | 71 | ||
40 | regions["Menu"].connect(regions["The Entry - Starting Room"], "Start Game") | 72 | regions["Menu"].connect(regions["The Entry - Starting Room"], "Start Game") |
41 | 73 | ||
42 | # TODO: The requirements of the opposite trigger also matter. | ||
43 | for connection in world.static_logic.objects.connections: | 74 | for connection in world.static_logic.objects.connections: |
75 | if connection.roof_access and not world.options.daedalus_roof_access: | ||
76 | continue | ||
77 | |||
78 | if connection.vanilla_only and world.options.shuffle_doors: | ||
79 | continue | ||
80 | |||
44 | from_region = world.static_logic.get_room_region_name(connection.from_room) | 81 | from_region = world.static_logic.get_room_region_name(connection.from_room) |
45 | to_region = world.static_logic.get_room_region_name(connection.to_room) | 82 | to_region = world.static_logic.get_room_region_name(connection.to_room) |
83 | |||
84 | if from_region not in regions or to_region not in regions: | ||
85 | continue | ||
86 | |||
46 | connection_name = f"{from_region} -> {to_region}" | 87 | connection_name = f"{from_region} -> {to_region}" |
47 | 88 | ||
48 | reqs = AccessRequirements() | 89 | reqs = AccessRequirements() |
@@ -56,7 +97,10 @@ def create_regions(world: "Lingo2World"): | |||
56 | 97 | ||
57 | if connection.HasField("port"): | 98 | if connection.HasField("port"): |
58 | port = world.static_logic.objects.ports[connection.port] | 99 | port = world.static_logic.objects.ports[connection.port] |
59 | connection_name = f"{connection_name} (via port {port.name})" | 100 | connection_name = f"{connection_name} (via {port.display_name})" |
101 | |||
102 | if world.options.shuffle_worldports and not port.no_shuffle: | ||
103 | continue | ||
60 | 104 | ||
61 | if port.HasField("required_door"): | 105 | if port.HasField("required_door"): |
62 | reqs.merge(world.player_logic.get_door_open_reqs(port.required_door)) | 106 | reqs.merge(world.player_logic.get_door_open_reqs(port.required_door)) |
@@ -79,14 +123,99 @@ def create_regions(world: "Lingo2World"): | |||
79 | else: | 123 | else: |
80 | connection_name = f"{connection_name} (via panel {panel.name})" | 124 | connection_name = f"{connection_name} (via panel {panel.name})" |
81 | 125 | ||
82 | if from_region in regions and to_region in regions: | 126 | if connection.HasField("purple_ending") and connection.purple_ending and world.options.strict_purple_ending: |
83 | connection = Entrance(world.player, connection_name, regions[from_region]) | 127 | world.player_logic.add_solution_reqs(reqs, "abcdefghijklmnopqrstuvwxyz") |
84 | connection.access_rule = make_location_lambda(reqs, world) | 128 | |
129 | if connection.HasField("cyan_ending") and connection.cyan_ending and world.options.strict_cyan_ending: | ||
130 | world.player_logic.add_solution_reqs(reqs, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz") | ||
131 | |||
132 | reqs.simplify() | ||
133 | reqs.remove_room(from_region) | ||
85 | 134 | ||
86 | regions[from_region].exits.append(connection) | 135 | if to_region in reqs.rooms: |
87 | connection.connect(regions[to_region]) | 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 | ||
88 | 140 | ||
89 | for region in reqs.rooms: | 141 | connection = Entrance(world.player, connection_name, regions[from_region]) |
90 | world.multiworld.register_indirect_condition(regions[region], connection) | 142 | connection.access_rule = make_location_lambda(reqs, world, regions) |
143 | |||
144 | regions[from_region].exits.append(connection) | ||
145 | connection.connect(regions[to_region]) | ||
146 | |||
147 | for region in reqs.get_referenced_rooms(): | ||
148 | world.multiworld.register_indirect_condition(regions[region], connection) | ||
91 | 149 | ||
92 | world.multiworld.regions += regions.values() | 150 | world.multiworld.regions += regions.values() |
151 | |||
152 | |||
153 | def shuffle_entrances(world: "Lingo2World"): | ||
154 | er_entrances: list[Entrance] = [] | ||
155 | er_exits: list[Entrance] = [] | ||
156 | |||
157 | port_id_by_name: dict[str, int] = {} | ||
158 | |||
159 | for port in world.static_logic.objects.ports: | ||
160 | if port.no_shuffle: | ||
161 | continue | ||
162 | |||
163 | port_region_name = world.static_logic.get_room_region_name(port.room_id) | ||
164 | port_region = world.multiworld.get_region(port_region_name, world.player) | ||
165 | |||
166 | connection_name = f"{port_region_name} - {port.display_name}" | ||
167 | port_id_by_name[connection_name] = port.id | ||
168 | |||
169 | entrance = port_region.create_er_target(connection_name) | ||
170 | entrance.randomization_type = BaseClasses.EntranceType.TWO_WAY | ||
171 | |||
172 | er_exit = port_region.create_exit(connection_name) | ||
173 | er_exit.randomization_type = BaseClasses.EntranceType.TWO_WAY | ||
174 | |||
175 | if port.HasField("required_door"): | ||
176 | door_reqs = world.player_logic.get_door_open_reqs(port.required_door) | ||
177 | er_exit.access_rule = make_location_lambda(door_reqs, world, None) | ||
178 | |||
179 | for region in door_reqs.get_referenced_rooms(): | ||
180 | world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player), | ||
181 | er_exit) | ||
182 | |||
183 | er_entrances.append(entrance) | ||
184 | er_exits.append(er_exit) | ||
185 | |||
186 | result = randomize_entrances(world, True, {0:[0]}, False, er_entrances, | ||
187 | er_exits) | ||
188 | |||
189 | for (f, to) in result.pairings: | ||
190 | world.port_pairings[port_id_by_name[f]] = port_id_by_name[to] | ||
191 | |||
192 | |||
193 | def connect_ports_from_ut(port_pairings: dict[int, int], world: "Lingo2World"): | ||
194 | for fpid, tpid in port_pairings.items(): | ||
195 | from_port = world.static_logic.objects.ports[fpid] | ||
196 | to_port = world.static_logic.objects.ports[tpid] | ||
197 | |||
198 | from_region_name = world.static_logic.get_room_region_name(from_port.room_id) | ||
199 | to_region_name = world.static_logic.get_room_region_name(to_port.room_id) | ||
200 | |||
201 | from_region = world.multiworld.get_region(from_region_name, world.player) | ||
202 | to_region = world.multiworld.get_region(to_region_name, world.player) | ||
203 | |||
204 | connection = Entrance(world.player, f"{from_region_name} - {from_port.display_name}", from_region) | ||
205 | |||
206 | reqs = AccessRequirements() | ||
207 | if from_port.HasField("required_door"): | ||
208 | reqs = world.player_logic.get_door_open_reqs(from_port.required_door).copy() | ||
209 | |||
210 | if world.for_tracker: | ||
211 | reqs.items.add(f"Worldport {fpid} Entered") | ||
212 | |||
213 | if not reqs.is_empty(): | ||
214 | connection.access_rule = make_location_lambda(reqs, world, None) | ||
215 | |||
216 | for region in reqs.get_referenced_rooms(): | ||
217 | world.multiworld.register_indirect_condition(world.multiworld.get_region(region, world.player), | ||
218 | connection) | ||
219 | |||
220 | from_region.exits.append(connection) | ||
221 | connection.connect(to_region) | ||
diff --git a/apworld/requirements.txt b/apworld/requirements.txt index b701d11..dbc395b 100644 --- a/apworld/requirements.txt +++ b/apworld/requirements.txt | |||
@@ -1 +1 @@ | |||
protobuf>=5.29.3 \ No newline at end of file | protobuf==3.20.3 | ||
diff --git a/apworld/rules.py b/apworld/rules.py index 4a84acf..f859e75 100644 --- a/apworld/rules.py +++ b/apworld/rules.py | |||
@@ -1,32 +1,66 @@ | |||
1 | from collections.abc import Callable | 1 | from collections.abc import Callable |
2 | from typing import TYPE_CHECKING | 2 | from typing import TYPE_CHECKING |
3 | 3 | ||
4 | from BaseClasses import CollectionState | 4 | from BaseClasses import CollectionState, Region |
5 | from .player_logic import AccessRequirements | 5 | from .player_logic import AccessRequirements |
6 | 6 | ||
7 | if TYPE_CHECKING: | 7 | if TYPE_CHECKING: |
8 | from . import Lingo2World | 8 | from . import Lingo2World |
9 | 9 | ||
10 | 10 | ||
11 | def lingo2_can_satisfy_requirements(state: CollectionState, reqs: AccessRequirements, world: "Lingo2World") -> bool: | 11 | def lingo2_can_satisfy_requirements(state: CollectionState, reqs: AccessRequirements, regions: list[Region], |
12 | world: "Lingo2World") -> bool: | ||
12 | if not all(state.has(item, world.player) for item in reqs.items): | 13 | if not all(state.has(item, world.player) for item in reqs.items): |
13 | return False | 14 | return False |
14 | 15 | ||
16 | if not all(state.has(item, world.player, amount) for item, amount in reqs.progressives.items()): | ||
17 | return False | ||
18 | |||
15 | if not all(state.can_reach_region(region_name, world.player) for region_name in reqs.rooms): | 19 | if not all(state.can_reach_region(region_name, world.player) for region_name in reqs.rooms): |
16 | return False | 20 | return False |
17 | 21 | ||
18 | # TODO: symbols | 22 | if not all(state.can_reach(region) for region in regions): |
23 | return False | ||
19 | 24 | ||
20 | for letter_key, letter_level in reqs.letters.items(): | 25 | for letter_key, letter_level in reqs.letters.items(): |
21 | if not state.has(letter_key, world.player, letter_level): | 26 | if not state.has(letter_key, world.player, letter_level): |
22 | return False | 27 | return False |
23 | 28 | ||
29 | if reqs.cyans: | ||
30 | if not any(state.has(letter, world.player, amount) | ||
31 | for letter, amount in world.player_logic.double_letter_amount.items()): | ||
32 | return False | ||
33 | |||
24 | if len(reqs.or_logic) > 0: | 34 | if len(reqs.or_logic) > 0: |
25 | if not all(any(lingo2_can_satisfy_requirements(state, sub_reqs, world) for sub_reqs in subjunction) | 35 | if not all(any(lingo2_can_satisfy_requirements(state, sub_reqs, [], world) for sub_reqs in subjunction) |
26 | for subjunction in reqs.or_logic): | 36 | for subjunction in reqs.or_logic): |
27 | return False | 37 | return False |
28 | 38 | ||
39 | if reqs.complete_at is not None: | ||
40 | completed = 0 | ||
41 | checked = 0 | ||
42 | for possibility in reqs.possibilities: | ||
43 | checked += 1 | ||
44 | if lingo2_can_satisfy_requirements(state, possibility, [], world): | ||
45 | completed += 1 | ||
46 | if completed >= reqs.complete_at: | ||
47 | break | ||
48 | elif len(reqs.possibilities) - checked + completed < reqs.complete_at: | ||
49 | # There aren't enough remaining possibilities for the check to pass. | ||
50 | return False | ||
51 | if completed < reqs.complete_at: | ||
52 | return False | ||
53 | |||
29 | return True | 54 | return True |
30 | 55 | ||
31 | def make_location_lambda(reqs: AccessRequirements, world: "Lingo2World") -> Callable[[CollectionState], bool]: | 56 | def make_location_lambda(reqs: AccessRequirements, world: "Lingo2World", |
32 | return lambda state: lingo2_can_satisfy_requirements(state, reqs, world) | 57 | regions: dict[str, Region] | None) -> Callable[[CollectionState], bool]: |
58 | # Replace required rooms with regions for the top level requirement, which saves looking up the regions during rule | ||
59 | # checking. | ||
60 | if regions is not None: | ||
61 | required_regions = [regions[room_name] for room_name in reqs.rooms] | ||
62 | else: | ||
63 | required_regions = [world.multiworld.get_region(room_name, world.player) for room_name in reqs.rooms] | ||
64 | new_reqs = reqs.copy() | ||
65 | new_reqs.rooms.clear() | ||
66 | return lambda state: lingo2_can_satisfy_requirements(state, new_reqs, required_regions, world) | ||
diff --git a/apworld/static_logic.py b/apworld/static_logic.py index 965ce3e..e59a47d 100644 --- a/apworld/static_logic.py +++ b/apworld/static_logic.py | |||
@@ -1,6 +1,8 @@ | |||
1 | from .generated import data_pb2 as data_pb2 | 1 | from .generated import data_pb2 as data_pb2 |
2 | from .items import SYMBOL_ITEMS, ANTI_COLLECTABLE_TRAPS | ||
2 | import pkgutil | 3 | import pkgutil |
3 | 4 | ||
5 | |||
4 | class Lingo2StaticLogic: | 6 | class Lingo2StaticLogic: |
5 | item_id_to_name: dict[int, str] | 7 | item_id_to_name: dict[int, str] |
6 | location_id_to_name: dict[int, str] | 8 | location_id_to_name: dict[int, str] |
@@ -8,9 +10,17 @@ class Lingo2StaticLogic: | |||
8 | item_name_to_id: dict[str, int] | 10 | item_name_to_id: dict[str, int] |
9 | location_name_to_id: dict[str, int] | 11 | location_name_to_id: dict[str, int] |
10 | 12 | ||
13 | item_name_groups: dict[str, list[str]] | ||
14 | location_name_groups: dict[str, list[str]] | ||
15 | |||
16 | letter_weights: dict[str, int] | ||
17 | |||
11 | def __init__(self): | 18 | def __init__(self): |
12 | self.item_id_to_name = {} | 19 | self.item_id_to_name = {} |
13 | self.location_id_to_name = {} | 20 | self.location_id_to_name = {} |
21 | self.item_name_groups = {} | ||
22 | self.location_name_groups = {} | ||
23 | self.letter_weights = {} | ||
14 | 24 | ||
15 | file = pkgutil.get_data(__name__, "generated/data.binpb") | 25 | file = pkgutil.get_data(__name__, "generated/data.binpb") |
16 | self.objects = data_pb2.AllObjects() | 26 | self.objects = data_pb2.AllObjects() |
@@ -18,38 +28,125 @@ class Lingo2StaticLogic: | |||
18 | 28 | ||
19 | for door in self.objects.doors: | 29 | for door in self.objects.doors: |
20 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: | 30 | if door.type in [data_pb2.DoorType.STANDARD, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: |
21 | location_name = f"{self.get_map_object_map_name(door)} - {door.name}" | 31 | location_name = self.get_door_location_name(door) |
22 | self.location_id_to_name[door.ap_id] = location_name | 32 | self.location_id_to_name[door.ap_id] = location_name |
23 | 33 | ||
24 | if door.type not in [data_pb2.DoorType.EVENT, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: | 34 | if door.type not in [data_pb2.DoorType.EVENT, data_pb2.DoorType.LOCATION_ONLY, data_pb2.DoorType.GRAVESTONE]: |
25 | item_name = self.get_door_item_name(door.id) | 35 | item_name = self.get_door_item_name(door) |
26 | self.item_id_to_name[door.ap_id] = item_name | 36 | self.item_id_to_name[door.ap_id] = item_name |
27 | 37 | ||
28 | for letter in self.objects.letters: | 38 | for letter in self.objects.letters: |
29 | letter_name = f"{letter.key.upper()}{'2' if letter.level2 else '1'}" | 39 | letter_name = f"{letter.key.upper()}{'2' if letter.level2 else '1'}" |
30 | location_name = f"{self.get_room_object_map_name(letter)} - {letter_name}" | 40 | location_name = f"{self.get_room_object_map_name(letter)} - {letter_name}" |
31 | self.location_id_to_name[letter.ap_id] = location_name | 41 | self.location_id_to_name[letter.ap_id] = location_name |
42 | self.location_name_groups.setdefault("Letters", []).append(location_name) | ||
32 | 43 | ||
33 | if not letter.level2: | 44 | if not letter.level2: |
34 | self.item_id_to_name[letter.ap_id] = letter_name | 45 | self.item_id_to_name[letter.ap_id] = letter.key.upper() |
46 | self.item_name_groups.setdefault("Letters", []).append(letter.key.upper()) | ||
35 | 47 | ||
36 | for mastery in self.objects.masteries: | 48 | for mastery in self.objects.masteries: |
37 | location_name = f"{self.get_room_object_map_name(mastery)} - Mastery" | 49 | location_name = f"{self.get_room_object_map_name(mastery)} - Mastery" |
38 | self.location_id_to_name[mastery.ap_id] = location_name | 50 | self.location_id_to_name[mastery.ap_id] = location_name |
51 | self.location_name_groups.setdefault("Masteries", []).append(location_name) | ||
39 | 52 | ||
40 | for ending in self.objects.endings: | 53 | for ending in self.objects.endings: |
41 | location_name = f"{self.get_room_object_map_name(ending)} - {ending.name.title()} Ending" | 54 | location_name = f"{self.get_room_object_map_name(ending)} - {ending.name.title()} Ending" |
42 | self.location_id_to_name[ending.ap_id] = location_name | 55 | self.location_id_to_name[ending.ap_id] = location_name |
56 | self.location_name_groups.setdefault("Endings", []).append(location_name) | ||
57 | |||
58 | for progressive in self.objects.progressives: | ||
59 | self.item_id_to_name[progressive.ap_id] = progressive.name | ||
60 | |||
61 | for door_group in self.objects.door_groups: | ||
62 | self.item_id_to_name[door_group.ap_id] = door_group.name | ||
63 | |||
64 | for keyholder in self.objects.keyholders: | ||
65 | if keyholder.HasField("key"): | ||
66 | location_name = f"{self.get_room_object_location_prefix(keyholder)} - {keyholder.key.upper()} Keyholder" | ||
67 | self.location_id_to_name[keyholder.ap_id] = location_name | ||
68 | self.location_name_groups.setdefault("Keyholders", []).append(location_name) | ||
69 | |||
70 | self.item_id_to_name[self.objects.special_ids["A Job Well Done"]] = "A Job Well Done" | ||
71 | |||
72 | for symbol_name in SYMBOL_ITEMS.values(): | ||
73 | self.item_id_to_name[self.objects.special_ids[symbol_name]] = symbol_name | ||
43 | 74 | ||
44 | self.item_id_to_name[self.objects.special_ids["Nothing"]] = "Nothing" | 75 | for trap_name in ANTI_COLLECTABLE_TRAPS: |
76 | self.item_id_to_name[self.objects.special_ids[trap_name]] = trap_name | ||
45 | 77 | ||
46 | self.item_name_to_id = {name: ap_id for ap_id, name in self.item_id_to_name.items()} | 78 | self.item_name_to_id = {name: ap_id for ap_id, name in self.item_id_to_name.items()} |
47 | self.location_name_to_id = {name: ap_id for ap_id, name in self.location_id_to_name.items()} | 79 | self.location_name_to_id = {name: ap_id for ap_id, name in self.location_id_to_name.items()} |
48 | 80 | ||
49 | def get_door_item_name(self, door_id: int) -> str: | 81 | for panel in self.objects.panels: |
50 | door = self.objects.doors[door_id] | 82 | for letter in panel.answer.upper(): |
83 | self.letter_weights[letter] = self.letter_weights.get(letter, 0) + 1 | ||
84 | |||
85 | def get_door_item_name(self, door: data_pb2.Door) -> str: | ||
51 | return f"{self.get_map_object_map_name(door)} - {door.name}" | 86 | return f"{self.get_map_object_map_name(door)} - {door.name}" |
52 | 87 | ||
88 | def get_door_item_name_by_id(self, door_id: int) -> str: | ||
89 | door = self.objects.doors[door_id] | ||
90 | return self.get_door_item_name(door_id) | ||
91 | |||
92 | def get_door_location_name(self, door: data_pb2.Door) -> str: | ||
93 | map_part = self.get_room_object_location_prefix(door) | ||
94 | |||
95 | if door.HasField("location_name"): | ||
96 | return f"{map_part} - {door.location_name}" | ||
97 | |||
98 | generated_location_name = self.get_generated_door_location_name(door) | ||
99 | if generated_location_name is not None: | ||
100 | return generated_location_name | ||
101 | |||
102 | return f"{map_part} - {door.name}" | ||
103 | |||
104 | def get_generated_door_location_name(self, door: data_pb2.Door) -> str | None: | ||
105 | if door.type != data_pb2.DoorType.STANDARD: | ||
106 | return None | ||
107 | |||
108 | if len(door.keyholders) > 0 or len(door.endings) > 0 or door.HasField("complete_at"): | ||
109 | return None | ||
110 | |||
111 | if len(door.panels) > 4: | ||
112 | return None | ||
113 | |||
114 | map_areas = set() | ||
115 | for panel_id in door.panels: | ||
116 | panel = self.objects.panels[panel_id.panel] | ||
117 | panel_room = self.objects.rooms[panel.room_id] | ||
118 | # It's okay if panel_display_name is not present because then it's coalesced with other unnamed areas. | ||
119 | map_areas.add(panel_room.panel_display_name) | ||
120 | |||
121 | if len(map_areas) > 1: | ||
122 | return None | ||
123 | |||
124 | game_map = self.objects.maps[door.map_id] | ||
125 | map_area = map_areas.pop() | ||
126 | if map_area == "": | ||
127 | map_part = game_map.display_name | ||
128 | else: | ||
129 | map_part = f"{game_map.display_name} ({map_area})" | ||
130 | |||
131 | def get_panel_display_name(panel: data_pb2.ProxyIdentifier) -> str: | ||
132 | panel_data = self.objects.panels[panel.panel] | ||
133 | panel_name = panel_data.display_name if panel_data.HasField("display_name") else panel_data.name | ||
134 | |||
135 | if panel.HasField("answer"): | ||
136 | return f"{panel_name}/{panel.answer.upper()}" | ||
137 | else: | ||
138 | return panel_name | ||
139 | |||
140 | panel_names = [get_panel_display_name(panel_id) | ||
141 | for panel_id in door.panels] | ||
142 | panel_names.sort() | ||
143 | |||
144 | return map_part + " - " + ", ".join(panel_names) | ||
145 | |||
146 | def get_door_location_name_by_id(self, door_id: int) -> str: | ||
147 | door = self.objects.doors[door_id] | ||
148 | return self.get_door_location_name(door) | ||
149 | |||
53 | def get_room_region_name(self, room_id: int) -> str: | 150 | def get_room_region_name(self, room_id: int) -> str: |
54 | room = self.objects.rooms[room_id] | 151 | room = self.objects.rooms[room_id] |
55 | return f"{self.get_map_object_map_name(room)} - {room.name}" | 152 | return f"{self.get_map_object_map_name(room)} - {room.name}" |
@@ -59,3 +156,16 @@ class Lingo2StaticLogic: | |||
59 | 156 | ||
60 | def get_room_object_map_name(self, obj) -> str: | 157 | def get_room_object_map_name(self, obj) -> str: |
61 | return self.get_map_object_map_name(self.objects.rooms[obj.room_id]) | 158 | return self.get_map_object_map_name(self.objects.rooms[obj.room_id]) |
159 | |||
160 | def get_room_object_location_prefix(self, obj) -> str: | ||
161 | room = self.objects.rooms[obj.room_id] | ||
162 | game_map = self.objects.maps[room.map_id] | ||
163 | |||
164 | if room.HasField("panel_display_name"): | ||
165 | return f"{game_map.display_name} ({room.panel_display_name})" | ||
166 | else: | ||
167 | return game_map.display_name | ||
168 | |||
169 | def get_data_version(self) -> list[int]: | ||
170 | version = self.objects.version | ||
171 | return [version.major, version.minor, version.patch] | ||
diff --git a/apworld/tracker.py b/apworld/tracker.py new file mode 100644 index 0000000..c65317c --- /dev/null +++ b/apworld/tracker.py | |||
@@ -0,0 +1,143 @@ | |||
1 | from typing import TYPE_CHECKING, Iterator | ||
2 | |||
3 | from BaseClasses import MultiWorld, CollectionState, ItemClassification, Region, Entrance | ||
4 | from NetUtils import NetworkItem | ||
5 | from . import Lingo2World, Lingo2Item | ||
6 | from .regions import connect_ports_from_ut | ||
7 | from .options import Lingo2Options, ShuffleLetters | ||
8 | |||
9 | if TYPE_CHECKING: | ||
10 | from .context import Lingo2Manager | ||
11 | |||
12 | PLAYER_NUM = 1 | ||
13 | |||
14 | |||
15 | class Tracker: | ||
16 | manager: "Lingo2Manager" | ||
17 | |||
18 | multiworld: MultiWorld | ||
19 | world: Lingo2World | ||
20 | |||
21 | collected_items: dict[int, int] | ||
22 | checked_locations: set[int] | ||
23 | accessible_locations: set[int] | ||
24 | accessible_worldports: set[int] | ||
25 | goal_accessible: bool | ||
26 | |||
27 | state: CollectionState | ||
28 | |||
29 | def __init__(self, manager: "Lingo2Manager"): | ||
30 | self.manager = manager | ||
31 | self.collected_items = {} | ||
32 | self.checked_locations = set() | ||
33 | self.accessible_locations = set() | ||
34 | self.accessible_worldports = set() | ||
35 | self.goal_accessible = False | ||
36 | |||
37 | def setup_slot(self, slot_data): | ||
38 | Lingo2World.for_tracker = True | ||
39 | |||
40 | self.multiworld = MultiWorld(players=PLAYER_NUM) | ||
41 | self.world = Lingo2World(self.multiworld, PLAYER_NUM) | ||
42 | self.multiworld.worlds[1] = self.world | ||
43 | self.world.options = Lingo2Options(**{k: t(slot_data.get(k, t.default)) | ||
44 | for k, t in Lingo2Options.type_hints.items()}) | ||
45 | |||
46 | self.world.generate_early() | ||
47 | self.world.create_regions() | ||
48 | |||
49 | if self.world.options.shuffle_worldports: | ||
50 | port_pairings = {int(fp): int(tp) for fp, tp in slot_data["port_pairings"].items()} | ||
51 | connect_ports_from_ut(port_pairings, self.world) | ||
52 | |||
53 | self.refresh_state() | ||
54 | |||
55 | def set_checked_locations(self, checked_locations: set[int]): | ||
56 | self.checked_locations = checked_locations.copy() | ||
57 | |||
58 | def set_collected_items(self, network_items: list[NetworkItem]): | ||
59 | self.collected_items = {} | ||
60 | |||
61 | for item in network_items: | ||
62 | self.collected_items[item.item] = self.collected_items.get(item.item, 0) + 1 | ||
63 | |||
64 | self.refresh_state() | ||
65 | |||
66 | def refresh_state(self): | ||
67 | self.state = CollectionState(self.multiworld) | ||
68 | |||
69 | for item_id, item_amount in self.collected_items.items(): | ||
70 | for i in range(item_amount): | ||
71 | self.state.collect(Lingo2Item(Lingo2World.static_logic.item_id_to_name.get(item_id), | ||
72 | ItemClassification.progression, item_id, PLAYER_NUM), prevent_sweep=True) | ||
73 | |||
74 | for k, v in self.manager.keyboard.items(): | ||
75 | # Unless all level 1 letters are pre-unlocked, H1 I1 N1 and T1 act differently between the generator and | ||
76 | # game. The generator considers them to be unlocked, which means they are not included in logic | ||
77 | # requirements, and only one item/event is needed to unlock their level 2 forms. The game considers them to | ||
78 | # be vanilla, which means you still have to pick them up in the Starting Room in order for them to appear on | ||
79 | # your keyboard. This also means that whether or not you have the level 1 forms should be synced to the | ||
80 | # multiworld. The tracker specifically should collect one fewer item for these letters in this scenario. | ||
81 | tv = v | ||
82 | if k in "hint" and self.world.options.shuffle_letters in [ShuffleLetters.option_vanilla, | ||
83 | ShuffleLetters.option_progressive]: | ||
84 | tv = max(0, v - 1) | ||
85 | |||
86 | if tv > 0: | ||
87 | for i in range(tv): | ||
88 | self.state.collect(Lingo2Item(k.upper(), ItemClassification.progression, None, PLAYER_NUM), | ||
89 | prevent_sweep=True) | ||
90 | |||
91 | for port_id in self.manager.worldports: | ||
92 | self.state.collect(Lingo2Item(f"Worldport {port_id} Entered", ItemClassification.progression, None, | ||
93 | PLAYER_NUM), prevent_sweep=True) | ||
94 | |||
95 | self.state.sweep_for_advancements() | ||
96 | |||
97 | self.accessible_locations = set() | ||
98 | self.accessible_worldports = set() | ||
99 | self.goal_accessible = False | ||
100 | |||
101 | for region in self.state.reachable_regions[PLAYER_NUM]: | ||
102 | for location in region.locations: | ||
103 | if location.access_rule(self.state): | ||
104 | if location.address is not None: | ||
105 | if location.address not in self.checked_locations: | ||
106 | self.accessible_locations.add(location.address) | ||
107 | elif hasattr(location, "port_id"): | ||
108 | if location.port_id not in self.manager.worldports: | ||
109 | self.accessible_worldports.add(location.port_id) | ||
110 | elif hasattr(location, "goal") and location.goal: | ||
111 | if not self.manager.goaled: | ||
112 | self.goal_accessible = True | ||
113 | |||
114 | def get_path_to_location(self, location_id: int) -> list[str] | None: | ||
115 | location_name = self.world.location_id_to_name.get(location_id) | ||
116 | location = self.multiworld.get_location(location_name, PLAYER_NUM) | ||
117 | return self.get_logical_path(location.parent_region) | ||
118 | |||
119 | def get_path_to_port(self, port_id: int) -> list[str] | None: | ||
120 | port = self.world.static_logic.objects.ports[port_id] | ||
121 | region_name = self.world.static_logic.get_room_region_name(port.room_id) | ||
122 | region = self.multiworld.get_region(region_name, PLAYER_NUM) | ||
123 | return self.get_logical_path(region) | ||
124 | |||
125 | def get_path_to_goal(self): | ||
126 | room_id = self.world.player_logic.goal_room_id | ||
127 | region_name = self.world.static_logic.get_room_region_name(room_id) | ||
128 | region = self.multiworld.get_region(region_name, PLAYER_NUM) | ||
129 | return self.get_logical_path(region) | ||
130 | |||
131 | def get_logical_path(self, region: Region) -> list[str] | None: | ||
132 | if region not in self.state.path: | ||
133 | return None | ||
134 | |||
135 | def flist_to_iter(path_value) -> Iterator[str]: | ||
136 | while path_value: | ||
137 | region_or_entrance, path_value = path_value | ||
138 | yield region_or_entrance | ||
139 | |||
140 | reversed_path = self.state.path.get(region) | ||
141 | flat_path = reversed(list(map(str, flist_to_iter(reversed_path)))) | ||
142 | |||
143 | return list(flat_path)[1::2] | ||
diff --git a/client/archipelago.tscn b/client/archipelago.tscn new file mode 100644 index 0000000..1c156a3 --- /dev/null +++ b/client/archipelago.tscn | |||
@@ -0,0 +1,153 @@ | |||
1 | [gd_scene load_steps=3 format=3 uid="uid://b5mj3cq2bcesd"] | ||
2 | |||
3 | [ext_resource type="Theme" uid="uid://7w454egydi41" path="res://assets/themes/baseUI.tres" id="1_mw3f1"] | ||
4 | |||
5 | [sub_resource id=2 type="GDScript"] | ||
6 | script/source = "extends Node2D | ||
7 | |||
8 | const CACHE_PATH = \"user://apworld_path.txt\" | ||
9 | |||
10 | |||
11 | func _ready(): | ||
12 | if FileAccess.file_exists(CACHE_PATH): | ||
13 | var file = FileAccess.open(CACHE_PATH, FileAccess.READ) | ||
14 | $Panel/HBoxContainer/LineEdit.text = file.get_as_text() | ||
15 | file.close() | ||
16 | |||
17 | |||
18 | func _browse_pressed(): | ||
19 | $FileDialog.popup_centered() | ||
20 | |||
21 | |||
22 | func _file_selected(path): | ||
23 | $Panel/HBoxContainer/LineEdit.text = path | ||
24 | |||
25 | |||
26 | func _start_pressed(): | ||
27 | var apworld_path = $Panel/HBoxContainer/LineEdit.text | ||
28 | |||
29 | if not FileAccess.file_exists(apworld_path): | ||
30 | $AcceptDialog.popup_centered() | ||
31 | return | ||
32 | |||
33 | var zip_reader = ZIPReader.new() | ||
34 | zip_reader.open(apworld_path) | ||
35 | |||
36 | var inner_path = \"lingo2/client/apworld_runtime.gd\" | ||
37 | if not zip_reader.file_exists(inner_path): | ||
38 | zip_reader.close() | ||
39 | $AcceptDialog.popup_centered() | ||
40 | return | ||
41 | |||
42 | var cache_file = FileAccess.open(CACHE_PATH, FileAccess.WRITE) | ||
43 | cache_file.store_string(apworld_path) | ||
44 | cache_file.close() | ||
45 | |||
46 | var runtime_script = GDScript.new() | ||
47 | runtime_script.source_code = zip_reader.read_file(inner_path).get_string_from_utf8() | ||
48 | runtime_script.reload() | ||
49 | |||
50 | zip_reader.close() | ||
51 | |||
52 | var runtime = runtime_script.new(apworld_path) | ||
53 | runtime.name = \"Runtime\" | ||
54 | |||
55 | global.add_child(runtime) | ||
56 | |||
57 | runtime.load_script_as_scene.call_deferred(\"settings_screen.gd\", \"settings_screen\") | ||
58 | |||
59 | |||
60 | func _quit_pressed(): | ||
61 | get_tree().change_scene_to_file(\"res://objects/scenes/menus/main_menu.tscn\") | ||
62 | |||
63 | " | ||
64 | |||
65 | [node name="Node2D" type="Node2D"] | ||
66 | script = SubResource( 2 ) | ||
67 | |||
68 | [node name="Panel" type="Panel" parent="."] | ||
69 | anchors_preset = -1 | ||
70 | offset_right = 1920.0 | ||
71 | offset_bottom = 1080.0 | ||
72 | |||
73 | [node name="Label" type="Label" parent="Panel"] | ||
74 | layout_mode = 1 | ||
75 | anchors_preset = -1 | ||
76 | offset_top = 75.0 | ||
77 | offset_right = 1920.0 | ||
78 | offset_bottom = 225.0 | ||
79 | theme = ExtResource("1_mw3f1") | ||
80 | text = "archipelago" | ||
81 | horizontal_alignment = 1 | ||
82 | vertical_alignment = 1 | ||
83 | |||
84 | [node name="Label2" type="Label" parent="Panel"] | ||
85 | layout_mode = 1 | ||
86 | anchors_preset = -1 | ||
87 | anchor_right = 1.0 | ||
88 | offset_left = 80.0 | ||
89 | offset_top = 300.0 | ||
90 | offset_right = -80.0 | ||
91 | offset_bottom = 388.0 | ||
92 | theme = ExtResource("1_mw3f1") | ||
93 | theme_override_font_sizes/font_size = 56 | ||
94 | text = "Put the path to your lingo2.apworld in the below field and click start. Then, open the archipelago launcher and click \"Lingo 2 Client\"." | ||
95 | horizontal_alignment = 1 | ||
96 | autowrap_mode = 3 | ||
97 | |||
98 | [node name="HBoxContainer" type="HBoxContainer" parent="Panel"] | ||
99 | layout_mode = 1 | ||
100 | anchors_preset = -1 | ||
101 | anchor_right = 1.0 | ||
102 | offset_left = 80.0 | ||
103 | offset_top = 595.0 | ||
104 | offset_right = -80.0 | ||
105 | offset_bottom = 755.0 | ||
106 | theme_override_constants/separation = 32 | ||
107 | |||
108 | [node name="LineEdit" type="LineEdit" parent="Panel/HBoxContainer"] | ||
109 | layout_mode = 2 | ||
110 | size_flags_horizontal = 3 | ||
111 | |||
112 | [node name="Button" type="Button" parent="Panel/HBoxContainer"] | ||
113 | layout_mode = 2 | ||
114 | theme = ExtResource("1_mw3f1") | ||
115 | text = "browse" | ||
116 | |||
117 | [node name="StartButton" type="Button" parent="Panel"] | ||
118 | layout_mode = 1 | ||
119 | anchors_preset = -1 | ||
120 | offset_left = 255.0 | ||
121 | offset_top = 875.0 | ||
122 | offset_right = 891.0 | ||
123 | offset_bottom = 1025.0 | ||
124 | theme = ExtResource("1_mw3f1") | ||
125 | text = "start" | ||
126 | |||
127 | [node name="QuitButton" type="Button" parent="Panel"] | ||
128 | layout_mode = 1 | ||
129 | anchors_preset = -1 | ||
130 | offset_left = 1102.0 | ||
131 | offset_top = 875.0 | ||
132 | offset_right = 1738.0 | ||
133 | offset_bottom = 1025.0 | ||
134 | theme = ExtResource("1_mw3f1") | ||
135 | text = "back" | ||
136 | |||
137 | [node name="FileDialog" type="FileDialog" parent="."] | ||
138 | title = "Open a File" | ||
139 | size = Vector2i(512, 512) | ||
140 | ok_button_text = "Open" | ||
141 | file_mode = 0 | ||
142 | access = 2 | ||
143 | filters = PackedStringArray("*.apworld;Archipelago Worlds") | ||
144 | show_hidden_files = true | ||
145 | use_native_dialog = true | ||
146 | |||
147 | [node name="AcceptDialog" type="AcceptDialog" parent="."] | ||
148 | dialog_text = "Could not open Lingo 2 apworld. Please check that the path is correct." | ||
149 | |||
150 | [connection signal="pressed" from="Panel/HBoxContainer/Button" to="." method="_browse_pressed"] | ||
151 | [connection signal="pressed" from="Panel/StartButton" to="." method="_start_pressed"] | ||
152 | [connection signal="pressed" from="Panel/QuitButton" to="." method="_quit_pressed"] | ||
153 | [connection signal="file_selected" from="FileDialog" to="." method="_file_selected"] | ||
diff --git a/data/README.md b/data/README.md new file mode 100644 index 0000000..bf0a51b --- /dev/null +++ b/data/README.md | |||
@@ -0,0 +1,13 @@ | |||
1 | # Lingo 2 Randomizer Data | ||
2 | |||
3 | This folder contains the logic for the Lingo 2 randomizer in a human-readable | ||
4 | format. This data is compiled into a single file and used in the various parts | ||
5 | of the randomizer project (client, apworld, etc). | ||
6 | |||
7 | The data is structured using [Protocol Buffers](https://protobuf.dev/). The | ||
8 | schema for the human-readable format is | ||
9 | [located in the repository](https://code.fourisland.com/lingo2-archipelago/tree/proto/human.proto). | ||
10 | |||
11 | ## Compiling | ||
12 | |||
13 | Hi. | ||
diff --git a/data/connections.txtpb b/data/connections.txtpb index 057d8bb..b261d83 100644 --- a/data/connections.txtpb +++ b/data/connections.txtpb | |||
@@ -20,7 +20,7 @@ connections { | |||
20 | from { | 20 | from { |
21 | port { | 21 | port { |
22 | map: "the_entry" | 22 | map: "the_entry" |
23 | room: "Flipped Second Room" | 23 | room: "Four Rooms Entrance" |
24 | name: "FOUR" | 24 | name: "FOUR" |
25 | } | 25 | } |
26 | } | 26 | } |
@@ -141,7 +141,7 @@ connections { | |||
141 | to { | 141 | to { |
142 | port { | 142 | port { |
143 | map: "the_darkroom" | 143 | map: "the_darkroom" |
144 | room: "First Room" | 144 | room: "Cyan Hallway" |
145 | name: "COLORFUL" | 145 | name: "COLORFUL" |
146 | } | 146 | } |
147 | } | 147 | } |
@@ -157,7 +157,7 @@ connections { | |||
157 | to { | 157 | to { |
158 | port { | 158 | port { |
159 | map: "the_darkroom" | 159 | map: "the_darkroom" |
160 | room: "Second Room" | 160 | room: "Congruent Entrance" |
161 | name: "CONGRUENT" | 161 | name: "CONGRUENT" |
162 | } | 162 | } |
163 | } | 163 | } |
@@ -233,7 +233,7 @@ connections { | |||
233 | from { | 233 | from { |
234 | port { | 234 | port { |
235 | map: "the_darkroom" | 235 | map: "the_darkroom" |
236 | room: "First Room" | 236 | room: "Double Sided Entrance" |
237 | name: "DOUBLESIDED" | 237 | name: "DOUBLESIDED" |
238 | } | 238 | } |
239 | } | 239 | } |
@@ -308,6 +308,23 @@ connections { | |||
308 | name: "GALLERY" | 308 | name: "GALLERY" |
309 | } | 309 | } |
310 | } | 310 | } |
311 | oneway: true | ||
312 | } | ||
313 | connections { | ||
314 | from { | ||
315 | port { | ||
316 | map: "the_butterfly" | ||
317 | room: "Main Area" | ||
318 | name: "GALLERY" | ||
319 | } | ||
320 | } | ||
321 | to { | ||
322 | room { | ||
323 | map: "the_gallery" | ||
324 | name: "Main Area" | ||
325 | } | ||
326 | } | ||
327 | oneway: true | ||
311 | } | 328 | } |
312 | connections { | 329 | connections { |
313 | from { | 330 | from { |
@@ -618,7 +635,7 @@ connections { | |||
618 | from { | 635 | from { |
619 | port { | 636 | port { |
620 | map: "the_entry" | 637 | map: "the_entry" |
621 | room: "Link Area" | 638 | room: "Liberated Entrance" |
622 | name: "BLUE" | 639 | name: "BLUE" |
623 | } | 640 | } |
624 | } | 641 | } |
@@ -666,7 +683,7 @@ connections { | |||
666 | from { | 683 | from { |
667 | port { | 684 | port { |
668 | map: "the_entry" | 685 | map: "the_entry" |
669 | room: "Link Area" | 686 | room: "Literate Entrance" |
670 | name: "BROWN" | 687 | name: "BROWN" |
671 | } | 688 | } |
672 | } | 689 | } |
@@ -714,7 +731,7 @@ connections { | |||
714 | from { | 731 | from { |
715 | port { | 732 | port { |
716 | map: "the_orb" | 733 | map: "the_orb" |
717 | room: "B Room" | 734 | room: "Middle Room" |
718 | name: "MID" | 735 | name: "MID" |
719 | } | 736 | } |
720 | } | 737 | } |
@@ -841,6 +858,8 @@ connections { | |||
841 | } | 858 | } |
842 | oneway: true | 859 | oneway: true |
843 | } | 860 | } |
861 | # Two one-way connections because the CLUE panel only needs to be solved to | ||
862 | # go from The Great to The Partial. | ||
844 | connections { | 863 | connections { |
845 | from { | 864 | from { |
846 | port { | 865 | port { |
@@ -856,6 +875,25 @@ connections { | |||
856 | name: "GREAT" | 875 | name: "GREAT" |
857 | } | 876 | } |
858 | } | 877 | } |
878 | oneway: true | ||
879 | } | ||
880 | connections { | ||
881 | from { | ||
882 | port { | ||
883 | map: "the_partial" | ||
884 | room: "Obverse Side" | ||
885 | name: "GREAT" | ||
886 | } | ||
887 | } | ||
888 | to { | ||
889 | port { | ||
890 | map: "the_great" | ||
891 | room: "West Side" | ||
892 | name: "PARTIAL" | ||
893 | } | ||
894 | } | ||
895 | oneway: true | ||
896 | bypass_target_door: true | ||
859 | } | 897 | } |
860 | connections { | 898 | connections { |
861 | from { | 899 | from { |
@@ -925,7 +963,7 @@ connections { | |||
925 | from { | 963 | from { |
926 | port { | 964 | port { |
927 | map: "the_entry" | 965 | map: "the_entry" |
928 | room: "Lime Room" | 966 | room: "Revitalized Entrance" |
929 | name: "REVITALIZED" | 967 | name: "REVITALIZED" |
930 | } | 968 | } |
931 | } | 969 | } |
@@ -1193,6 +1231,7 @@ connections { | |||
1193 | } | 1231 | } |
1194 | } | 1232 | } |
1195 | oneway: true | 1233 | oneway: true |
1234 | roof_access: true | ||
1196 | } | 1235 | } |
1197 | connections { | 1236 | connections { |
1198 | from { | 1237 | from { |
@@ -1398,7 +1437,7 @@ connections { | |||
1398 | to { | 1437 | to { |
1399 | room { | 1438 | room { |
1400 | map: "daedalus" | 1439 | map: "daedalus" |
1401 | name: "Roof" | 1440 | name: "Castle" |
1402 | } | 1441 | } |
1403 | } | 1442 | } |
1404 | oneway: true | 1443 | oneway: true |
@@ -1434,7 +1473,6 @@ connections { | |||
1434 | name: "GREAT" | 1473 | name: "GREAT" |
1435 | } | 1474 | } |
1436 | } | 1475 | } |
1437 | door { map: "the_great" name: "Daedalus Entrance" } | ||
1438 | oneway: true | 1476 | oneway: true |
1439 | } | 1477 | } |
1440 | connections { | 1478 | connections { |
@@ -1453,6 +1491,7 @@ connections { | |||
1453 | } | 1491 | } |
1454 | } | 1492 | } |
1455 | oneway: true | 1493 | oneway: true |
1494 | bypass_target_door: true | ||
1456 | } | 1495 | } |
1457 | connections { | 1496 | connections { |
1458 | from { | 1497 | from { |
@@ -1748,12 +1787,13 @@ connections { | |||
1748 | } | 1787 | } |
1749 | } | 1788 | } |
1750 | oneway: true | 1789 | oneway: true |
1790 | bypass_target_door: true | ||
1751 | } | 1791 | } |
1752 | connections { | 1792 | connections { |
1753 | from { | 1793 | from { |
1754 | port { | 1794 | port { |
1755 | map: "the_bearer" | 1795 | map: "the_bearer" |
1756 | room: "Back Area" | 1796 | room: "Tree Entrance" |
1757 | name: "TREE" | 1797 | name: "TREE" |
1758 | } | 1798 | } |
1759 | } | 1799 | } |
@@ -1830,7 +1870,6 @@ connections { | |||
1830 | } | 1870 | } |
1831 | } | 1871 | } |
1832 | connections { | 1872 | connections { |
1833 | # Two one-way connections because the door only blocks one direction. | ||
1834 | from { | 1873 | from { |
1835 | port { | 1874 | port { |
1836 | map: "the_great" | 1875 | map: "the_great" |
@@ -1847,6 +1886,7 @@ connections { | |||
1847 | } | 1886 | } |
1848 | } | 1887 | } |
1849 | connections { | 1888 | connections { |
1889 | # Two one-way connections because the door only blocks one direction. | ||
1850 | from { | 1890 | from { |
1851 | port { | 1891 | port { |
1852 | map: "the_unkempt" | 1892 | map: "the_unkempt" |
@@ -1879,6 +1919,7 @@ connections { | |||
1879 | } | 1919 | } |
1880 | } | 1920 | } |
1881 | oneway: true | 1921 | oneway: true |
1922 | bypass_target_door: true | ||
1882 | } | 1923 | } |
1883 | connections { | 1924 | connections { |
1884 | from { | 1925 | from { |
@@ -2022,7 +2063,7 @@ connections { | |||
2022 | to { | 2063 | to { |
2023 | room { | 2064 | room { |
2024 | map: "the_wondrous" | 2065 | map: "the_wondrous" |
2025 | name: "Regular" | 2066 | name: "Huge" |
2026 | } | 2067 | } |
2027 | } | 2068 | } |
2028 | oneway: true | 2069 | oneway: true |
@@ -2404,3 +2445,34 @@ connections { | |||
2404 | } | 2445 | } |
2405 | } | 2446 | } |
2406 | } | 2447 | } |
2448 | connections { | ||
2449 | from { | ||
2450 | painting { | ||
2451 | map: "the_entry" | ||
2452 | room: "Eye Room" | ||
2453 | name: "GALLERY" | ||
2454 | } | ||
2455 | } | ||
2456 | to { | ||
2457 | room { | ||
2458 | map: "the_gallery" | ||
2459 | name: "Main Area" | ||
2460 | } | ||
2461 | } | ||
2462 | oneway: true | ||
2463 | } | ||
2464 | connections { | ||
2465 | from { | ||
2466 | room { | ||
2467 | map: "the_sun_temple" | ||
2468 | name: "Temple" | ||
2469 | } | ||
2470 | } | ||
2471 | to { | ||
2472 | room { | ||
2473 | map: "the_graveyard" | ||
2474 | name: "Outside" | ||
2475 | } | ||
2476 | } | ||
2477 | oneway: true | ||
2478 | } | ||
diff --git a/data/door_groups.txtpb b/data/door_groups.txtpb new file mode 100644 index 0000000..ca94223 --- /dev/null +++ b/data/door_groups.txtpb | |||
@@ -0,0 +1,163 @@ | |||
1 | door_groups { | ||
2 | name: "The Entry - Repetitive Entrance" | ||
3 | # This *should* be a CONNECTOR, but currently we're not shuffling these | ||
4 | # entrances because we want to guarantee that there's a way to The Repetitive | ||
5 | # without missing keys in vanilla doors. Hopefully can be changed eventually. | ||
6 | type: SHUFFLE_GROUP | ||
7 | doors { | ||
8 | map: "the_entry" | ||
9 | name: "Starting Room West Wall North Door" | ||
10 | } | ||
11 | doors { | ||
12 | map: "the_repetitive" | ||
13 | name: "Entry Entrance" | ||
14 | } | ||
15 | } | ||
16 | door_groups { | ||
17 | name: "The Repetitive - Plaza Entrance" | ||
18 | type: CONNECTOR | ||
19 | doors { | ||
20 | map: "the_repetitive" | ||
21 | name: "Black Hallway" | ||
22 | } | ||
23 | doors { | ||
24 | map: "the_plaza" | ||
25 | name: "Repetitive Entrance" | ||
26 | } | ||
27 | } | ||
28 | door_groups { | ||
29 | name: "Control Center White Doors" | ||
30 | type: COLOR_CONNECTOR | ||
31 | doors { | ||
32 | map: "daedalus" | ||
33 | name: "White Hallway From Entry" | ||
34 | } | ||
35 | doors { | ||
36 | map: "the_entry" | ||
37 | name: "Control Center White Door" | ||
38 | } | ||
39 | } | ||
40 | door_groups { | ||
41 | name: "Control Center Purple Doors" | ||
42 | type: COLOR_CONNECTOR | ||
43 | doors { | ||
44 | map: "daedalus" | ||
45 | name: "Purple Hallway From Great" | ||
46 | } | ||
47 | doors { | ||
48 | map: "the_great" | ||
49 | name: "Control Center Purple Door" | ||
50 | } | ||
51 | } | ||
52 | door_groups { | ||
53 | name: "Control Center Orange Doors" | ||
54 | type: COLOR_CONNECTOR | ||
55 | doors { | ||
56 | map: "daedalus" | ||
57 | name: "Control Center Orange Door" | ||
58 | } | ||
59 | doors { | ||
60 | map: "the_unkempt" | ||
61 | name: "Control Center Orange Door" | ||
62 | } | ||
63 | } | ||
64 | door_groups { | ||
65 | name: "Control Center Brown Doors" | ||
66 | type: COLOR_CONNECTOR | ||
67 | doors { | ||
68 | map: "the_bearer" | ||
69 | name: "Control Center Brown Door" | ||
70 | } | ||
71 | doors { | ||
72 | map: "the_tree" | ||
73 | name: "Control Center Brown Door" | ||
74 | } | ||
75 | } | ||
76 | door_groups { | ||
77 | name: "Control Center Blue Doors" | ||
78 | type: COLOR_CONNECTOR | ||
79 | doors { | ||
80 | map: "the_digital" | ||
81 | name: "Control Center Blue Door" | ||
82 | } | ||
83 | doors { | ||
84 | map: "the_unyielding" | ||
85 | name: "Digital Entrance" | ||
86 | } | ||
87 | } | ||
88 | door_groups { | ||
89 | name: "Cyan Doors" | ||
90 | type: CYAN_DOORS | ||
91 | doors { | ||
92 | map: "daedalus" | ||
93 | name: "Eye Painting" | ||
94 | } | ||
95 | doors { | ||
96 | map: "the_bearer" | ||
97 | name: "Butterfly Entrance" | ||
98 | } | ||
99 | doors { | ||
100 | map: "the_darkroom" | ||
101 | name: "Double Letter Panel Blockers" | ||
102 | } | ||
103 | doors { | ||
104 | map: "the_entry" | ||
105 | name: "Starting Room West Wall North Door" | ||
106 | } | ||
107 | doors { | ||
108 | map: "the_entry" | ||
109 | name: "Flipped Pyramid Area Entrance" | ||
110 | } | ||
111 | doors { | ||
112 | map: "the_entry" | ||
113 | name: "Near D Room Painting" | ||
114 | } | ||
115 | doors { | ||
116 | map: "the_graveyard" | ||
117 | name: "Double Letters" | ||
118 | } | ||
119 | doors { | ||
120 | map: "the_great" | ||
121 | name: "Tower Entrance" | ||
122 | } | ||
123 | doors { | ||
124 | map: "the_great" | ||
125 | name: "Cyan Doors" | ||
126 | } | ||
127 | doors { | ||
128 | map: "the_parthenon" | ||
129 | name: "Double Letters" | ||
130 | } | ||
131 | doors { | ||
132 | map: "the_unkempt" | ||
133 | name: "Cyan Doors" | ||
134 | } | ||
135 | doors { | ||
136 | map: "the_unkempt" | ||
137 | name: "Control Center Orange Door" | ||
138 | } | ||
139 | doors { | ||
140 | map: "the_unyielding" | ||
141 | name: "Cyan Doors" | ||
142 | } | ||
143 | } | ||
144 | door_groups { | ||
145 | name: "Lavender Cubes" | ||
146 | type: SHUFFLE_GROUP | ||
147 | doors { | ||
148 | map: "daedalus" | ||
149 | name: "C Keyholder Blocker" | ||
150 | } | ||
151 | doors { | ||
152 | map: "the_congruent" | ||
153 | name: "T Keyholder Blocker" | ||
154 | } | ||
155 | doors { | ||
156 | map: "the_great" | ||
157 | name: "Lavender Cube" | ||
158 | } | ||
159 | doors { | ||
160 | map: "the_parthenon" | ||
161 | name: "Lavender Cubes" | ||
162 | } | ||
163 | } | ||
diff --git a/data/ids.yaml b/data/ids.yaml index 39bdfde..45c9ea0 100644 --- a/data/ids.yaml +++ b/data/ids.yaml | |||
@@ -20,6 +20,11 @@ maps: | |||
20 | panels: | 20 | panels: |
21 | COLOR: 2726 | 21 | COLOR: 2726 |
22 | Letters: 2727 | 22 | Letters: 2727 |
23 | keyholders: | ||
24 | 1: 2760 | ||
25 | 2: 2761 | ||
26 | 3: 2762 | ||
27 | 4: 2763 | ||
23 | Partial Entrance: | 28 | Partial Entrance: |
24 | panels: | 29 | panels: |
25 | PARTIAL: 2729 | 30 | PARTIAL: 2729 |
@@ -155,6 +160,9 @@ maps: | |||
155 | Brown Smiley: | 160 | Brown Smiley: |
156 | panels: | 161 | panels: |
157 | OTHERS: 1667 | 162 | OTHERS: 1667 |
163 | C Keyholder: | ||
164 | keyholders: | ||
165 | C: 2755 | ||
158 | Castle: | 166 | Castle: |
159 | panels: | 167 | panels: |
160 | FIVE (Blue): 1673 | 168 | FIVE (Blue): 1673 |
@@ -265,6 +273,9 @@ maps: | |||
265 | SUMMER: 1754 | 273 | SUMMER: 1754 |
266 | WORD: 1753 | 274 | WORD: 1753 |
267 | WORDWORD: 1761 | 275 | WORDWORD: 1761 |
276 | D Keyholder: | ||
277 | keyholders: | ||
278 | D: 2759 | ||
268 | Dark Light Exit: | 279 | Dark Light Exit: |
269 | panels: | 280 | panels: |
270 | GASKET: 1763 | 281 | GASKET: 1763 |
@@ -287,6 +298,9 @@ maps: | |||
287 | Eye Painting: | 298 | Eye Painting: |
288 | panels: | 299 | panels: |
289 | REVILED: 1777 | 300 | REVILED: 1777 |
301 | F Keyholder: | ||
302 | keyholders: | ||
303 | F: 2756 | ||
290 | F2 Room: | 304 | F2 Room: |
291 | panels: | 305 | panels: |
292 | CAST: 1782 | 306 | CAST: 1782 |
@@ -480,6 +494,8 @@ maps: | |||
480 | panels: | 494 | panels: |
481 | GOING: 1934 | 495 | GOING: 1934 |
482 | TURN: 1935 | 496 | TURN: 1935 |
497 | keyholders: | ||
498 | G: 2757 | ||
483 | Nursery: | 499 | Nursery: |
484 | panels: | 500 | panels: |
485 | "?": 1937 | 501 | "?": 1937 |
@@ -547,6 +563,8 @@ maps: | |||
547 | WALLS: 1986 | 563 | WALLS: 1986 |
548 | WHISPER: 1978 | 564 | WHISPER: 1978 |
549 | WING: 1979 | 565 | WING: 1979 |
566 | keyholders: | ||
567 | H: 2758 | ||
550 | Outside Magic Room: | 568 | Outside Magic Room: |
551 | panels: | 569 | panels: |
552 | WIZARD: 1988 | 570 | WIZARD: 1988 |
@@ -730,7 +748,7 @@ maps: | |||
730 | Back (2): 2090 | 748 | Back (2): 2090 |
731 | Colors: 2097 | 749 | Colors: 2097 |
732 | FIR: 2095 | 750 | FIR: 2095 |
733 | Left: 2088 | 751 | Near Obscured Puzzles: 2088 |
734 | OAK: 2093 | 752 | OAK: 2093 |
735 | PINE: 2094 | 753 | PINE: 2094 |
736 | WALK BACK: 2091 | 754 | WALK BACK: 2091 |
@@ -879,7 +897,6 @@ maps: | |||
879 | REDACTED: 2274 | 897 | REDACTED: 2274 |
880 | STRINGS: 2205 | 898 | STRINGS: 2205 |
881 | WINDS: 2204 | 899 | WINDS: 2204 |
882 | "[REDACTED]": 2207 | ||
883 | Yellow Color Door: | 900 | Yellow Color Door: |
884 | panels: | 901 | panels: |
885 | Paintings: 2210 | 902 | Paintings: 2210 |
@@ -970,7 +987,6 @@ maps: | |||
970 | Blue Rainbow Room: 1538 | 987 | Blue Rainbow Room: 1538 |
971 | Blue Room: 1477 | 988 | Blue Room: 1477 |
972 | Blue Room Entrance: 1476 | 989 | Blue Room Entrance: 1476 |
973 | Blue Smiley Entrance: 1478 | ||
974 | Blue Smiley Exit To Red: 1547 | 990 | Blue Smiley Exit To Red: 1547 |
975 | Book Room Entrance: 1588 | 991 | Book Room Entrance: 1588 |
976 | Book Room Exit: 1592 | 992 | Book Room Exit: 1592 |
@@ -998,12 +1014,13 @@ maps: | |||
998 | Dark Light Room Exit: 1570 | 1014 | Dark Light Room Exit: 1570 |
999 | Dark Light Room Exit Panel: 1571 | 1015 | Dark Light Room Exit Panel: 1571 |
1000 | Entry Shortcut Secret Exit: 1437 | 1016 | Entry Shortcut Secret Exit: 1437 |
1017 | Eye Painting: 2751 | ||
1001 | Eye Painting Exit: 1446 | 1018 | Eye Painting Exit: 1446 |
1002 | F Keyholder Door: 1551 | 1019 | F Keyholder Door: 1551 |
1003 | F2 Room Back Left Door: 1491 | 1020 | F2 Room Northwest Door: 1491 |
1004 | F2 Room Back Middle Door: 1492 | 1021 | F2 Room Southeast Door: 1487 |
1005 | F2 Room Back Right Door: 1490 | 1022 | F2 Room Southwest Door: 1490 |
1006 | F2 Room Entrance: 1487 | 1023 | F2 Room West Door: 1492 |
1007 | Flip Painting Blocker: 1552 | 1024 | Flip Painting Blocker: 1552 |
1008 | Globe Room East Door: 1589 | 1025 | Globe Room East Door: 1589 |
1009 | Globe Room South Door: 1591 | 1026 | Globe Room South Door: 1591 |
@@ -1026,6 +1043,7 @@ maps: | |||
1026 | House Entrance: 1495 | 1043 | House Entrance: 1495 |
1027 | House Side Door: 1566 | 1044 | House Side Door: 1566 |
1028 | Intense Room Entrance: 1522 | 1045 | Intense Room Entrance: 1522 |
1046 | Lime Hexes: 2810 | ||
1029 | Magenta Hexes: 2272 | 1047 | Magenta Hexes: 2272 |
1030 | Magic Room Entrance: 1500 | 1048 | Magic Room Entrance: 1500 |
1031 | Magic Room Panels: 1499 | 1049 | Magic Room Panels: 1499 |
@@ -1037,7 +1055,9 @@ maps: | |||
1037 | Near Sweet Blue Door: 1573 | 1055 | Near Sweet Blue Door: 1573 |
1038 | Near Sweet Brown Door: 1561 | 1056 | Near Sweet Brown Door: 1561 |
1039 | Near Yellow Room Door: 1565 | 1057 | Near Yellow Room Door: 1565 |
1040 | O2 Room Back Door: 1485 | 1058 | North Castle Panel: 2742 |
1059 | O2 Room Northeast Door: 1485 | ||
1060 | O2 Room Southeast Door: 1478 | ||
1041 | Orange Rainbow Panel: 2267 | 1061 | Orange Rainbow Panel: 2267 |
1042 | Orange Rainbow Room: 1535 | 1062 | Orange Rainbow Room: 1535 |
1043 | Orange Room: 1507 | 1063 | Orange Room: 1507 |
@@ -1064,6 +1084,7 @@ maps: | |||
1064 | Purple NW Vestibule: 1459 | 1084 | Purple NW Vestibule: 1459 |
1065 | Purple Rainbow Panel: 2271 | 1085 | Purple Rainbow Panel: 2271 |
1066 | Purple Rainbow Room: 1539 | 1086 | Purple Rainbow Room: 1539 |
1087 | Purple Room: 2741 | ||
1067 | Purple Room East Entrance: 1472 | 1088 | Purple Room East Entrance: 1472 |
1068 | Purple Room North Entrance: 1469 | 1089 | Purple Room North Entrance: 1469 |
1069 | Purple Room South Entrance: 1470 | 1090 | Purple Room South Entrance: 1470 |
@@ -1088,9 +1109,10 @@ maps: | |||
1088 | Snake Room Entrance: 1514 | 1109 | Snake Room Entrance: 1514 |
1089 | South Castle Area Back Door: 1574 | 1110 | South Castle Area Back Door: 1574 |
1090 | South Castle Area Entrance: 1575 | 1111 | South Castle Area Entrance: 1575 |
1112 | South Castle Panel: 2744 | ||
1091 | Southwest Area Intersection: 1475 | 1113 | Southwest Area Intersection: 1475 |
1092 | Splintering Exit Left Door: 1449 | 1114 | Splintering Exit North Door: 1449 |
1093 | Splintering Exit Right Door: 1450 | 1115 | Splintering Exit South Door: 1450 |
1094 | Starting Room East Wall Center Door: 1439 | 1116 | Starting Room East Wall Center Door: 1439 |
1095 | Starting Room East Wall North Door: 1440 | 1117 | Starting Room East Wall North Door: 1440 |
1096 | Starting Room North Wall Center Door: 1432 | 1118 | Starting Room North Wall Center Door: 1432 |
@@ -1103,15 +1125,17 @@ maps: | |||
1103 | Starting Room West Wall South Door: 1433 | 1125 | Starting Room West Wall South Door: 1433 |
1104 | Sticks And Stones Door: 1593 | 1126 | Sticks And Stones Door: 1593 |
1105 | Temple of the Eyes Entrance: 1444 | 1127 | Temple of the Eyes Entrance: 1444 |
1106 | U2 Room Back Door: 1497 | 1128 | Theo Panels: 2811 |
1107 | U2 Room Back Right Door: 1496 | 1129 | U2 Room East Door: 1498 |
1108 | U2 Room Entrance: 1498 | 1130 | U2 Room Southeast Door: 1493 |
1109 | U2 Room Shortcut: 1493 | 1131 | U2 Room Southwest Door: 1496 |
1132 | U2 Room West Door: 1497 | ||
1110 | Welcome Back Door: 1435 | 1133 | Welcome Back Door: 1435 |
1111 | Welcome Back Secret Door: 1434 | 1134 | Welcome Back Secret Door: 1434 |
1135 | West Castle Panel: 2743 | ||
1112 | White Hallway From Entry: 1488 | 1136 | White Hallway From Entry: 1488 |
1113 | Wonderland Left Door: 1520 | 1137 | Wonderland North Door: 1520 |
1114 | Wonderland Right Door: 1504 | 1138 | Wonderland South Door: 1504 |
1115 | Yellow Rainbow Panel: 2268 | 1139 | Yellow Rainbow Panel: 2268 |
1116 | Yellow Rainbow Room: 1536 | 1140 | Yellow Rainbow Room: 1536 |
1117 | Yellow Room: 1568 | 1141 | Yellow Room: 1568 |
@@ -1155,6 +1179,9 @@ maps: | |||
1155 | SWAY: 24 | 1179 | SWAY: 24 |
1156 | TERROR: 20 | 1180 | TERROR: 20 |
1157 | TURN: 22 | 1181 | TURN: 22 |
1182 | Keyholder Room: | ||
1183 | keyholders: | ||
1184 | A: 2773 | ||
1158 | Synonyms Room: | 1185 | Synonyms Room: |
1159 | panels: | 1186 | panels: |
1160 | ADORE: 26 | 1187 | ADORE: 26 |
@@ -1191,7 +1218,6 @@ maps: | |||
1191 | panels: | 1218 | panels: |
1192 | THIS: 45 | 1219 | THIS: 45 |
1193 | doors: | 1220 | doors: |
1194 | End Door: 42 | ||
1195 | Front Door: 41 | 1221 | Front Door: 41 |
1196 | Lavender Cubes: 43 | 1222 | Lavender Cubes: 43 |
1197 | the_bearer: | 1223 | the_bearer: |
@@ -1272,7 +1298,6 @@ maps: | |||
1272 | Control Center Brown Door: 49 | 1298 | Control Center Brown Door: 49 |
1273 | Exit Door: 47 | 1299 | Exit Door: 47 |
1274 | Overlook Door: 46 | 1300 | Overlook Door: 46 |
1275 | Q2 Door: 48 | ||
1276 | the_between: | 1301 | the_between: |
1277 | rooms: | 1302 | rooms: |
1278 | Control Center Side: | 1303 | Control Center Side: |
@@ -1447,6 +1472,9 @@ maps: | |||
1447 | panels: | 1472 | panels: |
1448 | CIVIL: 216 | 1473 | CIVIL: 216 |
1449 | CRABS: 217 | 1474 | CRABS: 217 |
1475 | T Keyholder: | ||
1476 | keyholders: | ||
1477 | T: 2754 | ||
1450 | doors: | 1478 | doors: |
1451 | C Keyholder Blocker: 176 | 1479 | C Keyholder Blocker: 176 |
1452 | C2 Door: 177 | 1480 | C2 Door: 177 |
@@ -1458,7 +1486,6 @@ maps: | |||
1458 | Obverse Magenta Door: 173 | 1486 | Obverse Magenta Door: 173 |
1459 | Obverse Yellow Door: 178 | 1487 | Obverse Yellow Door: 178 |
1460 | Obverse Yellow Puzzles: 179 | 1488 | Obverse Yellow Puzzles: 179 |
1461 | T Keyholder Blocker: 183 | ||
1462 | the_darkroom: | 1489 | the_darkroom: |
1463 | rooms: | 1490 | rooms: |
1464 | First Room: | 1491 | First Room: |
@@ -1489,9 +1516,7 @@ maps: | |||
1489 | doors: | 1516 | doors: |
1490 | Colorful Entrance: 222 | 1517 | Colorful Entrance: 222 |
1491 | Congruent Entrance: 223 | 1518 | Congruent Entrance: 223 |
1492 | Double Letter Panel Blockers: 218 | ||
1493 | Double Sided Entrance: 224 | 1519 | Double Sided Entrance: 224 |
1494 | S1 Door: 221 | ||
1495 | Second Room Entrance: 219 | 1520 | Second Room Entrance: 219 |
1496 | Third Room Entrance: 220 | 1521 | Third Room Entrance: 220 |
1497 | the_digital: | 1522 | the_digital: |
@@ -1610,10 +1635,6 @@ maps: | |||
1610 | Flipped Link Area: | 1635 | Flipped Link Area: |
1611 | panels: | 1636 | panels: |
1612 | WANDER: 340 | 1637 | WANDER: 340 |
1613 | Flipped Pyramid Area: | ||
1614 | panels: | ||
1615 | TURN (1): 341 | ||
1616 | TURN (2): 342 | ||
1617 | Flipped Right Eye: | 1638 | Flipped Right Eye: |
1618 | panels: | 1639 | panels: |
1619 | HERE: 344 | 1640 | HERE: 344 |
@@ -1637,6 +1658,9 @@ maps: | |||
1637 | STEALER: 352 | 1658 | STEALER: 352 |
1638 | TRUST: 354 | 1659 | TRUST: 354 |
1639 | WANT: 351 | 1660 | WANT: 351 |
1661 | Liberated Entrance Panel: | ||
1662 | panels: | ||
1663 | TURN (1): 341 | ||
1640 | Lime Room: | 1664 | Lime Room: |
1641 | panels: | 1665 | panels: |
1642 | COLOR: 361 | 1666 | COLOR: 361 |
@@ -1645,12 +1669,19 @@ maps: | |||
1645 | Link Area: | 1669 | Link Area: |
1646 | panels: | 1670 | panels: |
1647 | WANDER: 362 | 1671 | WANDER: 362 |
1672 | Literate Entrance Panel: | ||
1673 | panels: | ||
1674 | TURN (2): 342 | ||
1648 | Parthenon Return: | 1675 | Parthenon Return: |
1649 | panels: | 1676 | panels: |
1650 | RETURN: 363 | 1677 | RETURN: 363 |
1651 | Rabbit Hole: | 1678 | Rabbit Hole: |
1652 | panels: | 1679 | panels: |
1653 | PUZZLE: 364 | 1680 | PUZZLE: 364 |
1681 | Rabbit Hole Lock: | ||
1682 | panels: | ||
1683 | HOLE: 2749 | ||
1684 | RABBIT: 2748 | ||
1654 | Red Alcove: | 1685 | Red Alcove: |
1655 | panels: | 1686 | panels: |
1656 | BROW: 365 | 1687 | BROW: 365 |
@@ -1687,8 +1718,6 @@ maps: | |||
1687 | panels: | 1718 | panels: |
1688 | CORN: 393 | 1719 | CORN: 393 |
1689 | DICE: 392 | 1720 | DICE: 392 |
1690 | HOLE: 390 | ||
1691 | RABBIT: 389 | ||
1692 | WREATH: 391 | 1721 | WREATH: 391 |
1693 | doors: | 1722 | doors: |
1694 | Blue Alcove Entrance: 297 | 1723 | Blue Alcove Entrance: 297 |
@@ -1700,7 +1729,6 @@ maps: | |||
1700 | D Room Entrance: 319 | 1729 | D Room Entrance: 319 |
1701 | Daedalus Entrance: 311 | 1730 | Daedalus Entrance: 311 |
1702 | Flip Area Entrance: 310 | 1731 | Flip Area Entrance: 310 |
1703 | Flipped Pyramid Area Entrance: 315 | ||
1704 | Flipped Second Room Left Door: 300 | 1732 | Flipped Second Room Left Door: 300 |
1705 | Flipped Second Room Right Door: 299 | 1733 | Flipped Second Room Right Door: 299 |
1706 | Gallery Entrance: 321 | 1734 | Gallery Entrance: 321 |
@@ -1718,13 +1746,13 @@ maps: | |||
1718 | Red Blue Area Left Door: 302 | 1746 | Red Blue Area Left Door: 302 |
1719 | Red Blue Area Right Door: 303 | 1747 | Red Blue Area Right Door: 303 |
1720 | Red Room Painting: 323 | 1748 | Red Room Painting: 323 |
1721 | Repetitive Entrance: 312 | ||
1722 | Revitalized Entrance: 306 | 1749 | Revitalized Entrance: 306 |
1723 | Right Eye Entrance: 301 | 1750 | Right Eye Entrance: 301 |
1724 | Scarf Door: 296 | 1751 | Scarf Door: 296 |
1725 | Second Room Left Door: 298 | 1752 | Second Room Left Door: 298 |
1726 | Second Room Right Door: 290 | 1753 | Second Room Right Door: 290 |
1727 | Shop Entrance: 313 | 1754 | Shop Entrance: 313 |
1755 | Starting Room West Wall North Door: 2781 | ||
1728 | Third Eye Painting: 324 | 1756 | Third Eye Painting: 324 |
1729 | Trick Door: 287 | 1757 | Trick Door: 287 |
1730 | Trick To Shop Door: 289 | 1758 | Trick To Shop Door: 289 |
@@ -1751,6 +1779,8 @@ maps: | |||
1751 | X Plus: | 1779 | X Plus: |
1752 | panels: | 1780 | panels: |
1753 | ROSE: 405 | 1781 | ROSE: 405 |
1782 | keyholders: | ||
1783 | M: 2766 | ||
1754 | X Plus Middle Leg: | 1784 | X Plus Middle Leg: |
1755 | panels: | 1785 | panels: |
1756 | COLONY: 403 | 1786 | COLONY: 403 |
@@ -1780,6 +1810,9 @@ maps: | |||
1780 | Daedalus Extension: | 1810 | Daedalus Extension: |
1781 | panels: | 1811 | panels: |
1782 | WHERE: 433 | 1812 | WHERE: 433 |
1813 | Main Area: | ||
1814 | keyholders: | ||
1815 | P: 2765 | ||
1783 | doors: | 1816 | doors: |
1784 | Ancient Painting: 428 | 1817 | Ancient Painting: 428 |
1785 | Between Painting: 414 | 1818 | Between Painting: 414 |
@@ -1818,22 +1851,10 @@ maps: | |||
1818 | rooms: | 1851 | rooms: |
1819 | Back Area: | 1852 | Back Area: |
1820 | panels: | 1853 | panels: |
1821 | Left Landscape Bottom: 482 | ||
1822 | Left Landscape Left: 483 | ||
1823 | Left Landscape Right: 481 | ||
1824 | Left Landscape Top: 480 | ||
1825 | PAINTING: 474 | 1854 | PAINTING: 474 |
1826 | PLANT: 472 | 1855 | PLANT: 472 |
1827 | Right Landscape Bottom: 486 | ||
1828 | Right Landscape Left: 487 | ||
1829 | Right Landscape Right: 485 | ||
1830 | Right Landscape Top: 484 | ||
1831 | TOWEL: 475 | 1856 | TOWEL: 475 |
1832 | TREE: 473 | 1857 | TREE: 473 |
1833 | Top Landscape Bottom: 478 | ||
1834 | Top Landscape Left: 479 | ||
1835 | Top Landscape Right: 477 | ||
1836 | Top Landscape Top: 476 | ||
1837 | Behind Question Area: | 1858 | Behind Question Area: |
1838 | panels: | 1859 | panels: |
1839 | DEW: 488 | 1860 | DEW: 488 |
@@ -1964,6 +1985,8 @@ maps: | |||
1964 | LAUGH FINISHED: 573 | 1985 | LAUGH FINISHED: 573 |
1965 | PLANTS: 570 | 1986 | PLANTS: 570 |
1966 | WEATHER: 568 | 1987 | WEATHER: 568 |
1988 | keyholders: | ||
1989 | X: 2770 | ||
1967 | Outside Jail: | 1990 | Outside Jail: |
1968 | panels: | 1991 | panels: |
1969 | GUT: 575 | 1992 | GUT: 575 |
@@ -1989,6 +2012,20 @@ maps: | |||
1989 | Question Room Who: | 2012 | Question Room Who: |
1990 | panels: | 2013 | panels: |
1991 | QUESTION: 587 | 2014 | QUESTION: 587 |
2015 | The Landscapes: | ||
2016 | panels: | ||
2017 | Left Landscape Bottom: 482 | ||
2018 | Left Landscape Left: 483 | ||
2019 | Left Landscape Right: 481 | ||
2020 | Left Landscape Top: 480 | ||
2021 | Right Landscape Bottom: 486 | ||
2022 | Right Landscape Left: 487 | ||
2023 | Right Landscape Right: 485 | ||
2024 | Right Landscape Top: 484 | ||
2025 | Top Landscape Bottom: 478 | ||
2026 | Top Landscape Left: 479 | ||
2027 | Top Landscape Right: 477 | ||
2028 | Top Landscape Top: 476 | ||
1992 | Under Question Room: | 2029 | Under Question Room: |
1993 | panels: | 2030 | panels: |
1994 | QUESTION: 588 | 2031 | QUESTION: 588 |
@@ -2052,7 +2089,6 @@ maps: | |||
2052 | Into The Mouth Gravestone: 457 | 2089 | Into The Mouth Gravestone: 457 |
2053 | Invisible Entrance: 465 | 2090 | Invisible Entrance: 465 |
2054 | Jail Entrance: 451 | 2091 | Jail Entrance: 451 |
2055 | Lavender Cube: 469 | ||
2056 | Magnet Room Entrance: 449 | 2092 | Magnet Room Entrance: 449 |
2057 | Nature Room Door: 466 | 2093 | Nature Room Door: 466 |
2058 | Nature Room Panels: 467 | 2094 | Nature Room Panels: 467 |
@@ -2111,6 +2147,8 @@ maps: | |||
2111 | WAS: 631 | 2147 | WAS: 631 |
2112 | WINGS: 662 | 2148 | WINGS: 662 |
2113 | YELL: 636 | 2149 | YELL: 636 |
2150 | keyholders: | ||
2151 | B: 2769 | ||
2114 | Mastery Room: | 2152 | Mastery Room: |
2115 | masteries: | 2153 | masteries: |
2116 | MASTERY: 666 | 2154 | MASTERY: 666 |
@@ -2177,6 +2215,8 @@ maps: | |||
2177 | FLASHBACK: 705 | 2215 | FLASHBACK: 705 |
2178 | PUSH: 703 | 2216 | PUSH: 703 |
2179 | PUSHBACK: 702 | 2217 | PUSHBACK: 702 |
2218 | keyholders: | ||
2219 | J: 2772 | ||
2180 | doors: | 2220 | doors: |
2181 | Side Door: 687 | 2221 | Side Door: 687 |
2182 | the_keen: | 2222 | the_keen: |
@@ -2288,10 +2328,12 @@ maps: | |||
2288 | NAY: 774 | 2328 | NAY: 774 |
2289 | NIGH: 781 | 2329 | NIGH: 781 |
2290 | TORE: 787 | 2330 | TORE: 787 |
2331 | keyholders: | ||
2332 | S: 2767 | ||
2291 | doors: | 2333 | doors: |
2292 | Left Room Puzzles: 763 | 2334 | Blue Side Puzzles: 763 |
2293 | Main Room Puzzles: 765 | 2335 | Green Side Puzzles: 764 |
2294 | Right Room Puzzles: 764 | 2336 | Main Room Door: 2750 |
2295 | the_orb: | 2337 | the_orb: |
2296 | rooms: | 2338 | rooms: |
2297 | Main Area: | 2339 | Main Area: |
@@ -2318,6 +2360,7 @@ maps: | |||
2318 | COLOR: 823 | 2360 | COLOR: 823 |
2319 | ETCH: 837 | 2361 | ETCH: 837 |
2320 | FAINT: 821 | 2362 | FAINT: 821 |
2363 | FIZZLE: 2745 | ||
2321 | HAD: 830 | 2364 | HAD: 830 |
2322 | HEAVY: 829 | 2365 | HEAVY: 829 |
2323 | LAY: 834 | 2366 | LAY: 834 |
@@ -2350,11 +2393,10 @@ maps: | |||
2350 | panels: | 2393 | panels: |
2351 | CRUSH: 845 | 2394 | CRUSH: 845 |
2352 | RAY: 846 | 2395 | RAY: 846 |
2353 | R2C2.5 Bottom: | 2396 | R2C3 Bottom: |
2354 | panels: | 2397 | panels: |
2355 | BLACK: 849 | 2398 | BLACK: 2747 |
2356 | FIGMENT: 848 | 2399 | FIGMENT: 2746 |
2357 | FIZZLE: 847 | ||
2358 | Z Room: | 2400 | Z Room: |
2359 | panels: | 2401 | panels: |
2360 | MAZE: 850 | 2402 | MAZE: 850 |
@@ -2389,6 +2431,9 @@ maps: | |||
2389 | CLEOPATRA: 859 | 2431 | CLEOPATRA: 859 |
2390 | NAPOLEON: 860 | 2432 | NAPOLEON: 860 |
2391 | XERXES: 857 | 2433 | XERXES: 857 |
2434 | U Keyholder: | ||
2435 | keyholders: | ||
2436 | U: 2777 | ||
2392 | doors: | 2437 | doors: |
2393 | K2 Door: 852 | 2438 | K2 Door: 852 |
2394 | the_partial: | 2439 | the_partial: |
@@ -2412,6 +2457,8 @@ maps: | |||
2412 | TON: 878 | 2457 | TON: 878 |
2413 | TURN: 875 | 2458 | TURN: 875 |
2414 | UP: 870 | 2459 | UP: 870 |
2460 | keyholders: | ||
2461 | L: 2771 | ||
2415 | Reverse Side: | 2462 | Reverse Side: |
2416 | panels: | 2463 | panels: |
2417 | BRO: 884 | 2464 | BRO: 884 |
@@ -2516,20 +2563,23 @@ maps: | |||
2516 | TYPIST BEAR RIGHT WING: 968 | 2563 | TYPIST BEAR RIGHT WING: 968 |
2517 | WING: 950 | 2564 | WING: 950 |
2518 | doors: | 2565 | doors: |
2519 | Bottom Left Door: 894 | 2566 | Northeast Door: 893 |
2520 | Bottom Left Puzzles: 898 | 2567 | Northeast Puzzles: 897 |
2521 | Bottom Right Door: 895 | 2568 | Northwest Door: 892 |
2522 | Bottom Right Puzzles: 899 | 2569 | Northwest Puzzles: 896 |
2523 | Repetitive Entrance: 888 | 2570 | Repetitive Entrance: 888 |
2524 | Sirenic Entrance: 890 | 2571 | Sirenic Entrance: 890 |
2572 | Southeast Door: 895 | ||
2573 | Southeast Puzzles: 899 | ||
2574 | Southwest Door: 894 | ||
2575 | Southwest Puzzles: 898 | ||
2525 | Symbolic Entrance: 889 | 2576 | Symbolic Entrance: 889 |
2526 | Top Left Door: 892 | ||
2527 | Top Left Puzzles: 896 | ||
2528 | Top Right Door: 893 | ||
2529 | Top Right Puzzles: 897 | ||
2530 | Turtle Entrance: 891 | 2577 | Turtle Entrance: 891 |
2531 | the_quiet: | 2578 | the_quiet: |
2532 | rooms: | 2579 | rooms: |
2580 | Keyholder Room: | ||
2581 | keyholders: | ||
2582 | Q: 2778 | ||
2533 | Main Area: | 2583 | Main Area: |
2534 | panels: | 2584 | panels: |
2535 | BEE: 979 | 2585 | BEE: 979 |
@@ -2606,7 +2656,8 @@ maps: | |||
2606 | rooms: | 2656 | rooms: |
2607 | Anti Room: | 2657 | Anti Room: |
2608 | panels: | 2658 | panels: |
2609 | EYE: 1041 | 2659 | EYE (1): 1041 |
2660 | EYE (2): 2813 | ||
2610 | HA (1): 1035 | 2661 | HA (1): 1035 |
2611 | HA (2): 1036 | 2662 | HA (2): 1036 |
2612 | HA (3): 1037 | 2663 | HA (3): 1037 |
@@ -2713,7 +2764,9 @@ maps: | |||
2713 | W: 1117 | 2764 | W: 1117 |
2714 | ZEROING: 1118 | 2765 | ZEROING: 1118 |
2715 | doors: | 2766 | doors: |
2767 | Anti-Collectable: 2812 | ||
2716 | Anti-Collectable Room: 1025 | 2768 | Anti-Collectable Room: 1025 |
2769 | Black Hallway: 2780 | ||
2717 | Cyan Door: 1028 | 2770 | Cyan Door: 1028 |
2718 | Cyan Puzzles: 1032 | 2771 | Cyan Puzzles: 1032 |
2719 | Dot Area Entrance: 1026 | 2772 | Dot Area Entrance: 1026 |
@@ -2722,7 +2775,6 @@ maps: | |||
2722 | Lime Puzzles: 1031 | 2775 | Lime Puzzles: 1031 |
2723 | Magenta Door: 1029 | 2776 | Magenta Door: 1029 |
2724 | Magenta Puzzles: 1033 | 2777 | Magenta Puzzles: 1033 |
2725 | Plaza Entrance: 1024 | ||
2726 | Yellow Door: 1030 | 2778 | Yellow Door: 1030 |
2727 | Yellow Puzzles: 1034 | 2779 | Yellow Puzzles: 1034 |
2728 | the_revitalized: | 2780 | the_revitalized: |
@@ -2776,6 +2828,8 @@ maps: | |||
2776 | STIM: 1148 | 2828 | STIM: 1148 |
2777 | STONE: 1142 | 2829 | STONE: 1142 |
2778 | TADPOLES: 1159 | 2830 | TADPOLES: 1159 |
2831 | keyholders: | ||
2832 | N: 2779 | ||
2779 | doors: | 2833 | doors: |
2780 | Books Puzzles: 1136 | 2834 | Books Puzzles: 1136 |
2781 | Games Puzzles: 1137 | 2835 | Games Puzzles: 1137 |
@@ -3086,22 +3140,15 @@ maps: | |||
3086 | panels: | 3140 | panels: |
3087 | WHOLE: 2426 | 3141 | WHOLE: 2426 |
3088 | doors: | 3142 | doors: |
3089 | Black Door: 2276 | ||
3090 | Blue Door: 2278 | ||
3091 | Green Door: 2279 | ||
3092 | Main Area Fifth Row: 2290 | 3143 | Main Area Fifth Row: 2290 |
3093 | Main Area First Row: 2286 | 3144 | Main Area First Row: 2286 |
3094 | Main Area Fourth Row: 2289 | 3145 | Main Area Fourth Row: 2289 |
3095 | Main Area Second Row: 2287 | 3146 | Main Area Second Row: 2287 |
3096 | Main Area Third Row: 2288 | 3147 | Main Area Third Row: 2288 |
3097 | Orange Door: 2282 | ||
3098 | Poetry Room Panels: 2285 | 3148 | Poetry Room Panels: 2285 |
3099 | Purple Door: 2281 | 3149 | Tutorial Door: 2754 |
3100 | Red Door: 2277 | ||
3101 | Tutorial Panels: 2283 | 3150 | Tutorial Panels: 2283 |
3102 | Whirred Room Panels: 2284 | 3151 | Whirred Room Panels: 2284 |
3103 | White Door: 2275 | ||
3104 | Yellow Door: 2280 | ||
3105 | the_talented: | 3152 | the_talented: |
3106 | rooms: | 3153 | rooms: |
3107 | Back Room: | 3154 | Back Room: |
@@ -3130,6 +3177,8 @@ maps: | |||
3130 | SWINE (Brown): 2446 | 3177 | SWINE (Brown): 2446 |
3131 | WIFE (Black): 2440 | 3178 | WIFE (Black): 2440 |
3132 | WIFE (Brown): 2447 | 3179 | WIFE (Brown): 2447 |
3180 | keyholders: | ||
3181 | Y: 2764 | ||
3133 | doors: | 3182 | doors: |
3134 | Black Side Panels: 2427 | 3183 | Black Side Panels: 2427 |
3135 | Brown Side Panels: 2428 | 3184 | Brown Side Panels: 2428 |
@@ -3142,6 +3191,9 @@ maps: | |||
3142 | Control Center Entrance: | 3191 | Control Center Entrance: |
3143 | panels: | 3192 | panels: |
3144 | ZERO: 2455 | 3193 | ZERO: 2455 |
3194 | Main Area: | ||
3195 | keyholders: | ||
3196 | K: 2768 | ||
3145 | Mastery: | 3197 | Mastery: |
3146 | masteries: | 3198 | masteries: |
3147 | MASTERY: 2456 | 3199 | MASTERY: 2456 |
@@ -3346,6 +3398,8 @@ maps: | |||
3346 | WAYS: 2621 | 3398 | WAYS: 2621 |
3347 | WHILE: 2613 | 3399 | WHILE: 2613 |
3348 | ZOO: 2615 | 3400 | ZOO: 2615 |
3401 | keyholders: | ||
3402 | I: 2775 | ||
3349 | Middle Room: | 3403 | Middle Room: |
3350 | panels: | 3404 | panels: |
3351 | FELLOW: 2624 | 3405 | FELLOW: 2624 |
@@ -3393,12 +3447,18 @@ maps: | |||
3393 | UNINTERESTED: 2650 | 3447 | UNINTERESTED: 2650 |
3394 | UNIRONIC: 2656 | 3448 | UNIRONIC: 2656 |
3395 | UNLUCKY: 2654 | 3449 | UNLUCKY: 2654 |
3450 | V Keyholder: | ||
3451 | keyholders: | ||
3452 | V: 2776 | ||
3453 | W Keyholder: | ||
3454 | keyholders: | ||
3455 | W: 2774 | ||
3396 | doors: | 3456 | doors: |
3397 | Cog Rhino Hug Rug: 2586 | 3457 | Cog Rhino Hug Rug: 2586 |
3398 | Control Center Orange Door: 2582 | 3458 | Control Center Orange Door: 2582 |
3459 | East Door: 2580 | ||
3399 | Honor Our Hint: 2585 | 3460 | Honor Our Hint: 2585 |
3400 | Let Untrue Tie: 2583 | 3461 | Let Untrue Tie: 2583 |
3401 | Right Door: 2580 | ||
3402 | Routine Out Chute: 2584 | 3462 | Routine Out Chute: 2584 |
3403 | W2 Room Door: 2581 | 3463 | W2 Room Door: 2581 |
3404 | the_unyielding: | 3464 | the_unyielding: |
@@ -3638,9 +3698,9 @@ maps: | |||
3638 | HEALTH: 1428 | 3698 | HEALTH: 1428 |
3639 | doors: | 3699 | doors: |
3640 | Bearer Entrance: 1259 | 3700 | Bearer Entrance: 1259 |
3641 | Black Alcove: 2265 | ||
3642 | Brown Alcove: 1255 | 3701 | Brown Alcove: 1255 |
3643 | Digital Entrance: 1257 | 3702 | Digital Entrance: 1257 |
3703 | East Room 1: 2740 | ||
3644 | East Room 1 Entrance: 1251 | 3704 | East Room 1 Entrance: 1251 |
3645 | Hero Room Entrance: 1252 | 3705 | Hero Room Entrance: 1252 |
3646 | Jay Painting: 1253 | 3706 | Jay Painting: 1253 |
@@ -3783,4 +3843,61 @@ endings: | |||
3783 | WHITE: 2738 | 3843 | WHITE: 2738 |
3784 | YELLOW: 1206 | 3844 | YELLOW: 1206 |
3785 | special: | 3845 | special: |
3786 | Nothing: 1160 | 3846 | A Job Well Done: 1160 |
3847 | Age Symbol: 2791 | ||
3848 | Anagram Symbol: 2792 | ||
3849 | Anti A: 2814 | ||
3850 | Anti B: 2815 | ||
3851 | Anti C: 2816 | ||
3852 | Anti D: 2817 | ||
3853 | Anti E: 2818 | ||
3854 | Anti F: 2819 | ||
3855 | Anti G: 2820 | ||
3856 | Anti H: 2821 | ||
3857 | Anti I: 2822 | ||
3858 | Anti J: 2823 | ||
3859 | Anti K: 2824 | ||
3860 | Anti L: 2825 | ||
3861 | Anti M: 2826 | ||
3862 | Anti N: 2827 | ||
3863 | Anti O: 2828 | ||
3864 | Anti P: 2829 | ||
3865 | Anti Q: 2830 | ||
3866 | Anti R: 2831 | ||
3867 | Anti S: 2832 | ||
3868 | Anti T: 2833 | ||
3869 | Anti U: 2834 | ||
3870 | Anti V: 2835 | ||
3871 | Anti W: 2836 | ||
3872 | Anti X: 2837 | ||
3873 | Anti Y: 2838 | ||
3874 | Anti Z: 2839 | ||
3875 | Boxes Symbol: 2793 | ||
3876 | Cross Symbol: 2794 | ||
3877 | Eval Symbol: 2795 | ||
3878 | Example Symbol: 2796 | ||
3879 | Gender Symbol: 2797 | ||
3880 | Job Symbol: 2798 | ||
3881 | Lingo Symbol: 2799 | ||
3882 | Null Symbol: 2800 | ||
3883 | Planet Symbol: 2801 | ||
3884 | Pyramid Symbol: 2802 | ||
3885 | Question Symbol: 2803 | ||
3886 | Sound Symbol: 2804 | ||
3887 | Sparkles Symbol: 2805 | ||
3888 | Stars Symbol: 2806 | ||
3889 | Sun Symbol: 2807 | ||
3890 | Sweet Symbol: 2808 | ||
3891 | Zero Symbol: 2809 | ||
3892 | progressives: | ||
3893 | Progressive Gold Ending: 2753 | ||
3894 | door_groups: | ||
3895 | Control Center Blue Doors: 2788 | ||
3896 | Control Center Brown Doors: 2787 | ||
3897 | Control Center Orange Doors: 2786 | ||
3898 | Control Center Purple Doors: 2785 | ||
3899 | Control Center White Doors: 2784 | ||
3900 | Cyan Doors: 2789 | ||
3901 | Lavender Cubes: 2790 | ||
3902 | The Entry - Repetitive Entrance: 2782 | ||
3903 | The Repetitive - Plaza Entrance: 2783 | ||
diff --git a/data/maps/control_center/doors.txtpb b/data/maps/control_center/doors.txtpb index 0bb29c1..08476a7 100644 --- a/data/maps/control_center/doors.txtpb +++ b/data/maps/control_center/doors.txtpb | |||
@@ -109,6 +109,7 @@ doors { | |||
109 | keyholders { room: "Main Area" name: "3" key: "r" } | 109 | keyholders { room: "Main Area" name: "3" key: "r" } |
110 | keyholders { room: "Main Area" name: "4" key: "e" } | 110 | keyholders { room: "Main Area" name: "4" key: "e" } |
111 | location_room: "Main Area" | 111 | location_room: "Main Area" |
112 | location_name: "Keyword MORE" | ||
112 | } | 113 | } |
113 | doors { | 114 | doors { |
114 | name: "Perceptive From Outside" | 115 | name: "Perceptive From Outside" |
@@ -132,6 +133,7 @@ doors { | |||
132 | keyholders { room: "Main Area" name: "3" key: "r" } | 133 | keyholders { room: "Main Area" name: "3" key: "r" } |
133 | keyholders { room: "Main Area" name: "4" key: "o" } | 134 | keyholders { room: "Main Area" name: "4" key: "o" } |
134 | location_room: "Main Area" | 135 | location_room: "Main Area" |
136 | location_name: "Keyword ZERO" | ||
135 | } | 137 | } |
136 | doors { | 138 | doors { |
137 | name: "Between Door" | 139 | name: "Between Door" |
diff --git a/data/maps/control_center/rooms/Ancient Entrance.txtpb b/data/maps/control_center/rooms/Ancient Entrance.txtpb index 9fe50c5..5b65d9a 100644 --- a/data/maps/control_center/rooms/Ancient Entrance.txtpb +++ b/data/maps/control_center/rooms/Ancient Entrance.txtpb | |||
@@ -1,5 +1,10 @@ | |||
1 | name: "Ancient Entrance" | 1 | name: "Ancient Entrance" |
2 | ports { | 2 | ports { |
3 | name: "ANCIENT" | 3 | name: "ANCIENT" |
4 | display_name: "Ancient Entrance" | ||
4 | path: "Components/Warps/worldport8" | 5 | path: "Components/Warps/worldport8" |
6 | destination { x: -27 y: 0 z: -34 } | ||
7 | rotation: 90 | ||
8 | # TODO: shuffle entrances with dependent keyholders | ||
9 | no_shuffle: true | ||
5 | } | 10 | } |
diff --git a/data/maps/control_center/rooms/Between Entrance.txtpb b/data/maps/control_center/rooms/Between Entrance.txtpb index 2c21bdd..9da5344 100644 --- a/data/maps/control_center/rooms/Between Entrance.txtpb +++ b/data/maps/control_center/rooms/Between Entrance.txtpb | |||
@@ -8,5 +8,8 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "BETWEEN" | 10 | name: "BETWEEN" |
11 | display_name: "Between Connector" | ||
11 | path: "Components/Warps/worldport5" | 12 | path: "Components/Warps/worldport5" |
13 | destination { x: 39 y: 0 z: -17 } | ||
14 | rotation: 270 | ||
12 | } | 15 | } |
diff --git a/data/maps/control_center/rooms/Entry Entrance.txtpb b/data/maps/control_center/rooms/Entry Entrance.txtpb index d920523..ad882f5 100644 --- a/data/maps/control_center/rooms/Entry Entrance.txtpb +++ b/data/maps/control_center/rooms/Entry Entrance.txtpb | |||
@@ -8,5 +8,8 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "ENTRY" | 10 | name: "ENTRY" |
11 | display_name: "Entry Connector" | ||
11 | path: "Components/Warps/worldport2" | 12 | path: "Components/Warps/worldport2" |
13 | destination { x: 26 y: 0 z: -16.5 } | ||
14 | rotation: 0 | ||
12 | } | 15 | } |
diff --git a/data/maps/control_center/rooms/Entry.txtpb b/data/maps/control_center/rooms/Entry.txtpb index 7ef380c..09c21aa 100644 --- a/data/maps/control_center/rooms/Entry.txtpb +++ b/data/maps/control_center/rooms/Entry.txtpb | |||
@@ -8,5 +8,8 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "GREAT" | 10 | name: "GREAT" |
11 | display_name: "Main Entrance" | ||
11 | path: "Components/Warps/worldport" | 12 | path: "Components/Warps/worldport" |
13 | destination { x: 0 y: 0 z: -1.5 } | ||
14 | rotation: 0 | ||
12 | } | 15 | } |
diff --git a/data/maps/control_center/rooms/Main Area.txtpb b/data/maps/control_center/rooms/Main Area.txtpb index 192c02a..2c1e418 100644 --- a/data/maps/control_center/rooms/Main Area.txtpb +++ b/data/maps/control_center/rooms/Main Area.txtpb | |||
@@ -4,7 +4,7 @@ panels { | |||
4 | path: "Panels/Doors/entry_2" | 4 | path: "Panels/Doors/entry_2" |
5 | clue: "color" | 5 | clue: "color" |
6 | answer: "red" | 6 | answer: "red" |
7 | #proxies { answer: "red" path: "Panels/Colors/color_1" } | 7 | proxies { answer: "red" path: "Panels/Colors/color_1" } |
8 | proxies { answer: "blue" path: "Panels/Colors/color_2" } | 8 | proxies { answer: "blue" path: "Panels/Colors/color_2" } |
9 | proxies { answer: "green" path: "Panels/Colors/color_3" } | 9 | proxies { answer: "green" path: "Panels/Colors/color_3" } |
10 | proxies { answer: "yellow" path: "Panels/Colors/color_4" } | 10 | proxies { answer: "yellow" path: "Panels/Colors/color_4" } |
@@ -30,37 +30,52 @@ panels { | |||
30 | keyholders { | 30 | keyholders { |
31 | name: "1" | 31 | name: "1" |
32 | path: "Components/KeyHolders/keyHolder" | 32 | path: "Components/KeyHolders/keyHolder" |
33 | key: "z" | ||
33 | } | 34 | } |
34 | keyholders { | 35 | keyholders { |
35 | name: "2" | 36 | name: "2" |
36 | path: "Components/KeyHolders/keyHolder2" | 37 | path: "Components/KeyHolders/keyHolder2" |
38 | key: "e" | ||
37 | } | 39 | } |
38 | keyholders { | 40 | keyholders { |
39 | name: "3" | 41 | name: "3" |
40 | path: "Components/KeyHolders/keyHolder3" | 42 | path: "Components/KeyHolders/keyHolder3" |
43 | key: "r" | ||
41 | } | 44 | } |
42 | keyholders { | 45 | keyholders { |
43 | name: "4" | 46 | name: "4" |
44 | path: "Components/KeyHolders/keyHolder4" | 47 | path: "Components/KeyHolders/keyHolder4" |
48 | key: "o" | ||
45 | } | 49 | } |
46 | ports { | 50 | ports { |
47 | name: "RIGHT" | 51 | name: "RIGHT" |
52 | display_name: "Hinterlands South Entrance" | ||
48 | path: "Components/Warps/worldport6" | 53 | path: "Components/Warps/worldport6" |
54 | destination { x: 82 y: 0 z: -10 } | ||
55 | rotation: 90 | ||
49 | } | 56 | } |
50 | ports { | 57 | ports { |
51 | name: "LEFT" | 58 | name: "LEFT" |
59 | display_name: "Hinterlands North Entrance" | ||
52 | path: "Components/Warps/worldport7" | 60 | path: "Components/Warps/worldport7" |
53 | # Check that this is correct. | 61 | destination { x: 82 y: 0 z: -48 } |
62 | rotation: 90 | ||
54 | } | 63 | } |
55 | ports { | 64 | ports { |
56 | name: "RELENTLESS_LEFT" | 65 | name: "RELENTLESS_LEFT" |
66 | display_name: "Relentless LEFT Entrance" | ||
57 | path: "Components/Warps/worldport9" | 67 | path: "Components/Warps/worldport9" |
68 | no_shuffle: true | ||
58 | } | 69 | } |
59 | ports { | 70 | ports { |
60 | name: "RELENTLESS_SHOP" | 71 | name: "RELENTLESS_SHOP" |
72 | display_name: "Relentless SHOP Entrance" | ||
61 | path: "Components/Warps/worldport11" | 73 | path: "Components/Warps/worldport11" |
74 | no_shuffle: true | ||
62 | } | 75 | } |
63 | ports { | 76 | ports { |
64 | name: "RELENTLESS_TURN" | 77 | name: "RELENTLESS_TURN" |
78 | display_name: "Relentless TURN Entrance" | ||
65 | path: "Components/Warps/worldport10" | 79 | path: "Components/Warps/worldport10" |
80 | no_shuffle: true | ||
66 | } | 81 | } |
diff --git a/data/maps/control_center/rooms/Partial Entrance.txtpb b/data/maps/control_center/rooms/Partial Entrance.txtpb index 77b68fa..5771afc 100644 --- a/data/maps/control_center/rooms/Partial Entrance.txtpb +++ b/data/maps/control_center/rooms/Partial Entrance.txtpb | |||
@@ -8,5 +8,10 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "PARTIAL" | 10 | name: "PARTIAL" |
11 | display_name: "Partial Connector" | ||
11 | path: "Components/Warps/worldport4" | 12 | path: "Components/Warps/worldport4" |
13 | destination { x: 21 y: 0 z: -41 } | ||
14 | rotation: 270 | ||
15 | # TODO: shuffle entrances with dependent keyholders | ||
16 | no_shuffle: true | ||
12 | } | 17 | } |
diff --git a/data/maps/control_center/rooms/Perceptive Entrance.txtpb b/data/maps/control_center/rooms/Perceptive Entrance.txtpb index 6eec265..cf5a82c 100644 --- a/data/maps/control_center/rooms/Perceptive Entrance.txtpb +++ b/data/maps/control_center/rooms/Perceptive Entrance.txtpb | |||
@@ -16,5 +16,10 @@ panels { | |||
16 | } | 16 | } |
17 | ports { | 17 | ports { |
18 | name: "PERCEPTIVE" | 18 | name: "PERCEPTIVE" |
19 | display_name: "Perceptive Entrance" | ||
19 | path: "Components/Warps/worldport12" | 20 | path: "Components/Warps/worldport12" |
21 | destination { x: -23 y: 0 z: -11 } | ||
22 | rotation: 0 | ||
23 | # TODO: shuffle entrances with dependent keyholders | ||
24 | no_shuffle: true | ||
20 | } | 25 | } |
diff --git a/data/maps/control_center/rooms/Repetitive Entrance.txtpb b/data/maps/control_center/rooms/Repetitive Entrance.txtpb index 08b8fa4..6e242f3 100644 --- a/data/maps/control_center/rooms/Repetitive Entrance.txtpb +++ b/data/maps/control_center/rooms/Repetitive Entrance.txtpb | |||
@@ -1,5 +1,10 @@ | |||
1 | name: "Repetitive Entrance" | 1 | name: "Repetitive Entrance" |
2 | ports { | 2 | ports { |
3 | name: "REPETITIVE" | 3 | name: "REPETITIVE" |
4 | display_name: "Repetitive Entrance" | ||
4 | path: "Components/Warps/worldport14" | 5 | path: "Components/Warps/worldport14" |
6 | destination { x: -16 y: 0 z: -17.5 } | ||
7 | rotation: 0 | ||
8 | # TODO: shuffle entrances with dependent keyholders | ||
9 | no_shuffle: true | ||
5 | } | 10 | } |
diff --git a/data/maps/control_center/rooms/Tenacious Entrance.txtpb b/data/maps/control_center/rooms/Tenacious Entrance.txtpb index 0527d50..2689589 100644 --- a/data/maps/control_center/rooms/Tenacious Entrance.txtpb +++ b/data/maps/control_center/rooms/Tenacious Entrance.txtpb | |||
@@ -8,5 +8,10 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "TENACIOUS" | 10 | name: "TENACIOUS" |
11 | display_name: "Tenacious Connector" | ||
11 | path: "Components/Warps/worldport13" | 12 | path: "Components/Warps/worldport13" |
13 | destination { x: 56 y: 0 z: -38 } | ||
14 | rotation: 180 | ||
15 | # TODO: shuffle entrances with dependent keyholders | ||
16 | no_shuffle: true | ||
12 | } | 17 | } |
diff --git a/data/maps/control_center/rooms/Unkempt Entrance.txtpb b/data/maps/control_center/rooms/Unkempt Entrance.txtpb index b6fc074..5e65254 100644 --- a/data/maps/control_center/rooms/Unkempt Entrance.txtpb +++ b/data/maps/control_center/rooms/Unkempt Entrance.txtpb | |||
@@ -8,5 +8,10 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "UNKEMPT" | 10 | name: "UNKEMPT" |
11 | display_name: "Unkempt Connector" | ||
11 | path: "Components/Warps/worldport3" | 12 | path: "Components/Warps/worldport3" |
13 | destination { x: 34 y: 0 z: -38.5 } | ||
14 | rotation: 90 | ||
15 | # TODO: shuffle entrances with dependent keyholders | ||
16 | no_shuffle: true | ||
12 | } | 17 | } |
diff --git a/data/maps/daedalus/connections.txtpb b/data/maps/daedalus/connections.txtpb index fc0af60..cb27c38 100644 --- a/data/maps/daedalus/connections.txtpb +++ b/data/maps/daedalus/connections.txtpb | |||
@@ -100,6 +100,11 @@ connections { | |||
100 | oneway: true | 100 | oneway: true |
101 | } | 101 | } |
102 | connections { | 102 | connections { |
103 | from_room: "Outside House" | ||
104 | to_room: "Blue Hallway Tall Side" | ||
105 | door { name: "House Side Door" } | ||
106 | } | ||
107 | connections { | ||
103 | from_room: "Purple SE Vestibule" | 108 | from_room: "Purple SE Vestibule" |
104 | to_room: "Welcome Back Area" | 109 | to_room: "Welcome Back Area" |
105 | oneway: true | 110 | oneway: true |
@@ -200,11 +205,16 @@ connections { | |||
200 | door { name: "Temple of the Eyes Entrance" } | 205 | door { name: "Temple of the Eyes Entrance" } |
201 | } | 206 | } |
202 | connections { | 207 | connections { |
203 | from_room: "Outside Eye Temple" | 208 | from_room: "Eye Painting" |
204 | to_room: "Starting Room" | 209 | to_room: "Starting Room" |
205 | door { name: "Starting Room South Wall West Door" } | 210 | door { name: "Starting Room South Wall West Door" } |
206 | } | 211 | } |
207 | connections { | 212 | connections { |
213 | from_room: "Eye Painting" | ||
214 | to_room: "Outside Eye Temple" | ||
215 | door { name: "Eye Painting Exit" } | ||
216 | } | ||
217 | connections { | ||
208 | from_room: "Outside Pyramid" | 218 | from_room: "Outside Pyramid" |
209 | to_room: "Number Paintings Area" | 219 | to_room: "Number Paintings Area" |
210 | door { name: "Near Pyramid Gate" } | 220 | door { name: "Near Pyramid Gate" } |
@@ -217,12 +227,12 @@ connections { | |||
217 | connections { | 227 | connections { |
218 | from_room: "West Castle Area" | 228 | from_room: "West Castle Area" |
219 | to_room: "Post Orange Smiley Three Way" | 229 | to_room: "Post Orange Smiley Three Way" |
220 | door { name: "Splintering Exit Left Door" } | 230 | door { name: "Splintering Exit North Door" } |
221 | } | 231 | } |
222 | connections { | 232 | connections { |
223 | from_room: "West Castle Area" | 233 | from_room: "West Castle Area" |
224 | to_room: "Amber North 2" | 234 | to_room: "Amber North 2" |
225 | door { name: "Splintering Exit Right Door" } | 235 | door { name: "Splintering Exit South Door" } |
226 | } | 236 | } |
227 | connections { | 237 | connections { |
228 | from_room: "Z2 Room" | 238 | from_room: "Z2 Room" |
@@ -373,7 +383,7 @@ connections { | |||
373 | connections { | 383 | connections { |
374 | from_room: "O2 Room" | 384 | from_room: "O2 Room" |
375 | to_room: "Blue Smiley" | 385 | to_room: "Blue Smiley" |
376 | door { name: "Blue Smiley Entrance" } | 386 | door { name: "O2 Room Southeast Door" } |
377 | } | 387 | } |
378 | connections { | 388 | connections { |
379 | from_room: "O2 Room" | 389 | from_room: "O2 Room" |
@@ -403,7 +413,7 @@ connections { | |||
403 | connections { | 413 | connections { |
404 | from_room: "O2 Room" | 414 | from_room: "O2 Room" |
405 | to_room: "Blue Hallway" | 415 | to_room: "Blue Hallway" |
406 | door { name: "O2 Room Back Door" } | 416 | door { name: "O2 Room Northeast Door" } |
407 | } | 417 | } |
408 | connections { | 418 | connections { |
409 | from_room: "O2 Room" | 419 | from_room: "O2 Room" |
@@ -418,7 +428,7 @@ connections { | |||
418 | connections { | 428 | connections { |
419 | from_room: "Sweet Foyer" | 429 | from_room: "Sweet Foyer" |
420 | to_room: "F2 Room" | 430 | to_room: "F2 Room" |
421 | door { name: "F2 Room Entrance" } | 431 | door { name: "F2 Room Southeast Door" } |
422 | } | 432 | } |
423 | connections { | 433 | connections { |
424 | from_room: "Globe Room" | 434 | from_room: "Globe Room" |
@@ -433,17 +443,17 @@ connections { | |||
433 | connections { | 443 | connections { |
434 | from_room: "F2 Room" | 444 | from_room: "F2 Room" |
435 | to_room: "Blue Hallway" | 445 | to_room: "Blue Hallway" |
436 | door { name: "F2 Room Back Right Door" } | 446 | door { name: "F2 Room Southwest Door" } |
437 | } | 447 | } |
438 | connections { | 448 | connections { |
439 | from_room: "F2 Room" | 449 | from_room: "F2 Room" |
440 | to_room: "Outside Salt Room" | 450 | to_room: "Outside Salt Room" |
441 | door { name: "F2 Room Back Left Door" } | 451 | door { name: "F2 Room Northwest Door" } |
442 | } | 452 | } |
443 | connections { | 453 | connections { |
444 | from_room: "F2 Room" | 454 | from_room: "F2 Room" |
445 | to_room: "Red Color Door" | 455 | to_room: "Red Color Door" |
446 | door { name: "F2 Room Back Middle Door" } | 456 | door { name: "F2 Room West Door" } |
447 | oneway: true | 457 | oneway: true |
448 | # This is the red backside, which has nothing in it. Maybe could be its own | 458 | # This is the red backside, which has nothing in it. Maybe could be its own |
449 | # region at some point. | 459 | # region at some point. |
@@ -456,7 +466,7 @@ connections { | |||
456 | connections { | 466 | connections { |
457 | from_room: "U2 Room" | 467 | from_room: "U2 Room" |
458 | to_room: "Maze Paintings Area" | 468 | to_room: "Maze Paintings Area" |
459 | door { name: "U2 Room Shortcut" } | 469 | door { name: "U2 Room Southeast Door" } |
460 | } | 470 | } |
461 | connections { | 471 | connections { |
462 | from_room: "Maze Paintings Area" | 472 | from_room: "Maze Paintings Area" |
@@ -471,17 +481,17 @@ connections { | |||
471 | connections { | 481 | connections { |
472 | from_room: "U2 Room" | 482 | from_room: "U2 Room" |
473 | to_room: "Purple SE Vestibule" | 483 | to_room: "Purple SE Vestibule" |
474 | door { name: "U2 Room Back Right Door" } | 484 | door { name: "U2 Room Southwest Door" } |
475 | } | 485 | } |
476 | connections { | 486 | connections { |
477 | from_room: "U2 Room" | 487 | from_room: "U2 Room" |
478 | to_room: "Purple Room East" | 488 | to_room: "Purple Room East" |
479 | door { name: "U2 Room Back Door" } | 489 | door { name: "U2 Room West Door" } |
480 | } | 490 | } |
481 | connections { | 491 | connections { |
482 | from_room: "Maze" | 492 | from_room: "Maze" |
483 | to_room: "U2 Room" | 493 | to_room: "U2 Room" |
484 | door { name: "U2 Room Entrance" } | 494 | door { name: "U2 Room East Door" } |
485 | } | 495 | } |
486 | connections { | 496 | connections { |
487 | from_room: "Outside Magic Room" | 497 | from_room: "Outside Magic Room" |
@@ -506,7 +516,7 @@ connections { | |||
506 | connections { | 516 | connections { |
507 | from_room: "Wonderland" | 517 | from_room: "Wonderland" |
508 | to_room: "Black Hex" | 518 | to_room: "Black Hex" |
509 | door { name: "Wonderland Right Door" } | 519 | door { name: "Wonderland South Door" } |
510 | } | 520 | } |
511 | connections { | 521 | connections { |
512 | from_room: "Outside Pyramid" | 522 | from_room: "Outside Pyramid" |
@@ -530,6 +540,11 @@ connections { | |||
530 | } | 540 | } |
531 | connections { | 541 | connections { |
532 | from_room: "Z2 Room" | 542 | from_room: "Z2 Room" |
543 | to_room: "Orange Room Hallway" | ||
544 | door { name: "Z2 Room Southeast Door" } | ||
545 | } | ||
546 | connections { | ||
547 | from_room: "Orange Room Hallway" | ||
533 | to_room: "Orange Room" | 548 | to_room: "Orange Room" |
534 | door { name: "Z2 Room Southeast Door" } | 549 | door { name: "Z2 Room Southeast Door" } |
535 | } | 550 | } |
@@ -591,7 +606,7 @@ connections { | |||
591 | connections { | 606 | connections { |
592 | from_room: "Wonderland" | 607 | from_room: "Wonderland" |
593 | to_room: "Number Paintings Area" | 608 | to_room: "Number Paintings Area" |
594 | door { name: "Wonderland Left Door" } | 609 | door { name: "Wonderland North Door" } |
595 | } | 610 | } |
596 | connections { | 611 | connections { |
597 | from_room: "Outside House" | 612 | from_room: "Outside House" |
@@ -1540,3 +1555,322 @@ connections { | |||
1540 | to_room: "Pyramid Top" | 1555 | to_room: "Pyramid Top" |
1541 | door { name: "Pyramid Third Floor Door" } | 1556 | door { name: "Pyramid Third Floor Door" } |
1542 | } | 1557 | } |
1558 | connections { | ||
1559 | from_room: "Roof" | ||
1560 | to_room: "After Bee Room" | ||
1561 | oneway: true | ||
1562 | roof_access: true | ||
1563 | } | ||
1564 | connections { | ||
1565 | from_room: "Roof" | ||
1566 | to_room: "Amber North 2" | ||
1567 | oneway: true | ||
1568 | roof_access: true | ||
1569 | } | ||
1570 | connections { | ||
1571 | from_room: "Roof" | ||
1572 | to_room: "Black Hex" | ||
1573 | oneway: true | ||
1574 | roof_access: true | ||
1575 | } | ||
1576 | connections { | ||
1577 | from_room: "Roof" | ||
1578 | to_room: "Blue Hallway Tall Side" | ||
1579 | oneway: true | ||
1580 | roof_access: true | ||
1581 | } | ||
1582 | connections { | ||
1583 | from_room: "Roof" | ||
1584 | to_room: "Blue Hallway" | ||
1585 | oneway: true | ||
1586 | roof_access: true | ||
1587 | } | ||
1588 | # Blue Hallway Cut Side is inside. | ||
1589 | connections { | ||
1590 | from_room: "Roof" | ||
1591 | to_room: "Eye Painting" | ||
1592 | oneway: true | ||
1593 | roof_access: true | ||
1594 | } | ||
1595 | connections { | ||
1596 | from_room: "Roof" | ||
1597 | to_room: "Globe Room" | ||
1598 | oneway: true | ||
1599 | roof_access: true | ||
1600 | } | ||
1601 | connections { | ||
1602 | from_room: "Roof" | ||
1603 | to_room: "Gray Color Door" | ||
1604 | oneway: true | ||
1605 | roof_access: true | ||
1606 | } | ||
1607 | connections { | ||
1608 | from_room: "Roof" | ||
1609 | to_room: "Green Color Door" | ||
1610 | oneway: true | ||
1611 | roof_access: true | ||
1612 | } | ||
1613 | connections { | ||
1614 | from_room: "Roof" | ||
1615 | to_room: "Green Smiley" | ||
1616 | oneway: true | ||
1617 | roof_access: true | ||
1618 | } | ||
1619 | connections { | ||
1620 | from_room: "Roof" | ||
1621 | to_room: "Hedges" | ||
1622 | oneway: true | ||
1623 | roof_access: true | ||
1624 | } | ||
1625 | connections { | ||
1626 | from_room: "Roof" | ||
1627 | to_room: "Maze Paintings Area" | ||
1628 | oneway: true | ||
1629 | roof_access: true | ||
1630 | } | ||
1631 | connections { | ||
1632 | from_room: "Roof" | ||
1633 | to_room: "Maze" | ||
1634 | oneway: true | ||
1635 | roof_access: true | ||
1636 | } | ||
1637 | connections { | ||
1638 | from_room: "Roof" | ||
1639 | to_room: "North Castle Area" | ||
1640 | oneway: true | ||
1641 | roof_access: true | ||
1642 | } | ||
1643 | connections { | ||
1644 | from_room: "Roof" | ||
1645 | to_room: "Number Paintings Area" | ||
1646 | oneway: true | ||
1647 | roof_access: true | ||
1648 | } | ||
1649 | connections { | ||
1650 | from_room: "Roof" | ||
1651 | to_room: "Orange Room Hallway" | ||
1652 | oneway: true | ||
1653 | roof_access: true | ||
1654 | } | ||
1655 | connections { | ||
1656 | from_room: "Roof" | ||
1657 | to_room: "Outside Book Room" | ||
1658 | oneway: true | ||
1659 | roof_access: true | ||
1660 | } | ||
1661 | connections { | ||
1662 | from_room: "Roof" | ||
1663 | to_room: "Outside Eye Temple" | ||
1664 | oneway: true | ||
1665 | roof_access: true | ||
1666 | } | ||
1667 | connections { | ||
1668 | from_room: "Roof" | ||
1669 | to_room: "Outside Hedges" | ||
1670 | oneway: true | ||
1671 | roof_access: true | ||
1672 | } | ||
1673 | connections { | ||
1674 | from_room: "Roof" | ||
1675 | to_room: "Outside Hotel" | ||
1676 | oneway: true | ||
1677 | roof_access: true | ||
1678 | } | ||
1679 | connections { | ||
1680 | from_room: "Roof" | ||
1681 | to_room: "Outside House" | ||
1682 | oneway: true | ||
1683 | roof_access: true | ||
1684 | } | ||
1685 | connections { | ||
1686 | from_room: "Roof" | ||
1687 | to_room: "Outside Magic Room" | ||
1688 | oneway: true | ||
1689 | roof_access: true | ||
1690 | } | ||
1691 | connections { | ||
1692 | from_room: "Roof" | ||
1693 | to_room: "Outside Orange Room" | ||
1694 | oneway: true | ||
1695 | roof_access: true | ||
1696 | } | ||
1697 | connections { | ||
1698 | from_room: "Roof" | ||
1699 | to_room: "Outside Pyramid" | ||
1700 | oneway: true | ||
1701 | roof_access: true | ||
1702 | } | ||
1703 | connections { | ||
1704 | from_room: "Roof" | ||
1705 | to_room: "Outside Red Room" | ||
1706 | oneway: true | ||
1707 | roof_access: true | ||
1708 | } | ||
1709 | connections { | ||
1710 | from_room: "Roof" | ||
1711 | to_room: "Outside Salt Room" | ||
1712 | oneway: true | ||
1713 | roof_access: true | ||
1714 | } | ||
1715 | connections { | ||
1716 | from_room: "Roof" | ||
1717 | to_room: "Outside Snake Room" | ||
1718 | oneway: true | ||
1719 | roof_access: true | ||
1720 | } | ||
1721 | connections { | ||
1722 | from_room: "Roof" | ||
1723 | to_room: "Post Orange Smiley Three Way" | ||
1724 | oneway: true | ||
1725 | roof_access: true | ||
1726 | } | ||
1727 | connections { | ||
1728 | from_room: "Roof" | ||
1729 | to_room: "Purple NW Vestibule" | ||
1730 | oneway: true | ||
1731 | roof_access: true | ||
1732 | } | ||
1733 | connections { | ||
1734 | from_room: "Roof" | ||
1735 | to_room: "Purple Room East" | ||
1736 | oneway: true | ||
1737 | roof_access: true | ||
1738 | } | ||
1739 | connections { | ||
1740 | from_room: "Roof" | ||
1741 | to_room: "Purple Room South" | ||
1742 | oneway: true | ||
1743 | roof_access: true | ||
1744 | } | ||
1745 | connections { | ||
1746 | from_room: "Roof" | ||
1747 | to_room: "Purple Room West" | ||
1748 | oneway: true | ||
1749 | roof_access: true | ||
1750 | } | ||
1751 | connections { | ||
1752 | from_room: "Roof" | ||
1753 | to_room: "Purple SE Vestibule" | ||
1754 | oneway: true | ||
1755 | roof_access: true | ||
1756 | } | ||
1757 | connections { | ||
1758 | from_room: "Roof" | ||
1759 | to_room: "Pyramid Second Floor" | ||
1760 | oneway: true | ||
1761 | roof_access: true | ||
1762 | } | ||
1763 | connections { | ||
1764 | from_room: "Roof" | ||
1765 | to_room: "Pyramid Top" | ||
1766 | oneway: true | ||
1767 | roof_access: true | ||
1768 | } | ||
1769 | connections { | ||
1770 | from_room: "Roof" | ||
1771 | to_room: "Quiet Entrance" | ||
1772 | oneway: true | ||
1773 | roof_access: true | ||
1774 | } | ||
1775 | connections { | ||
1776 | from_room: "Roof" | ||
1777 | to_room: "Red Color Door" | ||
1778 | oneway: true | ||
1779 | roof_access: true | ||
1780 | } | ||
1781 | connections { | ||
1782 | from_room: "Roof" | ||
1783 | to_room: "South Castle Area" | ||
1784 | oneway: true | ||
1785 | roof_access: true | ||
1786 | } | ||
1787 | connections { | ||
1788 | from_room: "Roof" | ||
1789 | to_room: "Starting Room" | ||
1790 | oneway: true | ||
1791 | roof_access: true | ||
1792 | } | ||
1793 | connections { | ||
1794 | from_room: "Roof" | ||
1795 | to_room: "Sweet Foyer" | ||
1796 | oneway: true | ||
1797 | roof_access: true | ||
1798 | } | ||
1799 | connections { | ||
1800 | from_room: "Roof" | ||
1801 | to_room: "Tree Entrance" | ||
1802 | oneway: true | ||
1803 | roof_access: true | ||
1804 | } | ||
1805 | connections { | ||
1806 | from_room: "Roof" | ||
1807 | to_room: "West Castle Area" | ||
1808 | oneway: true | ||
1809 | roof_access: true | ||
1810 | } | ||
1811 | connections { | ||
1812 | from_room: "Roof" | ||
1813 | to_room: "West Spire" | ||
1814 | oneway: true | ||
1815 | roof_access: true | ||
1816 | } | ||
1817 | connections { | ||
1818 | from_room: "Roof" | ||
1819 | to_room: "Yellow Color Door" | ||
1820 | oneway: true | ||
1821 | roof_access: true | ||
1822 | } | ||
1823 | connections { | ||
1824 | from_room: "Roof" | ||
1825 | to_room: "Z2 Room" | ||
1826 | oneway: true | ||
1827 | roof_access: true | ||
1828 | } | ||
1829 | connections { | ||
1830 | from_room: "Roof" | ||
1831 | to_room: "Zoo Center" | ||
1832 | oneway: true | ||
1833 | roof_access: true | ||
1834 | } | ||
1835 | connections { | ||
1836 | from_room: "Roof" | ||
1837 | to_room: "Zoo E" | ||
1838 | oneway: true | ||
1839 | roof_access: true | ||
1840 | } | ||
1841 | connections { | ||
1842 | from_room: "Roof" | ||
1843 | to_room: "Zoo N" | ||
1844 | oneway: true | ||
1845 | roof_access: true | ||
1846 | } | ||
1847 | connections { | ||
1848 | from_room: "Roof" | ||
1849 | to_room: "Zoo NE" | ||
1850 | oneway: true | ||
1851 | roof_access: true | ||
1852 | } | ||
1853 | connections { | ||
1854 | from_room: "Roof" | ||
1855 | to_room: "Zoo S" | ||
1856 | oneway: true | ||
1857 | roof_access: true | ||
1858 | } | ||
1859 | connections { | ||
1860 | from_room: "Roof" | ||
1861 | to_room: "Zoo SE" | ||
1862 | oneway: true | ||
1863 | roof_access: true | ||
1864 | } | ||
1865 | connections { | ||
1866 | from_room: "Roof" | ||
1867 | to_room: "F Keyholder" | ||
1868 | oneway: true | ||
1869 | roof_access: true | ||
1870 | } | ||
1871 | connections { | ||
1872 | from_room: "Roof" | ||
1873 | to_room: "Yellow Color Backside" | ||
1874 | oneway: true | ||
1875 | roof_access: true | ||
1876 | } | ||
diff --git a/data/maps/daedalus/doors.txtpb b/data/maps/daedalus/doors.txtpb index 1ae6cc6..b6881b3 100644 --- a/data/maps/daedalus/doors.txtpb +++ b/data/maps/daedalus/doors.txtpb | |||
@@ -188,18 +188,18 @@ doors { | |||
188 | } | 188 | } |
189 | doors { | 189 | doors { |
190 | name: "Welcome Back Secret Door" | 190 | name: "Welcome Back Secret Door" |
191 | type: STANDARD | 191 | type: ITEM_ONLY |
192 | receivers: "Components/Doors/Entry/entry_13" | 192 | receivers: "Components/Doors/Entry/entry_13" |
193 | panels { room: "Welcome Back Area" name: "FAREWELL LITTLE LAMB" } | 193 | panels { room: "Welcome Back Area" name: "FAREWELL LITTLE LAMB" } |
194 | panels { room: "West Spire" name: "BYE" } | 194 | panels { room: "West Spire" name: "BYE" } |
195 | location_room: "West Spire" | ||
196 | } | 195 | } |
197 | doors { | 196 | doors { |
198 | name: "Welcome Back Door" | 197 | name: "Welcome Back Door" |
199 | type: STANDARD | 198 | type: LOCATION_ONLY |
200 | receivers: "Components/Doors/Entry/entry_14" | 199 | #receivers: "Components/Doors/Entry/entry_14" |
201 | panels { room: "Welcome Back Area" name: "GREETINGS OLD FRIEND" } | 200 | panels { room: "Welcome Back Area" name: "GREETINGS OLD FRIEND" } |
202 | location_room: "Welcome Back Area" | 201 | location_room: "Welcome Back Area" |
202 | location_name: "GREETINGS OLD FRIEND" | ||
203 | } | 203 | } |
204 | # entry_3 is the door to SEAL, which we will ignore. | 204 | # entry_3 is the door to SEAL, which we will ignore. |
205 | doors { | 205 | doors { |
@@ -296,9 +296,10 @@ doors { | |||
296 | panels { room: "Black Hex" name: "CLUES" } | 296 | panels { room: "Black Hex" name: "CLUES" } |
297 | panels { room: "Black Hex" name: "SECRET" } | 297 | panels { room: "Black Hex" name: "SECRET" } |
298 | location_room: "Black Hex" | 298 | location_room: "Black Hex" |
299 | location_name: "Black Hex" | ||
299 | } | 300 | } |
300 | doors { | 301 | doors { |
301 | name: "Splintering Exit Left Door" | 302 | name: "Splintering Exit North Door" |
302 | type: STANDARD | 303 | type: STANDARD |
303 | receivers: "Components/Doors/Entry/gate_4" | 304 | receivers: "Components/Doors/Entry/gate_4" |
304 | panels { room: "West Castle Area" name: "EVER" } | 305 | panels { room: "West Castle Area" name: "EVER" } |
@@ -308,7 +309,7 @@ doors { | |||
308 | location_room: "West Castle Area" | 309 | location_room: "West Castle Area" |
309 | } | 310 | } |
310 | doors { | 311 | doors { |
311 | name: "Splintering Exit Right Door" | 312 | name: "Splintering Exit South Door" |
312 | type: ITEM_ONLY | 313 | type: ITEM_ONLY |
313 | receivers: "Components/Doors/Entry/gate_5" | 314 | receivers: "Components/Doors/Entry/gate_5" |
314 | panels { room: "West Castle Area" name: "EVER" } | 315 | panels { room: "West Castle Area" name: "EVER" } |
@@ -382,6 +383,7 @@ doors { | |||
382 | panels { room: "Z2 Room" name: "CAPE" } | 383 | panels { room: "Z2 Room" name: "CAPE" } |
383 | panels { room: "Z2 Room" name: "GLANCE" } | 384 | panels { room: "Z2 Room" name: "GLANCE" } |
384 | location_room: "Z2 Room" | 385 | location_room: "Z2 Room" |
386 | location_name: "West Puzzles" | ||
385 | } | 387 | } |
386 | doors { | 388 | doors { |
387 | name: "Z2 Room Northwest Door" | 389 | name: "Z2 Room Northwest Door" |
@@ -413,6 +415,7 @@ doors { | |||
413 | panels { room: "Z2 Room" name: "DISCORD" } | 415 | panels { room: "Z2 Room" name: "DISCORD" } |
414 | panels { room: "Z2 Room" name: "CAT" } | 416 | panels { room: "Z2 Room" name: "CAT" } |
415 | location_room: "Z2 Room" | 417 | location_room: "Z2 Room" |
418 | location_name: "East Puzzles" | ||
416 | } | 419 | } |
417 | doors { | 420 | doors { |
418 | name: "Z2 Room Southeast Door" | 421 | name: "Z2 Room Southeast Door" |
@@ -517,6 +520,7 @@ doors { | |||
517 | panels { room: "Outside House" name: "BLITHELY" } | 520 | panels { room: "Outside House" name: "BLITHELY" } |
518 | panels { room: "Purple Room South" name: "THESE" } | 521 | panels { room: "Purple Room South" name: "THESE" } |
519 | location_room: "Outside House" | 522 | location_room: "Outside House" |
523 | location_name: "West Purple Vestibules" | ||
520 | } | 524 | } |
521 | doors { | 525 | doors { |
522 | name: "Purple West Area South Door" | 526 | name: "Purple West Area South Door" |
@@ -545,6 +549,7 @@ doors { | |||
545 | panels { room: "Godot Room" name: "TRAIN" } | 549 | panels { room: "Godot Room" name: "TRAIN" } |
546 | panels { room: "Godot Room" name: "RECORDING" } | 550 | panels { room: "Godot Room" name: "RECORDING" } |
547 | location_room: "Godot Room" | 551 | location_room: "Godot Room" |
552 | location_name: "Godot Room" | ||
548 | } | 553 | } |
549 | doors { | 554 | doors { |
550 | name: "Beehalls Intersection" | 555 | name: "Beehalls Intersection" |
@@ -576,6 +581,7 @@ doors { | |||
576 | panels { room: "Purple Room South" name: "ANY" } | 581 | panels { room: "Purple Room South" name: "ANY" } |
577 | panels { room: "Outside House" name: "A" } | 582 | panels { room: "Outside House" name: "A" } |
578 | location_room: "Outside House" | 583 | location_room: "Outside House" |
584 | location_name: "East Purple Vestibules" | ||
579 | } | 585 | } |
580 | doors { | 586 | doors { |
581 | name: "Purple East Area North Door" | 587 | name: "Purple East Area North Door" |
@@ -593,6 +599,7 @@ doors { | |||
593 | panels { room: "Outside House" name: "BLITHELY" } | 599 | panels { room: "Outside House" name: "BLITHELY" } |
594 | panels { room: "Purple Room South" name: "THESE" } | 600 | panels { room: "Purple Room South" name: "THESE" } |
595 | location_room: "Outside House" | 601 | location_room: "Outside House" |
602 | location_name: "Purple Vestibules" | ||
596 | } | 603 | } |
597 | doors { | 604 | doors { |
598 | name: "Purple Room South Entrance" | 605 | name: "Purple Room South Entrance" |
@@ -622,6 +629,20 @@ doors { | |||
622 | panels { room: "Purple Room South" name: "THESE" } | 629 | panels { room: "Purple Room South" name: "THESE" } |
623 | } | 630 | } |
624 | doors { | 631 | doors { |
632 | name: "Purple Room" | ||
633 | type: LOCATION_ONLY | ||
634 | panels { room: "Purple Room" name: "HOIST" } | ||
635 | panels { room: "Purple Room" name: "CORE" } | ||
636 | panels { room: "Purple Room" name: "FISH" } | ||
637 | panels { room: "Purple Room" name: "ALLOW" } | ||
638 | panels { room: "Purple Room" name: "BIRD" } | ||
639 | panels { room: "Purple Room" name: "HONK" } | ||
640 | panels { room: "Purple Room" name: "APE" } | ||
641 | panels { room: "Purple Room" name: "APATHY" } | ||
642 | location_room: "Purple Room" | ||
643 | location_name: "Puzzles" | ||
644 | } | ||
645 | doors { | ||
625 | name: "Hedges Tower" | 646 | name: "Hedges Tower" |
626 | type: LOCATION_ONLY | 647 | type: LOCATION_ONLY |
627 | # TODO: Not making this an item right now in order to force the player to | 648 | # TODO: Not making this an item right now in order to force the player to |
@@ -676,6 +697,7 @@ doors { | |||
676 | panels { room: "Blue Room" name: "CELEBRATORY" } | 697 | panels { room: "Blue Room" name: "CELEBRATORY" } |
677 | panels { room: "Blue Room" name: "DETECTIVE" } | 698 | panels { room: "Blue Room" name: "DETECTIVE" } |
678 | location_room: "Blue Room" | 699 | location_room: "Blue Room" |
700 | location_name: "Puzzles" | ||
679 | } | 701 | } |
680 | doors { | 702 | doors { |
681 | name: "O2 Prize" | 703 | name: "O2 Prize" |
@@ -694,7 +716,7 @@ doors { | |||
694 | panels { room: "O2 Room" name: "UNBLOCKED" } | 716 | panels { room: "O2 Room" name: "UNBLOCKED" } |
695 | } | 717 | } |
696 | doors { | 718 | doors { |
697 | name: "Blue Smiley Entrance" | 719 | name: "O2 Room Southeast Door" |
698 | type: STANDARD | 720 | type: STANDARD |
699 | receivers: "Components/Doors/Halls/oroom_2" | 721 | receivers: "Components/Doors/Halls/oroom_2" |
700 | panels { room: "O2 Room" name: "HONEST" } | 722 | panels { room: "O2 Room" name: "HONEST" } |
@@ -734,6 +756,7 @@ doors { | |||
734 | panels { room: "Composite Room S" name: "BLEAKCARD" } | 756 | panels { room: "Composite Room S" name: "BLEAKCARD" } |
735 | panels { room: "Composite Room S" name: "MISSIONMISSION" } | 757 | panels { room: "Composite Room S" name: "MISSIONMISSION" } |
736 | location_room: "Composite Room S" | 758 | location_room: "Composite Room S" |
759 | location_name: "East Rooms" | ||
737 | } | 760 | } |
738 | doors { | 761 | doors { |
739 | name: "Composite Room North Door" | 762 | name: "Composite Room North Door" |
@@ -762,6 +785,7 @@ doors { | |||
762 | panels { room: "Composite Room NW" name: "OUTGARDEN" } | 785 | panels { room: "Composite Room NW" name: "OUTGARDEN" } |
763 | panels { room: "Composite Room NW" name: "HELLOTALE" } | 786 | panels { room: "Composite Room NW" name: "HELLOTALE" } |
764 | location_room: "Composite Room NE" | 787 | location_room: "Composite Room NE" |
788 | location_name: "North Rooms" | ||
765 | } | 789 | } |
766 | doors { | 790 | doors { |
767 | name: "Composite Room West Door" | 791 | name: "Composite Room West Door" |
@@ -792,12 +816,13 @@ doors { | |||
792 | panels { room: "Composite Room S" name: "OUTEAT" } | 816 | panels { room: "Composite Room S" name: "OUTEAT" } |
793 | panels { room: "Composite Room S" name: "SUMMERIN" } | 817 | panels { room: "Composite Room S" name: "SUMMERIN" } |
794 | location_room: "Composite Room NW" | 818 | location_room: "Composite Room NW" |
819 | location_name: "West Rooms" | ||
795 | } | 820 | } |
796 | doors { | 821 | doors { |
797 | name: "Composite Room NW Entrance" | 822 | name: "Composite Room NW Entrance" |
798 | type: STANDARD | 823 | type: STANDARD |
799 | receivers: "Components/Doors/Halls/oroom_10" | 824 | receivers: "Components/Doors/Halls/oroom_10" |
800 | panels { room: "Red Color Door" name: "Left" } | 825 | panels { room: "Red Color Door" name: "Near Obscured Puzzles" } |
801 | location_room: "Red Color Door" | 826 | location_room: "Red Color Door" |
802 | } | 827 | } |
803 | doors { | 828 | doors { |
@@ -829,9 +854,10 @@ doors { | |||
829 | panels { room: "Composite Room S" name: "OUTEAT" } | 854 | panels { room: "Composite Room S" name: "OUTEAT" } |
830 | panels { room: "Composite Room S" name: "SUMMERIN" } | 855 | panels { room: "Composite Room S" name: "SUMMERIN" } |
831 | location_room: "Composite Room S" | 856 | location_room: "Composite Room S" |
857 | location_name: "South Rooms" | ||
832 | } | 858 | } |
833 | doors { | 859 | doors { |
834 | name: "O2 Room Back Door" | 860 | name: "O2 Room Northeast Door" |
835 | type: STANDARD | 861 | type: STANDARD |
836 | receivers: "Components/Doors/Halls/oroom_4" | 862 | receivers: "Components/Doors/Halls/oroom_4" |
837 | panels { room: "O2 Room" name: "UNBLOCKED" } | 863 | panels { room: "O2 Room" name: "UNBLOCKED" } |
@@ -858,7 +884,7 @@ doors { | |||
858 | panels { room: "F2 Room" name: "SHAPE" } | 884 | panels { room: "F2 Room" name: "SHAPE" } |
859 | } | 885 | } |
860 | doors { | 886 | doors { |
861 | name: "F2 Room Entrance" | 887 | name: "F2 Room Southeast Door" |
862 | type: STANDARD | 888 | type: STANDARD |
863 | receivers: "Components/Doors/Halls/froom_2" | 889 | receivers: "Components/Doors/Halls/froom_2" |
864 | panels { room: "Sweet Foyer" name: "RENT (1)" } | 890 | panels { room: "Sweet Foyer" name: "RENT (1)" } |
@@ -866,36 +892,32 @@ doors { | |||
866 | } | 892 | } |
867 | doors { | 893 | doors { |
868 | name: "White Hallway From Entry" | 894 | name: "White Hallway From Entry" |
869 | # TODO: This should be combined with the corresponding door in the_entry, at | ||
870 | # least when connections are not shuffled. | ||
871 | type: CONTROL_CENTER_COLOR | 895 | type: CONTROL_CENTER_COLOR |
872 | receivers: "Components/Doors/Halls/froom_6" | 896 | receivers: "Components/Doors/Halls/froom_6" |
873 | control_center_color: "white" | 897 | control_center_color: "white" |
874 | } | 898 | } |
875 | doors { | 899 | doors { |
876 | name: "Purple Hallway From Great" | 900 | name: "Purple Hallway From Great" |
877 | # TODO: This should be combined with the corresponding door in the_great, at | ||
878 | # least when connections are not shuffled. | ||
879 | type: CONTROL_CENTER_COLOR | 901 | type: CONTROL_CENTER_COLOR |
880 | receivers: "Components/Doors/Halls/froom_7" | 902 | receivers: "Components/Doors/Halls/froom_7" |
881 | control_center_color: "purple" | 903 | control_center_color: "purple" |
882 | } | 904 | } |
883 | doors { | 905 | doors { |
884 | name: "F2 Room Back Right Door" | 906 | name: "F2 Room Southwest Door" |
885 | type: STANDARD | 907 | type: STANDARD |
886 | receivers: "Components/Doors/Halls/froom_3" | 908 | receivers: "Components/Doors/Halls/froom_3" |
887 | panels { room: "F2 Room" name: "RISKY" } | 909 | panels { room: "F2 Room" name: "RISKY" } |
888 | location_room: "F2 Room" | 910 | location_room: "F2 Room" |
889 | } | 911 | } |
890 | doors { | 912 | doors { |
891 | name: "F2 Room Back Left Door" | 913 | name: "F2 Room Northwest Door" |
892 | type: STANDARD | 914 | type: STANDARD |
893 | receivers: "Components/Doors/Halls/froom_4" | 915 | receivers: "Components/Doors/Halls/froom_4" |
894 | panels { room: "F2 Room" name: "SHAPE" } | 916 | panels { room: "F2 Room" name: "SHAPE" } |
895 | location_room: "F2 Room" | 917 | location_room: "F2 Room" |
896 | } | 918 | } |
897 | doors { | 919 | doors { |
898 | name: "F2 Room Back Middle Door" | 920 | name: "F2 Room West Door" |
899 | type: STANDARD | 921 | type: STANDARD |
900 | receivers: "Components/Doors/Halls/froom_5" | 922 | receivers: "Components/Doors/Halls/froom_5" |
901 | panels { room: "F2 Room" name: "DIRT" } | 923 | panels { room: "F2 Room" name: "DIRT" } |
@@ -916,7 +938,7 @@ doors { | |||
916 | panels { room: "U2 Room" name: "HEAVEN" } | 938 | panels { room: "U2 Room" name: "HEAVEN" } |
917 | } | 939 | } |
918 | doors { | 940 | doors { |
919 | name: "U2 Room Shortcut" | 941 | name: "U2 Room Southeast Door" |
920 | type: STANDARD | 942 | type: STANDARD |
921 | receivers: "Components/Doors/Halls/uroom_2" | 943 | receivers: "Components/Doors/Halls/uroom_2" |
922 | panels { room: "U2 Room" name: "WICKED" } | 944 | panels { room: "U2 Room" name: "WICKED" } |
@@ -937,21 +959,21 @@ doors { | |||
937 | location_room: "House Entrance" | 959 | location_room: "House Entrance" |
938 | } | 960 | } |
939 | doors { | 961 | doors { |
940 | name: "U2 Room Back Right Door" | 962 | name: "U2 Room Southwest Door" |
941 | type: STANDARD | 963 | type: STANDARD |
942 | receivers: "Components/Doors/Halls/uroom_3" | 964 | receivers: "Components/Doors/Halls/uroom_3" |
943 | panels { room: "U2 Room" name: "HEAVEN" } | 965 | panels { room: "U2 Room" name: "HEAVEN" } |
944 | location_room: "U2 Room" | 966 | location_room: "U2 Room" |
945 | } | 967 | } |
946 | doors { | 968 | doors { |
947 | name: "U2 Room Back Door" | 969 | name: "U2 Room West Door" |
948 | type: ITEM_ONLY | 970 | type: ITEM_ONLY |
949 | receivers: "Components/Doors/Halls/uroom_5" | 971 | receivers: "Components/Doors/Halls/uroom_5" |
950 | panels { room: "Purple Room South" name: "ANY" } | 972 | panels { room: "Purple Room South" name: "ANY" } |
951 | panels { room: "Outside House" name: "A" } | 973 | panels { room: "Outside House" name: "A" } |
952 | } | 974 | } |
953 | doors { | 975 | doors { |
954 | name: "U2 Room Entrance" | 976 | name: "U2 Room East Door" |
955 | type: ITEM_ONLY | 977 | type: ITEM_ONLY |
956 | receivers: "Components/Doors/Halls/uroom_4" | 978 | receivers: "Components/Doors/Halls/uroom_4" |
957 | panels { room: "Outside Magic Room" name: "WIZARD" } | 979 | panels { room: "Outside Magic Room" name: "WIZARD" } |
@@ -995,7 +1017,7 @@ doors { | |||
995 | panels { room: "Outside Magic Room" name: "WIZARD" } | 1017 | panels { room: "Outside Magic Room" name: "WIZARD" } |
996 | } | 1018 | } |
997 | doors { | 1019 | doors { |
998 | name: "Wonderland Right Door" | 1020 | name: "Wonderland South Door" |
999 | type: STANDARD | 1021 | type: STANDARD |
1000 | receivers: "Components/Doors/Halls/wonderland_1" | 1022 | receivers: "Components/Doors/Halls/wonderland_1" |
1001 | panels { room: "Wonderland" name: "APRIL" } | 1023 | panels { room: "Wonderland" name: "APRIL" } |
@@ -1004,6 +1026,7 @@ doors { | |||
1004 | panels { room: "Wonderland" name: "ARTS" } | 1026 | panels { room: "Wonderland" name: "ARTS" } |
1005 | panels { room: "Wonderland" name: "SONG" } | 1027 | panels { room: "Wonderland" name: "SONG" } |
1006 | location_room: "Wonderland" | 1028 | location_room: "Wonderland" |
1029 | location_name: "Wonderland" | ||
1007 | } | 1030 | } |
1008 | doors { | 1031 | doors { |
1009 | name: "Pyramid Entrance" | 1032 | name: "Pyramid Entrance" |
@@ -1034,6 +1057,7 @@ doors { | |||
1034 | panels { room: "Orange Room" name: "COAL" } | 1057 | panels { room: "Orange Room" name: "COAL" } |
1035 | panels { room: "Orange Room" name: "OWED" } | 1058 | panels { room: "Orange Room" name: "OWED" } |
1036 | location_room: "Orange Room" | 1059 | location_room: "Orange Room" |
1060 | location_name: "Puzzles" | ||
1037 | } | 1061 | } |
1038 | doors { | 1062 | doors { |
1039 | name: "Hedges Entrance" | 1063 | name: "Hedges Entrance" |
@@ -1052,6 +1076,7 @@ doors { | |||
1052 | panels { room: "Outside Snake Room" name: "SONG (South)" } | 1076 | panels { room: "Outside Snake Room" name: "SONG (South)" } |
1053 | panels { room: "West Castle Area" name: "SONG (2)" } | 1077 | panels { room: "West Castle Area" name: "SONG (2)" } |
1054 | location_room: "West Castle Area" | 1078 | location_room: "West Castle Area" |
1079 | location_name: "South SONGs" | ||
1055 | } | 1080 | } |
1056 | doors { | 1081 | doors { |
1057 | name: "Amber North Door" | 1082 | name: "Amber North Door" |
@@ -1060,6 +1085,7 @@ doors { | |||
1060 | panels { room: "Outside Snake Room" name: "SONG (North)" } | 1085 | panels { room: "Outside Snake Room" name: "SONG (North)" } |
1061 | panels { room: "Amber North 2" name: "SONG" } | 1086 | panels { room: "Amber North 2" name: "SONG" } |
1062 | location_room: "Amber North 2" | 1087 | location_room: "Amber North 2" |
1088 | location_name: "North SONGs" | ||
1063 | } | 1089 | } |
1064 | doors { | 1090 | doors { |
1065 | name: "Amber East Doors" | 1091 | name: "Amber East Doors" |
@@ -1182,70 +1208,37 @@ doors { | |||
1182 | type: ITEM_ONLY | 1208 | type: ITEM_ONLY |
1183 | receivers: "Components/Doors/Halls/connections_1" | 1209 | receivers: "Components/Doors/Halls/connections_1" |
1184 | receivers: "Components/Doors/Halls/connections_3" | 1210 | receivers: "Components/Doors/Halls/connections_3" |
1211 | # These have the same effect as the above, but including them here prevents | ||
1212 | # them from opening in door shuffle when the J2 door opens. | ||
1213 | receivers: "Components/Triggers/teleportListenerConnections3" | ||
1214 | receivers: "Components/Triggers/teleportListenerConnections4" | ||
1215 | # This door can open from either solving all panels, or just the smiley ones, | ||
1216 | # and the latter is obviously a subset of the former so let's just check for | ||
1217 | # that. | ||
1185 | panels { room: "Hotel" name: "PARKA" } | 1218 | panels { room: "Hotel" name: "PARKA" } |
1186 | panels { room: "Hotel" name: "MARLIN" } | ||
1187 | panels { room: "Hotel" name: "WHO" } | ||
1188 | panels { room: "Hotel" name: "CLOAK" } | 1219 | panels { room: "Hotel" name: "CLOAK" } |
1189 | panels { room: "Hotel" name: "MANE" } | ||
1190 | panels { room: "Hotel" name: "WHAT" } | ||
1191 | panels { room: "Hotel" name: "BLAZER" } | ||
1192 | panels { room: "Hotel" name: "WHERE" } | ||
1193 | panels { room: "Hotel" name: "DOROTHY" } | 1220 | panels { room: "Hotel" name: "DOROTHY" } |
1194 | panels { room: "Hotel" name: "JACKET" } | ||
1195 | panels { room: "Hotel" name: "TAIL" } | ||
1196 | panels { room: "Hotel" name: "JAWS" } | 1221 | panels { room: "Hotel" name: "JAWS" } |
1197 | panels { room: "Hotel" name: "FLOUNDER" } | ||
1198 | panels { room: "Hotel" name: "WHEN" } | 1222 | panels { room: "Hotel" name: "WHEN" } |
1199 | panels { room: "Hotel" name: "CLAWS" } | 1223 | panels { room: "Hotel" name: "CLAWS" } |
1200 | panels { room: "Hotel" name: "BRUCE" } | ||
1201 | panels { room: "Hotel" name: "POTATO" } | 1224 | panels { room: "Hotel" name: "POTATO" } |
1202 | panels { room: "Hotel" name: "SALAD" } | ||
1203 | panels { room: "Hotel" name: "BATHING" } | ||
1204 | panels { room: "Hotel" name: "MICRO" } | 1225 | panels { room: "Hotel" name: "MICRO" } |
1205 | panels { room: "Hotel" name: "BUSINESS" } | ||
1206 | panels { room: "Hotel" name: "WEDDING" } | ||
1207 | panels { room: "Hotel" name: "TREE" } | ||
1208 | panels { room: "Hotel" name: "RIVER" } | ||
1209 | panels { room: "Hotel" name: "TUNING" } | 1226 | panels { room: "Hotel" name: "TUNING" } |
1210 | panels { room: "Hotel" name: "BOXING" } | ||
1211 | panels { room: "Hotel" name: "TELEPHONE" } | ||
1212 | panels { room: "Hotel" name: "LAW" } | 1227 | panels { room: "Hotel" name: "LAW" } |
1213 | panels { room: "Hotel" name: "POKER" } | ||
1214 | panels { room: "Hotel" name: "CARD" } | 1228 | panels { room: "Hotel" name: "CARD" } |
1215 | panels { room: "Hotel" name: "ROAD" } | 1229 | panels { room: "Hotel" name: "ROAD" } |
1216 | panels { room: "Hotel" name: "CHOCOLATE" } | ||
1217 | panels { room: "Hotel" name: "DEPART" } | 1230 | panels { room: "Hotel" name: "DEPART" } |
1218 | panels { room: "Hotel" name: "WITHDRAW" } | ||
1219 | panels { room: "Hotel" name: "QUIT" } | ||
1220 | panels { room: "Hotel" name: "LEAVE" } | 1231 | panels { room: "Hotel" name: "LEAVE" } |
1221 | panels { room: "Hotel" name: "PALE" } | ||
1222 | panels { room: "Hotel" name: "JUST" } | ||
1223 | panels { room: "Hotel" name: "NEW" } | ||
1224 | panels { room: "Hotel" name: "UNTALENTED" } | ||
1225 | panels { room: "Hotel" name: "SERVICE" } | 1232 | panels { room: "Hotel" name: "SERVICE" } |
1226 | panels { room: "Hotel" name: "FULL" } | ||
1227 | panels { room: "Hotel" name: "EVIL" } | ||
1228 | panels { room: "Hotel" name: "HONEY" } | 1233 | panels { room: "Hotel" name: "HONEY" } |
1229 | panels { room: "Hotel" name: "CRESCENT" } | ||
1230 | panels { room: "Hotel" name: "INVALID" } | 1234 | panels { room: "Hotel" name: "INVALID" } |
1231 | panels { room: "Hotel" name: "FESTIVAL" } | 1235 | panels { room: "Hotel" name: "FESTIVAL" } |
1232 | panels { room: "Hotel" name: "BEAUTIFUL" } | ||
1233 | panels { room: "Hotel" name: "WILTED" } | 1236 | panels { room: "Hotel" name: "WILTED" } |
1234 | panels { room: "Hotel" name: "DROOPED" } | ||
1235 | panels { room: "Hotel" name: "FADED" } | ||
1236 | panels { room: "Hotel" name: "WANED" } | 1237 | panels { room: "Hotel" name: "WANED" } |
1237 | panels { room: "Hotel" name: "TALL" } | ||
1238 | panels { room: "Hotel" name: "CANVAS" } | ||
1239 | panels { room: "Hotel" name: "LEVER" } | ||
1240 | panels { room: "Hotel" name: "SCULPTURE" } | ||
1241 | panels { room: "Hotel" name: "RAGE" } | 1238 | panels { room: "Hotel" name: "RAGE" } |
1242 | panels { room: "Hotel" name: "BALL" } | ||
1243 | panels { room: "Hotel" name: "FOOL" } | ||
1244 | panels { room: "Hotel" name: "VERGE" } | 1239 | panels { room: "Hotel" name: "VERGE" } |
1245 | panels { room: "Hotel" name: "ART" } | ||
1246 | panels { room: "Hotel" name: "EVER" } | 1240 | panels { room: "Hotel" name: "EVER" } |
1247 | panels { room: "Hotel" name: "PAIN" } | 1241 | panels { room: "Hotel" name: "PAIN" } |
1248 | panels { room: "Hotel" name: "FOOT" } | ||
1249 | } | 1242 | } |
1250 | doors { | 1243 | doors { |
1251 | name: "J2 Door 1" | 1244 | name: "J2 Door 1" |
@@ -1281,7 +1274,7 @@ doors { | |||
1281 | panels { room: "J2 Vestibule" name: "COLORFUL" } | 1274 | panels { room: "J2 Vestibule" name: "COLORFUL" } |
1282 | } | 1275 | } |
1283 | doors { | 1276 | doors { |
1284 | name: "Wonderland Left Door" | 1277 | name: "Wonderland North Door" |
1285 | type: ITEM_ONLY | 1278 | type: ITEM_ONLY |
1286 | receivers: "Components/Doors/Halls/wonderland_2" | 1279 | receivers: "Components/Doors/Halls/wonderland_2" |
1287 | panels { room: "Wonderland" name: "APRIL" } | 1280 | panels { room: "Wonderland" name: "APRIL" } |
@@ -1389,12 +1382,32 @@ doors { | |||
1389 | } | 1382 | } |
1390 | doors { | 1383 | doors { |
1391 | name: "Roof Access" | 1384 | name: "Roof Access" |
1392 | type: STANDARD | 1385 | type: ITEM_ONLY |
1393 | receivers: "Components/Doors/Castle/entry_stairs_big" | 1386 | receivers: "Components/Doors/Castle/entry_stairs_big" |
1394 | receivers: "Components/Doors/Castle/entry_stairs_big2" | 1387 | receivers: "Components/Doors/Castle/entry_stairs_big2" |
1388 | receivers: "Meshes/Stairs/staircase31/teleportListener" | ||
1389 | receivers: "Meshes/Stairs/staircase32/teleportListener2" | ||
1390 | receivers: "Meshes/Stairs/staircase33/teleportListener3" | ||
1395 | panels { room: "North Castle Area" name: "A SUMMER PLACE" } | 1391 | panels { room: "North Castle Area" name: "A SUMMER PLACE" } |
1396 | panels { room: "West Castle Area" name: "SONG FACE" } | 1392 | panels { room: "West Castle Area" name: "SONG FACE" } |
1397 | panels { room: "South Castle Area" name: "AN OFFER VILLAGE BEFORE LAIR" } | 1393 | panels { room: "South Castle Area" name: "AN OFFER VILLAGE BEFORE LAIR" } |
1394 | } | ||
1395 | doors { | ||
1396 | name: "North Castle Panel" | ||
1397 | type: LOCATION_ONLY | ||
1398 | panels { room: "North Castle Area" name: "A SUMMER PLACE" } | ||
1399 | location_room: "North Castle Area" | ||
1400 | } | ||
1401 | doors { | ||
1402 | name: "West Castle Panel" | ||
1403 | type: LOCATION_ONLY | ||
1404 | panels { room: "West Castle Area" name: "SONG FACE" } | ||
1405 | location_room: "West Castle Area" | ||
1406 | } | ||
1407 | doors { | ||
1408 | name: "South Castle Panel" | ||
1409 | type: LOCATION_ONLY | ||
1410 | panels { room: "South Castle Area" name: "AN OFFER VILLAGE BEFORE LAIR" } | ||
1398 | location_room: "South Castle Area" | 1411 | location_room: "South Castle Area" |
1399 | } | 1412 | } |
1400 | doors { | 1413 | doors { |
@@ -1411,6 +1424,7 @@ doors { | |||
1411 | panels { room: "West Spire" name: "CUT" } | 1424 | panels { room: "West Spire" name: "CUT" } |
1412 | panels { room: "West Spire" name: "STONES" } | 1425 | panels { room: "West Spire" name: "STONES" } |
1413 | location_room: "West Spire" | 1426 | location_room: "West Spire" |
1427 | location_name: "Pairs Room Puzzles" | ||
1414 | } | 1428 | } |
1415 | doors { | 1429 | doors { |
1416 | name: "Pairs Room West Door" | 1430 | name: "Pairs Room West Door" |
@@ -1453,87 +1467,87 @@ doors { | |||
1453 | } | 1467 | } |
1454 | doors { | 1468 | doors { |
1455 | name: "Red Rainbow Room" | 1469 | name: "Red Rainbow Room" |
1456 | type: ITEM_ONLY | 1470 | type: STANDARD |
1457 | receivers: "Components/Doors/Color Reading/door_3" | 1471 | receivers: "Components/Doors/Color Reading/door_3" |
1458 | panels { room: "Rainbow Start" name: "PAINTING" } | 1472 | panels { room: "Rainbow Start" name: "PAINTING" } |
1459 | panels { room: "Red Smiley" name: "SMILE" } | 1473 | location_room: "Rainbow Start" |
1460 | } | 1474 | } |
1461 | doors { | 1475 | doors { |
1462 | name: "Orange Rainbow Room" | 1476 | name: "Orange Rainbow Room" |
1463 | type: ITEM_ONLY | 1477 | type: ITEM_ONLY |
1464 | receivers: "Components/Doors/Color Reading/door_4" | 1478 | receivers: "Components/Doors/Color Reading/door_4" |
1465 | panels { room: "Rainbow Red" name: "THEME" } | 1479 | panels { room: "Rainbow Red" name: "THEME" } |
1466 | panels { room: "Outside Orange Room" name: "SMILE" } | 1480 | panels { room: "Red Smiley" name: "SMILE" } |
1467 | } | 1481 | } |
1468 | doors { | 1482 | doors { |
1469 | name: "Yellow Rainbow Room" | 1483 | name: "Yellow Rainbow Room" |
1470 | type: ITEM_ONLY | 1484 | type: ITEM_ONLY |
1471 | receivers: "Components/Doors/Color Reading/door_17" | 1485 | receivers: "Components/Doors/Color Reading/door_17" |
1472 | panels { room: "Rainbow Orange" name: "THEME" } | 1486 | panels { room: "Rainbow Orange" name: "THEME" } |
1473 | panels { room: "Hedges" name: "SMILE" } | 1487 | panels { room: "Outside Orange Room" name: "SMILE" } |
1474 | } | 1488 | } |
1475 | doors { | 1489 | doors { |
1476 | name: "Green Rainbow Room" | 1490 | name: "Green Rainbow Room" |
1477 | type: ITEM_ONLY | 1491 | type: ITEM_ONLY |
1478 | receivers: "Components/Doors/Color Reading/door_5" | 1492 | receivers: "Components/Doors/Color Reading/door_5" |
1479 | panels { room: "Rainbow Yellow" name: "THEME" } | 1493 | panels { room: "Rainbow Yellow" name: "THEME" } |
1480 | panels { room: "Green Smiley" name: "SMILE" } | 1494 | panels { room: "Hedges" name: "SMILE" } |
1481 | } | 1495 | } |
1482 | doors { | 1496 | doors { |
1483 | name: "Blue Rainbow Room" | 1497 | name: "Blue Rainbow Room" |
1484 | type: ITEM_ONLY | 1498 | type: ITEM_ONLY |
1485 | receivers: "Components/Doors/Color Reading/door_6" | 1499 | receivers: "Components/Doors/Color Reading/door_6" |
1486 | panels { room: "Rainbow Green" name: "THEME" } | 1500 | panels { room: "Rainbow Green" name: "THEME" } |
1487 | panels { room: "Blue Smiley" name: "SMILE" } | 1501 | panels { room: "Green Smiley" name: "SMILE" } |
1488 | } | 1502 | } |
1489 | doors { | 1503 | doors { |
1490 | name: "Purple Rainbow Room" | 1504 | name: "Purple Rainbow Room" |
1491 | type: ITEM_ONLY | 1505 | type: ITEM_ONLY |
1492 | receivers: "Components/Doors/Color Reading/door_7" | 1506 | receivers: "Components/Doors/Color Reading/door_7" |
1493 | panels { room: "Rainbow Blue" name: "THEME" } | 1507 | panels { room: "Rainbow Blue" name: "THEME" } |
1494 | panels { room: "Purple Smiley" name: "SMILE" } | 1508 | panels { room: "Blue Smiley" name: "SMILE" } |
1495 | } | 1509 | } |
1496 | doors { | 1510 | doors { |
1497 | name: "Red Rainbow Panel" | 1511 | name: "Red Rainbow Panel" |
1498 | type: LOCATION_ONLY | 1512 | type: LOCATION_ONLY |
1499 | panels { room: "Rainbow Start" name: "PAINTING" } | ||
1500 | location_room: "Rainbow Start" | ||
1501 | } | ||
1502 | doors { | ||
1503 | name: "Orange Rainbow Panel" | ||
1504 | type: LOCATION_ONLY | ||
1505 | panels { room: "Rainbow Red" name: "THEME" } | 1513 | panels { room: "Rainbow Red" name: "THEME" } |
1506 | location_room: "Rainbow Red" | 1514 | location_room: "Rainbow Red" |
1507 | } | 1515 | } |
1508 | doors { | 1516 | doors { |
1509 | name: "Yellow Rainbow Panel" | 1517 | name: "Orange Rainbow Panel" |
1510 | type: LOCATION_ONLY | 1518 | type: LOCATION_ONLY |
1511 | panels { room: "Rainbow Orange" name: "THEME" } | 1519 | panels { room: "Rainbow Orange" name: "THEME" } |
1512 | location_room: "Rainbow Orange" | 1520 | location_room: "Rainbow Orange" |
1513 | } | 1521 | } |
1514 | doors { | 1522 | doors { |
1515 | name: "Green Rainbow Panel" | 1523 | name: "Yellow Rainbow Panel" |
1516 | type: LOCATION_ONLY | 1524 | type: LOCATION_ONLY |
1517 | panels { room: "Rainbow Yellow" name: "THEME" } | 1525 | panels { room: "Rainbow Yellow" name: "THEME" } |
1518 | location_room: "Rainbow Yellow" | 1526 | location_room: "Rainbow Yellow" |
1519 | } | 1527 | } |
1520 | doors { | 1528 | doors { |
1521 | name: "Blue Rainbow Panel" | 1529 | name: "Green Rainbow Panel" |
1522 | type: LOCATION_ONLY | 1530 | type: LOCATION_ONLY |
1523 | panels { room: "Rainbow Green" name: "THEME" } | 1531 | panels { room: "Rainbow Green" name: "THEME" } |
1524 | location_room: "Rainbow Green" | 1532 | location_room: "Rainbow Green" |
1525 | } | 1533 | } |
1526 | doors { | 1534 | doors { |
1527 | name: "Purple Rainbow Panel" | 1535 | name: "Blue Rainbow Panel" |
1528 | type: LOCATION_ONLY | 1536 | type: LOCATION_ONLY |
1529 | panels { room: "Rainbow Blue" name: "THEME" } | 1537 | panels { room: "Rainbow Blue" name: "THEME" } |
1530 | location_room: "Rainbow Blue" | 1538 | location_room: "Rainbow Blue" |
1531 | } | 1539 | } |
1532 | doors { | 1540 | doors { |
1533 | name: "Cyan Rainbow Room" | 1541 | name: "Cyan Rainbow Room" |
1534 | type: STANDARD | 1542 | type: ITEM_ONLY |
1535 | receivers: "Components/Doors/Color Reading/door_18" | 1543 | receivers: "Components/Doors/Color Reading/door_18" |
1536 | panels { room: "Rainbow Purple" name: "THEME" } | 1544 | panels { room: "Rainbow Purple" name: "THEME" } |
1545 | panels { room: "Purple Smiley" name: "SMILE" } | ||
1546 | } | ||
1547 | doors { | ||
1548 | name: "Purple Rainbow Panel" | ||
1549 | type: LOCATION_ONLY | ||
1550 | panels { room: "Rainbow Purple" name: "THEME" } | ||
1537 | location_room: "Rainbow Purple" | 1551 | location_room: "Rainbow Purple" |
1538 | } | 1552 | } |
1539 | doors { | 1553 | doors { |
@@ -1542,6 +1556,7 @@ doors { | |||
1542 | receivers: "Components/Doors/Color Reading/door_8" | 1556 | receivers: "Components/Doors/Color Reading/door_8" |
1543 | panels { room: "Rainbow Cyan" name: "THEME" } | 1557 | panels { room: "Rainbow Cyan" name: "THEME" } |
1544 | location_room: "Rainbow Cyan" | 1558 | location_room: "Rainbow Cyan" |
1559 | location_name: "Cyan Rainbow Panel" | ||
1545 | } | 1560 | } |
1546 | doors { | 1561 | doors { |
1547 | name: "Pepper Room Entrance" | 1562 | name: "Pepper Room Entrance" |
@@ -1565,6 +1580,7 @@ doors { | |||
1565 | panels { room: "Salt Room" name: "SEASONING" } | 1580 | panels { room: "Salt Room" name: "SEASONING" } |
1566 | panels { room: "Pepper Room" name: "SEASONING" } | 1581 | panels { room: "Pepper Room" name: "SEASONING" } |
1567 | location_room: "Pepper Room" | 1582 | location_room: "Pepper Room" |
1583 | location_name: "Seasonings" | ||
1568 | } | 1584 | } |
1569 | doors { | 1585 | doors { |
1570 | name: "Bow Side" | 1586 | name: "Bow Side" |
@@ -1600,6 +1616,7 @@ doors { | |||
1600 | # Components/Doors/Smileys/blue_1 | 1616 | # Components/Doors/Smileys/blue_1 |
1601 | panels { room: "Blue Smiley" name: "SMILE" } | 1617 | panels { room: "Blue Smiley" name: "SMILE" } |
1602 | location_room: "Blue Smiley" | 1618 | location_room: "Blue Smiley" |
1619 | location_name: "Blue SMILE" | ||
1603 | } | 1620 | } |
1604 | doors { | 1621 | doors { |
1605 | name: "Blue Smiley Annex" | 1622 | name: "Blue Smiley Annex" |
@@ -1631,6 +1648,7 @@ doors { | |||
1631 | receivers: "Components/Doors/Smileys/yellow_2" | 1648 | receivers: "Components/Doors/Smileys/yellow_2" |
1632 | panels { room: "Hedges" name: "SMILE" } | 1649 | panels { room: "Hedges" name: "SMILE" } |
1633 | location_room: "Hedges" | 1650 | location_room: "Hedges" |
1651 | location_name: "Yellow SMILE" | ||
1634 | } | 1652 | } |
1635 | doors { | 1653 | doors { |
1636 | name: "Green Smiley" | 1654 | name: "Green Smiley" |
@@ -1639,6 +1657,7 @@ doors { | |||
1639 | receivers: "Components/Doors/Smileys/green_2" | 1657 | receivers: "Components/Doors/Smileys/green_2" |
1640 | panels { room: "Green Smiley" name: "SMILE" } | 1658 | panels { room: "Green Smiley" name: "SMILE" } |
1641 | location_room: "Green Smiley" | 1659 | location_room: "Green Smiley" |
1660 | location_name: "Green SMILE" | ||
1642 | } | 1661 | } |
1643 | doors { | 1662 | doors { |
1644 | name: "Orange Smiley Exit" | 1663 | name: "Orange Smiley Exit" |
@@ -1646,6 +1665,7 @@ doors { | |||
1646 | receivers: "Components/Doors/Smileys/orange_1" | 1665 | receivers: "Components/Doors/Smileys/orange_1" |
1647 | panels { room: "Outside Orange Room" name: "SMILE" } | 1666 | panels { room: "Outside Orange Room" name: "SMILE" } |
1648 | location_room: "Outside Orange Room" | 1667 | location_room: "Outside Orange Room" |
1668 | location_name: "Orange SMILE" | ||
1649 | } | 1669 | } |
1650 | doors { | 1670 | doors { |
1651 | name: "F Keyholder Door" | 1671 | name: "F Keyholder Door" |
@@ -1670,6 +1690,7 @@ doors { | |||
1670 | type: LOCATION_ONLY | 1690 | type: LOCATION_ONLY |
1671 | panels { room: "Red Smiley" name: "SMILE" } | 1691 | panels { room: "Red Smiley" name: "SMILE" } |
1672 | location_room: "Red Smiley" | 1692 | location_room: "Red Smiley" |
1693 | location_name: "Red SMILE" | ||
1673 | } | 1694 | } |
1674 | doors { | 1695 | doors { |
1675 | name: "Pink Hallway" | 1696 | name: "Pink Hallway" |
@@ -1708,6 +1729,7 @@ doors { | |||
1708 | panels { room: "Cyan Room" name: "COLD" } | 1729 | panels { room: "Cyan Room" name: "COLD" } |
1709 | panels { room: "Cyan Room" name: "WORDWORD" } | 1730 | panels { room: "Cyan Room" name: "WORDWORD" } |
1710 | location_room: "Cyan Room" | 1731 | location_room: "Cyan Room" |
1732 | location_name: "Puzzles" | ||
1711 | } | 1733 | } |
1712 | doors { | 1734 | doors { |
1713 | name: "Green Room Entrance" | 1735 | name: "Green Room Entrance" |
@@ -1731,6 +1753,7 @@ doors { | |||
1731 | panels { room: "Green Room" name: "DOUBLE" } | 1753 | panels { room: "Green Room" name: "DOUBLE" } |
1732 | panels { room: "Green Room" name: "BADMINTON" } | 1754 | panels { room: "Green Room" name: "BADMINTON" } |
1733 | location_room: "Green Room" | 1755 | location_room: "Green Room" |
1756 | location_name: "Puzzles" | ||
1734 | } | 1757 | } |
1735 | doors { | 1758 | doors { |
1736 | name: "Blue Hallway South Divider" | 1759 | name: "Blue Hallway South Divider" |
@@ -1769,6 +1792,7 @@ doors { | |||
1769 | panels { room: "Red Room" name: "TESTAMENT" } | 1792 | panels { room: "Red Room" name: "TESTAMENT" } |
1770 | panels { room: "Red Room" name: "TAKEOUT" } | 1793 | panels { room: "Red Room" name: "TAKEOUT" } |
1771 | location_room: "Red Room" | 1794 | location_room: "Red Room" |
1795 | location_name: "Puzzles" | ||
1772 | } | 1796 | } |
1773 | doors { | 1797 | doors { |
1774 | name: "Blue Hallway To Red Room" | 1798 | name: "Blue Hallway To Red Room" |
@@ -1782,6 +1806,7 @@ doors { | |||
1782 | panels { room: "Blue Hallway" name: "CHOP" } | 1806 | panels { room: "Blue Hallway" name: "CHOP" } |
1783 | panels { room: "Blue Hallway Tall Side" name: "TALL" } | 1807 | panels { room: "Blue Hallway Tall Side" name: "TALL" } |
1784 | location_room: "Blue Hallway Tall Side" | 1808 | location_room: "Blue Hallway Tall Side" |
1809 | location_name: "CHOP, TALL" | ||
1785 | } | 1810 | } |
1786 | doors { | 1811 | doors { |
1787 | name: "Near Yellow Room Door" | 1812 | name: "Near Yellow Room Door" |
@@ -1794,6 +1819,7 @@ doors { | |||
1794 | panels { room: "Blue Hallway Tall Side" name: "CHILD" } | 1819 | panels { room: "Blue Hallway Tall Side" name: "CHILD" } |
1795 | panels { room: "Blue Hallway Tall Side" name: "NEW" } | 1820 | panels { room: "Blue Hallway Tall Side" name: "NEW" } |
1796 | location_room: "Blue Hallway Tall Side" | 1821 | location_room: "Blue Hallway Tall Side" |
1822 | location_name: "Pink Hex" | ||
1797 | } | 1823 | } |
1798 | doors { | 1824 | doors { |
1799 | name: "House Side Door" | 1825 | name: "House Side Door" |
@@ -1830,6 +1856,7 @@ doors { | |||
1830 | panels { room: "Yellow Room" name: "PROTON" } | 1856 | panels { room: "Yellow Room" name: "PROTON" } |
1831 | panels { room: "Yellow Room" name: "SPIRIT" } | 1857 | panels { room: "Yellow Room" name: "SPIRIT" } |
1832 | location_room: "Yellow Room" | 1858 | location_room: "Yellow Room" |
1859 | location_name: "Puzzles" | ||
1833 | } | 1860 | } |
1834 | doors { | 1861 | doors { |
1835 | name: "Dark Light Room Entrance" | 1862 | name: "Dark Light Room Entrance" |
@@ -1865,6 +1892,7 @@ doors { | |||
1865 | type: LOCATION_ONLY | 1892 | type: LOCATION_ONLY |
1866 | panels { room: "Dark Light Exit" name: "GASKET" } | 1893 | panels { room: "Dark Light Exit" name: "GASKET" } |
1867 | location_room: "Dark Light Exit" | 1894 | location_room: "Dark Light Exit" |
1895 | location_name: "GASKET" | ||
1868 | } | 1896 | } |
1869 | doors { | 1897 | doors { |
1870 | name: "Dark Light Room Divider" | 1898 | name: "Dark Light Room Divider" |
@@ -1884,6 +1912,7 @@ doors { | |||
1884 | # Not technically true; it's complete_at=11 with both rooms, but you couldn't | 1912 | # Not technically true; it's complete_at=11 with both rooms, but you couldn't |
1885 | # get to the other side in vanilla doors anyway. | 1913 | # get to the other side in vanilla doors anyway. |
1886 | location_room: "Dark Light Room" | 1914 | location_room: "Dark Light Room" |
1915 | location_name: "Main Puzzles" | ||
1887 | } | 1916 | } |
1888 | doors { | 1917 | doors { |
1889 | name: "Near Sweet Blue Door" | 1918 | name: "Near Sweet Blue Door" |
@@ -1896,6 +1925,7 @@ doors { | |||
1896 | panels { room: "Gray Color Backside" name: "LAST" } | 1925 | panels { room: "Gray Color Backside" name: "LAST" } |
1897 | panels { room: "Gray Color Backside" name: "RISE" } | 1926 | panels { room: "Gray Color Backside" name: "RISE" } |
1898 | location_room: "Gray Color Backside" | 1927 | location_room: "Gray Color Backside" |
1928 | location_name: "Light Green Hex" | ||
1899 | } | 1929 | } |
1900 | doors { | 1930 | doors { |
1901 | name: "South Castle Area Back Door" | 1931 | name: "South Castle Area Back Door" |
@@ -1935,6 +1965,7 @@ doors { | |||
1935 | panels { room: "Plum Room" name: "SNAKE" } | 1965 | panels { room: "Plum Room" name: "SNAKE" } |
1936 | panels { room: "Plum Room" name: "CENTER" } | 1966 | panels { room: "Plum Room" name: "CENTER" } |
1937 | location_room: "Plum Room" | 1967 | location_room: "Plum Room" |
1968 | location_name: "Plum Room" | ||
1938 | } | 1969 | } |
1939 | doors { | 1970 | doors { |
1940 | name: "D Keyholder Blocker" | 1971 | name: "D Keyholder Blocker" |
@@ -2036,6 +2067,7 @@ doors { | |||
2036 | panels { room: "Computer Room" name: "MOUSE (2)" } | 2067 | panels { room: "Computer Room" name: "MOUSE (2)" } |
2037 | panels { room: "Computer Room" name: "KEYBOARD (2)" } | 2068 | panels { room: "Computer Room" name: "KEYBOARD (2)" } |
2038 | location_room: "Computer Room" | 2069 | location_room: "Computer Room" |
2070 | location_name: "Main Puzzles" | ||
2039 | } | 2071 | } |
2040 | doors { | 2072 | doors { |
2041 | name: "Computer Room Entrance" | 2073 | name: "Computer Room Entrance" |
@@ -2048,12 +2080,17 @@ doors { | |||
2048 | panels { room: "Rainbow Color Doors" name: "MISCHIEF" } | 2080 | panels { room: "Rainbow Color Doors" name: "MISCHIEF" } |
2049 | panels { room: "Rainbow Color Doors" name: "CASUAL" } | 2081 | panels { room: "Rainbow Color Doors" name: "CASUAL" } |
2050 | location_room: "Rainbow Color Doors" | 2082 | location_room: "Rainbow Color Doors" |
2083 | location_name: "Red Tower" | ||
2051 | } | 2084 | } |
2052 | doors { | 2085 | doors { |
2053 | name: "C Keyholder Blocker" | 2086 | name: "C Keyholder Blocker" |
2054 | type: EVENT | 2087 | type: EVENT |
2055 | # Components/Doors/Unincorporated/temple_foyer_7 | 2088 | receivers: "Components/Doors/Unincorporated/temple_foyer_7" |
2056 | switches: "lavender_cubes" | 2089 | panels { |
2090 | map: "the_ancient" | ||
2091 | room: "Inside" | ||
2092 | name: "COLOR" | ||
2093 | } | ||
2057 | } | 2094 | } |
2058 | doors { | 2095 | doors { |
2059 | name: "Computer Room Back Door" | 2096 | name: "Computer Room Back Door" |
@@ -2115,6 +2152,7 @@ doors { | |||
2115 | panels { room: "Book Room" name: "BOOK (11)" } | 2152 | panels { room: "Book Room" name: "BOOK (11)" } |
2116 | panels { room: "Book Room" name: "BOOK (12)" } | 2153 | panels { room: "Book Room" name: "BOOK (12)" } |
2117 | location_room: "Book Room" | 2154 | location_room: "Book Room" |
2155 | location_name: "Book Room" | ||
2118 | } | 2156 | } |
2119 | doors { | 2157 | doors { |
2120 | name: "Sticks And Stones Door" | 2158 | name: "Sticks And Stones Door" |
@@ -2122,6 +2160,7 @@ doors { | |||
2122 | receivers: "Components/Doors/Unincorporated/temple_foyer_6" | 2160 | receivers: "Components/Doors/Unincorporated/temple_foyer_6" |
2123 | panels { room: "Globe Room" name: "WORD" } | 2161 | panels { room: "Globe Room" name: "WORD" } |
2124 | location_room: "Globe Room" | 2162 | location_room: "Globe Room" |
2163 | location_name: "Sticks and Stones" | ||
2125 | } | 2164 | } |
2126 | doors { | 2165 | doors { |
2127 | name: "Castle Numbers Puzzle" | 2166 | name: "Castle Numbers Puzzle" |
@@ -2141,6 +2180,7 @@ doors { | |||
2141 | panels { room: "Black Hex" name: "BARK" } | 2180 | panels { room: "Black Hex" name: "BARK" } |
2142 | panels { room: "Zoo N" name: "LEAF" } | 2181 | panels { room: "Zoo N" name: "LEAF" } |
2143 | location_room: "Zoo N" | 2182 | location_room: "Zoo N" |
2183 | location_name: "BARK, LEAF" | ||
2144 | } | 2184 | } |
2145 | doors { | 2185 | doors { |
2146 | name: "Zoo East Entrance" | 2186 | name: "Zoo East Entrance" |
@@ -2226,3 +2266,38 @@ doors { | |||
2226 | panels { room: "Yellow Color Backside" name: "REDACTED" } | 2266 | panels { room: "Yellow Color Backside" name: "REDACTED" } |
2227 | location_room: "Yellow Color Backside" | 2267 | location_room: "Yellow Color Backside" |
2228 | } | 2268 | } |
2269 | doors { | ||
2270 | name: "Tenacious Color Painting" | ||
2271 | type: EVENT | ||
2272 | panels { room: "South Castle Area" name: "COLOR (1)" answer: "red" } | ||
2273 | panels { room: "South Castle Area" name: "COLOR (2)" answer: "yellow" } | ||
2274 | panels { room: "South Castle Area" name: "COLOR (3)" answer: "purple" } | ||
2275 | panels { room: "South Castle Area" name: "COLOR (4)" answer: "green" } | ||
2276 | } | ||
2277 | doors { | ||
2278 | name: "Eye Painting" | ||
2279 | type: ITEM_ONLY | ||
2280 | receivers: "Components/Paintings/Temple of the Eyes/eyeRedStart/teleportListener" | ||
2281 | double_letters: true | ||
2282 | } | ||
2283 | doors { | ||
2284 | name: "Lime Hexes" | ||
2285 | type: LOCATION_ONLY | ||
2286 | panels { room: "Tree Entrance" name: "RAT" } | ||
2287 | panels { room: "Tree Entrance" name: "DIFFERENCE" } | ||
2288 | panels { room: "Tree Entrance" name: "LEANS" } | ||
2289 | panels { room: "Tree Entrance" name: "QUESTION" } | ||
2290 | panels { room: "Tree Entrance" name: "WHERE" } | ||
2291 | panels { room: "Tree Entrance" name: "SUNDER" } | ||
2292 | location_room: "Tree Entrance" | ||
2293 | } | ||
2294 | doors { | ||
2295 | name: "Theo Panels" | ||
2296 | type: LOCATION_ONLY | ||
2297 | panels { room: "House" name: "GOAT" } | ||
2298 | panels { room: "House" name: "AMAZE" } | ||
2299 | panels { room: "House" name: "SKINNYHIM" } | ||
2300 | panels { room: "House" name: "THEO" } | ||
2301 | location_room: "House" | ||
2302 | location_name: "All Puzzles" | ||
2303 | } | ||
diff --git a/data/maps/daedalus/rooms/After Bee Room.txtpb b/data/maps/daedalus/rooms/After Bee Room.txtpb index f38bd7d..c2dfc0f 100644 --- a/data/maps/daedalus/rooms/After Bee Room.txtpb +++ b/data/maps/daedalus/rooms/After Bee Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "After Bee Room" | 1 | name: "After Bee Room" |
2 | display_name: "North Area" | 2 | panel_display_name: "North Area" |
3 | panels { | 3 | panels { |
4 | name: "GAS" | 4 | name: "GAS" |
5 | path: "Panels/Beehalls/beehalls_2" | 5 | path: "Panels/Beehalls/beehalls_2" |
diff --git a/data/maps/daedalus/rooms/Amber North 2.txtpb b/data/maps/daedalus/rooms/Amber North 2.txtpb index 8fbaccd..7029695 100644 --- a/data/maps/daedalus/rooms/Amber North 2.txtpb +++ b/data/maps/daedalus/rooms/Amber North 2.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Amber North 2" | 1 | name: "Amber North 2" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
3 | panels { | 3 | panels { |
4 | name: "SONG" | 4 | name: "SONG" |
5 | path: "Panels/Amber/amber_north_2" | 5 | path: "Panels/Amber/amber_north_2" |
diff --git a/data/maps/daedalus/rooms/Bee Room Obverse.txtpb b/data/maps/daedalus/rooms/Bee Room Obverse.txtpb index 1badbc0..7677ed1 100644 --- a/data/maps/daedalus/rooms/Bee Room Obverse.txtpb +++ b/data/maps/daedalus/rooms/Bee Room Obverse.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Bee Room Obverse" | 1 | name: "Bee Room Obverse" |
2 | display_name: "Bee Room" | 2 | panel_display_name: "Bee Room" |
3 | panels { | 3 | panels { |
4 | name: "SINGLE" | 4 | name: "SINGLE" |
5 | path: "Panels/Bee Room/bee_1" | 5 | path: "Panels/Bee Room/bee_1" |
diff --git a/data/maps/daedalus/rooms/Bee Room Reverse.txtpb b/data/maps/daedalus/rooms/Bee Room Reverse.txtpb index f455f06..cba8285 100644 --- a/data/maps/daedalus/rooms/Bee Room Reverse.txtpb +++ b/data/maps/daedalus/rooms/Bee Room Reverse.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Bee Room Reverse" | 1 | name: "Bee Room Reverse" |
2 | display_name: "Bee Room" | 2 | panel_display_name: "Bee Room" |
3 | panels { | 3 | panels { |
4 | name: "POCKET" | 4 | name: "POCKET" |
5 | path: "Panels/Bee Room/bee_9" | 5 | path: "Panels/Bee Room/bee_9" |
diff --git a/data/maps/daedalus/rooms/Beehalls Intersection.txtpb b/data/maps/daedalus/rooms/Beehalls Intersection.txtpb index fecf71d..7ecbe50 100644 --- a/data/maps/daedalus/rooms/Beehalls Intersection.txtpb +++ b/data/maps/daedalus/rooms/Beehalls Intersection.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Beehalls Intersection" | 1 | name: "Beehalls Intersection" |
2 | display_name: "North Area" | 2 | panel_display_name: "North Area" |
3 | panels { | 3 | panels { |
4 | name: "CLOUDS" | 4 | name: "CLOUDS" |
5 | path: "Panels/Halls/beehalls_4" | 5 | path: "Panels/Halls/beehalls_4" |
diff --git a/data/maps/daedalus/rooms/Black Hex.txtpb b/data/maps/daedalus/rooms/Black Hex.txtpb index bd8359e..1276685 100644 --- a/data/maps/daedalus/rooms/Black Hex.txtpb +++ b/data/maps/daedalus/rooms/Black Hex.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Black Hex" | 1 | name: "Black Hex" |
2 | display_name: "Northwest Area" | 2 | panel_display_name: "Northwest Area" |
3 | panels { | 3 | panels { |
4 | name: "HIDE" | 4 | name: "HIDE" |
5 | path: "Panels/Hexes/black_1" | 5 | path: "Panels/Hexes/black_1" |
diff --git a/data/maps/daedalus/rooms/Blue Hallway Cut Side.txtpb b/data/maps/daedalus/rooms/Blue Hallway Cut Side.txtpb index ea2ffef..5a6c081 100644 --- a/data/maps/daedalus/rooms/Blue Hallway Cut Side.txtpb +++ b/data/maps/daedalus/rooms/Blue Hallway Cut Side.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Blue Hallway Cut Side" | 1 | name: "Blue Hallway Cut Side" |
2 | display_name: "South Area" | 2 | panel_display_name: "South Area" |
3 | panels { | 3 | panels { |
4 | name: "CUT" | 4 | name: "CUT" |
5 | path: "Panels/Halls/halls_6" | 5 | path: "Panels/Halls/halls_6" |
diff --git a/data/maps/daedalus/rooms/Blue Hallway Tall Side.txtpb b/data/maps/daedalus/rooms/Blue Hallway Tall Side.txtpb index 93d4136..4a775d8 100644 --- a/data/maps/daedalus/rooms/Blue Hallway Tall Side.txtpb +++ b/data/maps/daedalus/rooms/Blue Hallway Tall Side.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Blue Hallway Tall Side" | 1 | name: "Blue Hallway Tall Side" |
2 | display_name: "Northeast Area" | 2 | panel_display_name: "Northeast Area" |
3 | panels { | 3 | panels { |
4 | name: "TALL" | 4 | name: "TALL" |
5 | path: "Panels/Halls/halls_9" | 5 | path: "Panels/Halls/halls_9" |
diff --git a/data/maps/daedalus/rooms/Blue Hallway.txtpb b/data/maps/daedalus/rooms/Blue Hallway.txtpb index 0bac459..81bc428 100644 --- a/data/maps/daedalus/rooms/Blue Hallway.txtpb +++ b/data/maps/daedalus/rooms/Blue Hallway.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Blue Hallway" | 1 | name: "Blue Hallway" |
2 | display_name: "South Area" | 2 | panel_display_name: "South Area" |
3 | panels { | 3 | panels { |
4 | name: "CHOP" | 4 | name: "CHOP" |
5 | path: "Panels/Halls/halls_10" | 5 | path: "Panels/Halls/halls_10" |
diff --git a/data/maps/daedalus/rooms/Blue Room.txtpb b/data/maps/daedalus/rooms/Blue Room.txtpb index 98d933b..1d060d8 100644 --- a/data/maps/daedalus/rooms/Blue Room.txtpb +++ b/data/maps/daedalus/rooms/Blue Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Blue Room" | 1 | name: "Blue Room" |
2 | display_name: "East Area" | 2 | panel_display_name: "Blue Room" |
3 | panels { | 3 | panels { |
4 | name: "RED" | 4 | name: "RED" |
5 | path: "Panels/Blue Room/panel_1" | 5 | path: "Panels/Blue Room/panel_1" |
diff --git a/data/maps/daedalus/rooms/Blue Smiley Annex.txtpb b/data/maps/daedalus/rooms/Blue Smiley Annex.txtpb index c39aeb5..d44bf1a 100644 --- a/data/maps/daedalus/rooms/Blue Smiley Annex.txtpb +++ b/data/maps/daedalus/rooms/Blue Smiley Annex.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Blue Smiley Annex" | 1 | name: "Blue Smiley Annex" |
2 | display_name: "South Area" | 2 | panel_display_name: "South Area" |
3 | panels { | 3 | panels { |
4 | name: "ORANGE (1)" | 4 | name: "ORANGE (1)" |
5 | path: "Panels/Miscellaneous/yellow" | 5 | path: "Panels/Miscellaneous/yellow" |
diff --git a/data/maps/daedalus/rooms/Blue Smiley.txtpb b/data/maps/daedalus/rooms/Blue Smiley.txtpb index 5ddb330..8464525 100644 --- a/data/maps/daedalus/rooms/Blue Smiley.txtpb +++ b/data/maps/daedalus/rooms/Blue Smiley.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Blue Smiley" | 1 | name: "Blue Smiley" |
2 | display_name: "South Area" | 2 | panel_display_name: "South Area" |
3 | panels { | 3 | panels { |
4 | name: "SMILE" | 4 | name: "SMILE" |
5 | path: "Panels/Smiley Rooms/blue" | 5 | path: "Panels/Smiley Rooms/blue" |
diff --git a/data/maps/daedalus/rooms/Book Room.txtpb b/data/maps/daedalus/rooms/Book Room.txtpb index 7571ec1..534fbfe 100644 --- a/data/maps/daedalus/rooms/Book Room.txtpb +++ b/data/maps/daedalus/rooms/Book Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Book Room" | 1 | name: "Book Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "BOOK (1)" | 4 | name: "BOOK (1)" |
5 | path: "Panels/Book Room/book_1" | 5 | path: "Panels/Book Room/book_1" |
diff --git a/data/maps/daedalus/rooms/Bow Side.txtpb b/data/maps/daedalus/rooms/Bow Side.txtpb index 6e07925..f04065d 100644 --- a/data/maps/daedalus/rooms/Bow Side.txtpb +++ b/data/maps/daedalus/rooms/Bow Side.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Bow Side" | 1 | name: "Bow Side" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "?" | 4 | name: "?" |
5 | path: "Panels/Smiley Rooms/bow" | 5 | path: "Panels/Smiley Rooms/bow" |
6 | clue: "" | 6 | clue: "" |
7 | answer: "bow" | 7 | answer: "bow" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "? (2)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Brown Smiley.txtpb b/data/maps/daedalus/rooms/Brown Smiley.txtpb index 91ba963..53783c1 100644 --- a/data/maps/daedalus/rooms/Brown Smiley.txtpb +++ b/data/maps/daedalus/rooms/Brown Smiley.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Brown Smiley" | 1 | name: "Brown Smiley" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "OTHERS" | 4 | name: "OTHERS" |
5 | path: "Panels/Smiley Rooms/rainbow2" | 5 | path: "Panels/Smiley Rooms/rainbow2" |
diff --git a/data/maps/daedalus/rooms/C Keyholder.txtpb b/data/maps/daedalus/rooms/C Keyholder.txtpb index a8ad9aa..28793b2 100644 --- a/data/maps/daedalus/rooms/C Keyholder.txtpb +++ b/data/maps/daedalus/rooms/C Keyholder.txtpb | |||
@@ -1,6 +1,7 @@ | |||
1 | name: "C Keyholder" | 1 | name: "C Keyholder" |
2 | display_name: "North Area" | 2 | panel_display_name: "East Area" |
3 | keyholders { | 3 | keyholders { |
4 | name: "C" | 4 | name: "C" |
5 | path: "Components/KeyHolders/keyHolderC" | 5 | path: "Components/KeyHolders/keyHolderC" |
6 | key: "c" | ||
6 | } | 7 | } |
diff --git a/data/maps/daedalus/rooms/Castle.txtpb b/data/maps/daedalus/rooms/Castle.txtpb index 4797e80..7fd9a81 100644 --- a/data/maps/daedalus/rooms/Castle.txtpb +++ b/data/maps/daedalus/rooms/Castle.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Castle" | 1 | name: "Castle" |
2 | display_name: "Castle" | 2 | panel_display_name: "Castle" |
3 | panels { | 3 | panels { |
4 | name: "REVERSE" | 4 | name: "REVERSE" |
5 | path: "Panels/Castle Interior/panel_flip" | 5 | path: "Panels/Castle Interior/panel_flip" |
diff --git a/data/maps/daedalus/rooms/Coin Tower.txtpb b/data/maps/daedalus/rooms/Coin Tower.txtpb index 032ece3..177fc6e 100644 --- a/data/maps/daedalus/rooms/Coin Tower.txtpb +++ b/data/maps/daedalus/rooms/Coin Tower.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Coin Tower" | 1 | name: "Coin Tower" |
2 | display_name: "Northeast Area" | 2 | panel_display_name: "Northeast Area" |
3 | panels { | 3 | panels { |
4 | name: "RAIN" | 4 | name: "RAIN" |
5 | path: "Panels/Entry/db_2" | 5 | path: "Panels/Entry/db_2" |
diff --git a/data/maps/daedalus/rooms/Composite Room NE.txtpb b/data/maps/daedalus/rooms/Composite Room NE.txtpb index a4b13cd..c91a06f 100644 --- a/data/maps/daedalus/rooms/Composite Room NE.txtpb +++ b/data/maps/daedalus/rooms/Composite Room NE.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Composite Room NE" | 1 | name: "Composite Room NE" |
2 | display_name: "Composite Room" | 2 | panel_display_name: "Composite Room" |
3 | panels { | 3 | panels { |
4 | name: "<-" | 4 | name: "<-" |
5 | path: "Panels/Combo Room NE/panel_1" | 5 | path: "Panels/Combo Room NE/panel_1" |
diff --git a/data/maps/daedalus/rooms/Composite Room NW.txtpb b/data/maps/daedalus/rooms/Composite Room NW.txtpb index 94f987b..949fe31 100644 --- a/data/maps/daedalus/rooms/Composite Room NW.txtpb +++ b/data/maps/daedalus/rooms/Composite Room NW.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Composite Room NW" | 1 | name: "Composite Room NW" |
2 | display_name: "Composite Room" | 2 | panel_display_name: "Composite Room" |
3 | panels { | 3 | panels { |
4 | name: "BEHOUSE" | 4 | name: "BEHOUSE" |
5 | path: "Panels/Combo Room NW/panel_1" | 5 | path: "Panels/Combo Room NW/panel_1" |
diff --git a/data/maps/daedalus/rooms/Composite Room S.txtpb b/data/maps/daedalus/rooms/Composite Room S.txtpb index ec36ac3..0cb69bf 100644 --- a/data/maps/daedalus/rooms/Composite Room S.txtpb +++ b/data/maps/daedalus/rooms/Composite Room S.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Composite Room S" | 1 | name: "Composite Room S" |
2 | display_name: "Composite Room" | 2 | panel_display_name: "Composite Room" |
3 | panels { | 3 | panels { |
4 | name: "CONCAVE" | 4 | name: "CONCAVE" |
5 | path: "Panels/Combo Room SW/panel_1" | 5 | path: "Panels/Combo Room SW/panel_1" |
@@ -194,5 +194,8 @@ panels { | |||
194 | } | 194 | } |
195 | ports { | 195 | ports { |
196 | name: "ENTRY" | 196 | name: "ENTRY" |
197 | display_name: "Composite Room Worldport" | ||
197 | path: "Components/Warps/Worldports/worldport16" | 198 | path: "Components/Warps/Worldports/worldport16" |
199 | destination { x: -84 y: 0 z: 81 } | ||
200 | rotation: 270 | ||
198 | } | 201 | } |
diff --git a/data/maps/daedalus/rooms/Computer Room Seal.txtpb b/data/maps/daedalus/rooms/Computer Room Seal.txtpb index 19dcf3a..b271a5c 100644 --- a/data/maps/daedalus/rooms/Computer Room Seal.txtpb +++ b/data/maps/daedalus/rooms/Computer Room Seal.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Computer Room Seal" | 1 | name: "Computer Room Seal" |
2 | display_name: "Computer Room" | 2 | panel_display_name: "Computer Room" |
3 | panels { | 3 | panels { |
4 | name: "SCROLL" | 4 | name: "SCROLL" |
5 | path: "Panels/Computer/computer_11" | 5 | path: "Panels/Computer/computer_11" |
diff --git a/data/maps/daedalus/rooms/Computer Room.txtpb b/data/maps/daedalus/rooms/Computer Room.txtpb index 9cc6cbf..1d5a56d 100644 --- a/data/maps/daedalus/rooms/Computer Room.txtpb +++ b/data/maps/daedalus/rooms/Computer Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Computer Room" | 1 | name: "Computer Room" |
2 | display_name: "Computer Room" | 2 | panel_display_name: "Computer Room" |
3 | panels { | 3 | panels { |
4 | name: "MONITOR (1)" | 4 | name: "MONITOR (1)" |
5 | path: "Panels/Computer/computer_1" | 5 | path: "Panels/Computer/computer_1" |
diff --git a/data/maps/daedalus/rooms/Cyan Room.txtpb b/data/maps/daedalus/rooms/Cyan Room.txtpb index 8430dcd..60a3595 100644 --- a/data/maps/daedalus/rooms/Cyan Room.txtpb +++ b/data/maps/daedalus/rooms/Cyan Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Cyan Room" | 1 | name: "Cyan Room" |
2 | display_name: "West Area" | 2 | panel_display_name: "Cyan Room" |
3 | panels { | 3 | panels { |
4 | name: "LIFE" | 4 | name: "LIFE" |
5 | path: "Panels/Brown Room/panel_1" | 5 | path: "Panels/Brown Room/panel_1" |
diff --git a/data/maps/daedalus/rooms/D Keyholder.txtpb b/data/maps/daedalus/rooms/D Keyholder.txtpb index d2f226b..a5852be 100644 --- a/data/maps/daedalus/rooms/D Keyholder.txtpb +++ b/data/maps/daedalus/rooms/D Keyholder.txtpb | |||
@@ -1,6 +1,7 @@ | |||
1 | name: "D Keyholder" | 1 | name: "D Keyholder" |
2 | display_name: "Plum Room" | 2 | panel_display_name: "Plum Room" |
3 | keyholders { | 3 | keyholders { |
4 | name: "D" | 4 | name: "D" |
5 | path: "Components/KeyHolders/keyHolderD" | 5 | path: "Components/KeyHolders/keyHolderD" |
6 | key: "d" | ||
6 | } | 7 | } |
diff --git a/data/maps/daedalus/rooms/D2 Room.txtpb b/data/maps/daedalus/rooms/D2 Room.txtpb index cfc645d..ec41086 100644 --- a/data/maps/daedalus/rooms/D2 Room.txtpb +++ b/data/maps/daedalus/rooms/D2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "D2 Room" | 1 | name: "D2 Room" |
2 | display_name: "Intense Room" | 2 | panel_display_name: "Intense Room" |
3 | letters { | 3 | letters { |
4 | key: "d" | 4 | key: "d" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/Dark Light Exit.txtpb b/data/maps/daedalus/rooms/Dark Light Exit.txtpb index 9c4d674..9b6ae28 100644 --- a/data/maps/daedalus/rooms/Dark Light Exit.txtpb +++ b/data/maps/daedalus/rooms/Dark Light Exit.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Dark Light Exit" | 1 | name: "Dark Light Exit" |
2 | display_name: "Outside Pumpkin" | 2 | panel_display_name: "Dark Light Room" |
3 | panels { | 3 | panels { |
4 | name: "GASKET" | 4 | name: "GASKET" |
5 | path: "Panels/Dark Light Room/dark_7" | 5 | path: "Panels/Dark Light Room/dark_7" |
diff --git a/data/maps/daedalus/rooms/Dark Light Room.txtpb b/data/maps/daedalus/rooms/Dark Light Room.txtpb index 4716a36..45526fd 100644 --- a/data/maps/daedalus/rooms/Dark Light Room.txtpb +++ b/data/maps/daedalus/rooms/Dark Light Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Dark Light Room" | 1 | name: "Dark Light Room" |
2 | display_name: "Outside Pumpkin" | 2 | panel_display_name: "Dark Light Room" |
3 | panels { | 3 | panels { |
4 | name: "COIN (1)" | 4 | name: "COIN (1)" |
5 | path: "Panels/Dark Light Room/dark_1" | 5 | path: "Panels/Dark Light Room/dark_1" |
diff --git a/data/maps/daedalus/rooms/Ending.txtpb b/data/maps/daedalus/rooms/Ending.txtpb index b8d91c0..6b7843c 100644 --- a/data/maps/daedalus/rooms/Ending.txtpb +++ b/data/maps/daedalus/rooms/Ending.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Ending" | 1 | name: "Ending" |
2 | display_name: "Castle" | 2 | panel_display_name: "Castle" |
3 | endings { | 3 | endings { |
4 | name: "ORANGE" | 4 | name: "ORANGE" |
5 | path: "Components/Triggers/orange_ending" | 5 | path: "Components/Triggers/orange_ending" |
diff --git a/data/maps/daedalus/rooms/Entry Shortcut.txtpb b/data/maps/daedalus/rooms/Entry Shortcut.txtpb index a94d84c..3c3abb7 100644 --- a/data/maps/daedalus/rooms/Entry Shortcut.txtpb +++ b/data/maps/daedalus/rooms/Entry Shortcut.txtpb | |||
@@ -1,13 +1,17 @@ | |||
1 | name: "Entry Shortcut" | 1 | name: "Entry Shortcut" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "WELCOME" | 4 | name: "WELCOME" |
5 | path: "Panels/Entry/entry_3" | 5 | path: "Panels/Entry/entry_3" |
6 | clue: "welcome" | 6 | clue: "welcome" |
7 | answer: "back" | 7 | answer: "back" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "WELCOME (Red/Blue)" | ||
9 | } | 10 | } |
10 | ports { | 11 | ports { |
11 | name: "ENTRY" | 12 | name: "ENTRY" |
13 | display_name: "Starting Room West Wall Middle Worldport" | ||
12 | path: "Components/Warps/Worldports/worldport4" | 14 | path: "Components/Warps/Worldports/worldport4" |
15 | destination { x: -21 y: 0 z: -4 } | ||
16 | rotation: 90 | ||
13 | } | 17 | } |
diff --git a/data/maps/daedalus/rooms/Eye Painting.txtpb b/data/maps/daedalus/rooms/Eye Painting.txtpb index d4c7cc6..4214811 100644 --- a/data/maps/daedalus/rooms/Eye Painting.txtpb +++ b/data/maps/daedalus/rooms/Eye Painting.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Painting" | 1 | name: "Eye Painting" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | panels { | 3 | panels { |
4 | name: "REVILED" | 4 | name: "REVILED" |
5 | path: "Panels/Entry/entry_5" | 5 | path: "Panels/Entry/entry_5" |
diff --git a/data/maps/daedalus/rooms/Eye Temple 1F Side.txtpb b/data/maps/daedalus/rooms/Eye Temple 1F Side.txtpb index 0e914d5..3eb1a6b 100644 --- a/data/maps/daedalus/rooms/Eye Temple 1F Side.txtpb +++ b/data/maps/daedalus/rooms/Eye Temple 1F Side.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Temple 1F Side" | 1 | name: "Eye Temple 1F Side" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | paintings { | 3 | paintings { |
4 | name: "EYEREDSIDE1" | 4 | name: "EYEREDSIDE1" |
5 | path: "Components/Paintings/Temple of the Eyes/eyeRedSide1" | 5 | path: "Components/Paintings/Temple of the Eyes/eyeRedSide1" |
diff --git a/data/maps/daedalus/rooms/Eye Temple 1F.txtpb b/data/maps/daedalus/rooms/Eye Temple 1F.txtpb index 9e8dc12..e15afc1 100644 --- a/data/maps/daedalus/rooms/Eye Temple 1F.txtpb +++ b/data/maps/daedalus/rooms/Eye Temple 1F.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Temple 1F" | 1 | name: "Eye Temple 1F" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | paintings { | 3 | paintings { |
4 | name: "EYEREDTOEXITMAIN2" | 4 | name: "EYEREDTOEXITMAIN2" |
5 | path: "Components/Paintings/Temple of the Eyes/eyeRedToExitMain2" | 5 | path: "Components/Paintings/Temple of the Eyes/eyeRedToExitMain2" |
diff --git a/data/maps/daedalus/rooms/Eye Temple 2F Side.txtpb b/data/maps/daedalus/rooms/Eye Temple 2F Side.txtpb index b78a413..7a1eb0a 100644 --- a/data/maps/daedalus/rooms/Eye Temple 2F Side.txtpb +++ b/data/maps/daedalus/rooms/Eye Temple 2F Side.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Temple 2F Side" | 1 | name: "Eye Temple 2F Side" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | paintings { | 3 | paintings { |
4 | name: "EYEREDTOEXITMAIN4" | 4 | name: "EYEREDTOEXITMAIN4" |
5 | path: "Components/Paintings/Temple of the Eyes/eyeRedToExitMain4" | 5 | path: "Components/Paintings/Temple of the Eyes/eyeRedToExitMain4" |
diff --git a/data/maps/daedalus/rooms/Eye Temple 2F.txtpb b/data/maps/daedalus/rooms/Eye Temple 2F.txtpb index b564e7e..d9e06d9 100644 --- a/data/maps/daedalus/rooms/Eye Temple 2F.txtpb +++ b/data/maps/daedalus/rooms/Eye Temple 2F.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Temple 2F" | 1 | name: "Eye Temple 2F" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | paintings { | 3 | paintings { |
4 | name: "EYEREDEXITTOP1" | 4 | name: "EYEREDEXITTOP1" |
5 | path: "Components/Paintings/Temple of the Eyes/eyeRedExitTop1" | 5 | path: "Components/Paintings/Temple of the Eyes/eyeRedExitTop1" |
diff --git a/data/maps/daedalus/rooms/Eye Temple Pillar 1.txtpb b/data/maps/daedalus/rooms/Eye Temple Pillar 1.txtpb index 7fccfb2..8243704 100644 --- a/data/maps/daedalus/rooms/Eye Temple Pillar 1.txtpb +++ b/data/maps/daedalus/rooms/Eye Temple Pillar 1.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Temple Pillar 1" | 1 | name: "Eye Temple Pillar 1" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | paintings { | 3 | paintings { |
4 | name: "EYEREDEXITPILLAR1" | 4 | name: "EYEREDEXITPILLAR1" |
5 | path: "Components/Paintings/Temple of the Eyes/eyeRedExitPillar1" | 5 | path: "Components/Paintings/Temple of the Eyes/eyeRedExitPillar1" |
diff --git a/data/maps/daedalus/rooms/Eye Temple Pillar 2.txtpb b/data/maps/daedalus/rooms/Eye Temple Pillar 2.txtpb index 88b468e..445649a 100644 --- a/data/maps/daedalus/rooms/Eye Temple Pillar 2.txtpb +++ b/data/maps/daedalus/rooms/Eye Temple Pillar 2.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Temple Pillar 2" | 1 | name: "Eye Temple Pillar 2" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | paintings { | 3 | paintings { |
4 | name: "EYEREDEXITPILLAR2" | 4 | name: "EYEREDEXITPILLAR2" |
5 | path: "Components/Paintings/Temple of the Eyes/eyeRedExitPillar2" | 5 | path: "Components/Paintings/Temple of the Eyes/eyeRedExitPillar2" |
diff --git a/data/maps/daedalus/rooms/F Keyholder.txtpb b/data/maps/daedalus/rooms/F Keyholder.txtpb index 8063161..b424c6a 100644 --- a/data/maps/daedalus/rooms/F Keyholder.txtpb +++ b/data/maps/daedalus/rooms/F Keyholder.txtpb | |||
@@ -1,6 +1,7 @@ | |||
1 | name: "F Keyholder" | 1 | name: "F Keyholder" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
3 | keyholders { | 3 | keyholders { |
4 | name: "F" | 4 | name: "F" |
5 | path: "Components/KeyHolders/keyHolderF" | 5 | path: "Components/KeyHolders/keyHolderF" |
6 | key: "f" | ||
6 | } | 7 | } |
diff --git a/data/maps/daedalus/rooms/F2 Prize.txtpb b/data/maps/daedalus/rooms/F2 Prize.txtpb index 7a062f1..ac95340 100644 --- a/data/maps/daedalus/rooms/F2 Prize.txtpb +++ b/data/maps/daedalus/rooms/F2 Prize.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "F2 Prize" | 1 | name: "F2 Prize" |
2 | display_name: "F2 Room" | 2 | panel_display_name: "F2 Room" |
3 | letters { | 3 | letters { |
4 | key: "f" | 4 | key: "f" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/F2 Room.txtpb b/data/maps/daedalus/rooms/F2 Room.txtpb index 49872ec..96b609e 100644 --- a/data/maps/daedalus/rooms/F2 Room.txtpb +++ b/data/maps/daedalus/rooms/F2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "F2 Room" | 1 | name: "F2 Room" |
2 | display_name: "F2 Room" | 2 | panel_display_name: "F2 Room" |
3 | panels { | 3 | panels { |
4 | name: "DULLS" | 4 | name: "DULLS" |
5 | path: "Panels/The Big F/o_1" | 5 | path: "Panels/The Big F/o_1" |
diff --git a/data/maps/daedalus/rooms/Flip Painting Destination.txtpb b/data/maps/daedalus/rooms/Flip Painting Destination.txtpb index 99ceb25..b3ec055 100644 --- a/data/maps/daedalus/rooms/Flip Painting Destination.txtpb +++ b/data/maps/daedalus/rooms/Flip Painting Destination.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Flip Painting Destination" | 1 | name: "Flip Painting Destination" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | paintings { | 3 | paintings { |
4 | name: "FLIP" | 4 | name: "FLIP" |
5 | path: "Components/Paintings/Group2/flip" | 5 | path: "Components/Paintings/Group2/flip" |
diff --git a/data/maps/daedalus/rooms/Flip Painting Hidden Panel.txtpb b/data/maps/daedalus/rooms/Flip Painting Hidden Panel.txtpb index 71d345e..d597114 100644 --- a/data/maps/daedalus/rooms/Flip Painting Hidden Panel.txtpb +++ b/data/maps/daedalus/rooms/Flip Painting Hidden Panel.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Flip Painting Hidden Panel" | 1 | name: "Flip Painting Hidden Panel" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "HIDDEN" | 4 | name: "HIDDEN" |
5 | path: "Panels/Halls/halls_2" | 5 | path: "Panels/Halls/halls_2" |
@@ -8,4 +8,5 @@ panels { | |||
8 | symbols: SUN | 8 | symbols: SUN |
9 | proxies { answer: "covert" path: "Panels/Halls/secret_proxy_1" } | 9 | proxies { answer: "covert" path: "Panels/Halls/secret_proxy_1" } |
10 | proxies { answer: "secret" path: "Panels/Halls/secret_proxy_2" } | 10 | proxies { answer: "secret" path: "Panels/Halls/secret_proxy_2" } |
11 | display_name: "HIDDEN (East)" | ||
11 | } | 12 | } |
diff --git a/data/maps/daedalus/rooms/Flip Painting.txtpb b/data/maps/daedalus/rooms/Flip Painting.txtpb index cea1273..6d9bf06 100644 --- a/data/maps/daedalus/rooms/Flip Painting.txtpb +++ b/data/maps/daedalus/rooms/Flip Painting.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Flip Painting" | 1 | name: "Flip Painting" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
3 | paintings { | 3 | paintings { |
4 | name: "FLIP2" | 4 | name: "FLIP2" |
5 | path: "Components/Paintings/Group2/flip2" | 5 | path: "Components/Paintings/Group2/flip2" |
diff --git a/data/maps/daedalus/rooms/Gallery Entrance.txtpb b/data/maps/daedalus/rooms/Gallery Entrance.txtpb index bed708f..3616bf7 100644 --- a/data/maps/daedalus/rooms/Gallery Entrance.txtpb +++ b/data/maps/daedalus/rooms/Gallery Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Gallery Entrance" | 1 | name: "Gallery Entrance" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | paintings { | 3 | paintings { |
4 | name: "GALLERY" | 4 | name: "GALLERY" |
5 | path: "Components/Warps/eyeWorldport" | 5 | path: "Components/Warps/eyeWorldport" |
diff --git a/data/maps/daedalus/rooms/Globe Room.txtpb b/data/maps/daedalus/rooms/Globe Room.txtpb index 49488f0..b090ac6 100644 --- a/data/maps/daedalus/rooms/Globe Room.txtpb +++ b/data/maps/daedalus/rooms/Globe Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Globe Room" | 1 | name: "Globe Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "NORTH" | 4 | name: "NORTH" |
5 | path: "Panels/Halls/directions_1" | 5 | path: "Panels/Halls/directions_1" |
diff --git a/data/maps/daedalus/rooms/Godot Room.txtpb b/data/maps/daedalus/rooms/Godot Room.txtpb index a9c89ec..92cf009 100644 --- a/data/maps/daedalus/rooms/Godot Room.txtpb +++ b/data/maps/daedalus/rooms/Godot Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Godot Room" | 1 | name: "Godot Room" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "MOTORCYCLE" | 4 | name: "MOTORCYCLE" |
5 | path: "Panels/Southwest Room/sw_1" | 5 | path: "Panels/Southwest Room/sw_1" |
diff --git a/data/maps/daedalus/rooms/Gray Color Backside.txtpb b/data/maps/daedalus/rooms/Gray Color Backside.txtpb index 8afb97e..7d90b7f 100644 --- a/data/maps/daedalus/rooms/Gray Color Backside.txtpb +++ b/data/maps/daedalus/rooms/Gray Color Backside.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Gray Color Backside" | 1 | name: "Gray Color Backside" |
2 | display_name: "Outside Pumpkin" | 2 | panel_display_name: "Outside Pumpkin" |
3 | panels { | 3 | panels { |
4 | name: "ORANGE" | 4 | name: "ORANGE" |
5 | path: "Panels/Hexes/lightgreen_1" | 5 | path: "Panels/Hexes/lightgreen_1" |
diff --git a/data/maps/daedalus/rooms/Gray Color Door.txtpb b/data/maps/daedalus/rooms/Gray Color Door.txtpb index f8298ff..db46389 100644 --- a/data/maps/daedalus/rooms/Gray Color Door.txtpb +++ b/data/maps/daedalus/rooms/Gray Color Door.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Gray Color Door" | 1 | name: "Gray Color Door" |
2 | display_name: "Outside Pumpkin" | 2 | panel_display_name: "Outside Pumpkin" |
3 | panels { | 3 | panels { |
4 | name: "PATCH" | 4 | name: "PATCH" |
5 | path: "Panels/Halls/halls_3" | 5 | path: "Panels/Halls/halls_3" |
diff --git a/data/maps/daedalus/rooms/Green Color Door.txtpb b/data/maps/daedalus/rooms/Green Color Door.txtpb index 275a3fa..fe52c09 100644 --- a/data/maps/daedalus/rooms/Green Color Door.txtpb +++ b/data/maps/daedalus/rooms/Green Color Door.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Green Color Door" | 1 | name: "Green Color Door" |
2 | display_name: "Outside Pumpkin" | 2 | panel_display_name: "Outside Pumpkin" |
3 | panels { | 3 | panels { |
4 | name: "OLD (1)" | 4 | name: "OLD (1)" |
5 | path: "Panels/Halls/halls_20" | 5 | path: "Panels/Halls/halls_20" |
diff --git a/data/maps/daedalus/rooms/Green Room.txtpb b/data/maps/daedalus/rooms/Green Room.txtpb index 3b1cde1..d93ee4a 100644 --- a/data/maps/daedalus/rooms/Green Room.txtpb +++ b/data/maps/daedalus/rooms/Green Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Green Room" | 1 | name: "Green Room" |
2 | display_name: "Green Room" | 2 | panel_display_name: "Green Room" |
3 | panels { | 3 | panels { |
4 | name: "TIMESCALE" | 4 | name: "TIMESCALE" |
5 | path: "Panels/Green Room/panel_1" | 5 | path: "Panels/Green Room/panel_1" |
diff --git a/data/maps/daedalus/rooms/Green Smiley.txtpb b/data/maps/daedalus/rooms/Green Smiley.txtpb index 7827f45..18f067f 100644 --- a/data/maps/daedalus/rooms/Green Smiley.txtpb +++ b/data/maps/daedalus/rooms/Green Smiley.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Green Smiley" | 1 | name: "Green Smiley" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "SMILE" | 4 | name: "SMILE" |
5 | path: "Panels/Smiley Rooms/green" | 5 | path: "Panels/Smiley Rooms/green" |
diff --git a/data/maps/daedalus/rooms/Hedges Tower.txtpb b/data/maps/daedalus/rooms/Hedges Tower.txtpb index 97fe935..3b88cd7 100644 --- a/data/maps/daedalus/rooms/Hedges Tower.txtpb +++ b/data/maps/daedalus/rooms/Hedges Tower.txtpb | |||
@@ -1,6 +1,8 @@ | |||
1 | name: "Hedges Tower" | 1 | name: "Hedges Tower" |
2 | display_name: "Hedges" | 2 | panel_display_name: "Hedges" |
3 | ports { | 3 | ports { |
4 | name: "TENACIOUS" | 4 | name: "TENACIOUS" |
5 | display_name: "Hedge Maze Tower" | ||
5 | path: "Components/Warps/Worldports/worldport13" | 6 | path: "Components/Warps/Worldports/worldport13" |
7 | no_shuffle: true | ||
6 | } | 8 | } |
diff --git a/data/maps/daedalus/rooms/Hedges.txtpb b/data/maps/daedalus/rooms/Hedges.txtpb index e467f7c..69c66a9 100644 --- a/data/maps/daedalus/rooms/Hedges.txtpb +++ b/data/maps/daedalus/rooms/Hedges.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Hedges" | 1 | name: "Hedges" |
2 | display_name: "Hedges" | 2 | panel_display_name: "Hedges" |
3 | panels { | 3 | panels { |
4 | name: "SOLVE" | 4 | name: "SOLVE" |
5 | path: "Panels/Tower Maze/maze_1" | 5 | path: "Panels/Tower Maze/maze_1" |
diff --git a/data/maps/daedalus/rooms/Hotel.txtpb b/data/maps/daedalus/rooms/Hotel.txtpb index 9834c3f..d2a05db 100644 --- a/data/maps/daedalus/rooms/Hotel.txtpb +++ b/data/maps/daedalus/rooms/Hotel.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Hotel" | 1 | name: "Hotel" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | # TODO: Something has to be changed in-game so that the puzzles don't disappear | 3 | # TODO: Something has to be changed in-game so that the puzzles don't disappear |
4 | # and thus cause them to become unsolvable. | 4 | # and thus cause them to become unsolvable. |
5 | panels { | 5 | panels { |
diff --git a/data/maps/daedalus/rooms/House Entrance.txtpb b/data/maps/daedalus/rooms/House Entrance.txtpb index 99bf58e..06dcb3f 100644 --- a/data/maps/daedalus/rooms/House Entrance.txtpb +++ b/data/maps/daedalus/rooms/House Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "House Entrance" | 1 | name: "House Entrance" |
2 | display_name: "Maze" | 2 | panel_display_name: "Maze" |
3 | panels { | 3 | panels { |
4 | name: "ADULT" | 4 | name: "ADULT" |
5 | path: "Panels/Entry/entry_6" | 5 | path: "Panels/Entry/entry_6" |
diff --git a/data/maps/daedalus/rooms/House.txtpb b/data/maps/daedalus/rooms/House.txtpb index fcf938d..3cfd4d8 100644 --- a/data/maps/daedalus/rooms/House.txtpb +++ b/data/maps/daedalus/rooms/House.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "House" | 1 | name: "House" |
2 | display_name: "House" | 2 | panel_display_name: "House" |
3 | panels { | 3 | panels { |
4 | name: "GOAT" | 4 | name: "GOAT" |
5 | path: "Panels/Theos House/panel_1" | 5 | path: "Panels/Theos House/panel_1" |
diff --git a/data/maps/daedalus/rooms/I2 Room.txtpb b/data/maps/daedalus/rooms/I2 Room.txtpb index ac9e7d5..2735a3b 100644 --- a/data/maps/daedalus/rooms/I2 Room.txtpb +++ b/data/maps/daedalus/rooms/I2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "I2 Room" | 1 | name: "I2 Room" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | letters { | 3 | letters { |
4 | key: "i" | 4 | key: "i" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/Intense Room.txtpb b/data/maps/daedalus/rooms/Intense Room.txtpb index ce1cd08..30780f9 100644 --- a/data/maps/daedalus/rooms/Intense Room.txtpb +++ b/data/maps/daedalus/rooms/Intense Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Intense Room" | 1 | name: "Intense Room" |
2 | display_name: "Intense Room" | 2 | panel_display_name: "Intense Room" |
3 | panels { | 3 | panels { |
4 | name: "BRILLIANT" | 4 | name: "BRILLIANT" |
5 | path: "Panels/Intense Room/intense_1" | 5 | path: "Panels/Intense Room/intense_1" |
diff --git a/data/maps/daedalus/rooms/J2 Room.txtpb b/data/maps/daedalus/rooms/J2 Room.txtpb index 48ae0c2..20211d9 100644 --- a/data/maps/daedalus/rooms/J2 Room.txtpb +++ b/data/maps/daedalus/rooms/J2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "J2 Room" | 1 | name: "J2 Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | letters { | 3 | letters { |
4 | key: "j" | 4 | key: "j" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/J2 Vestibule.txtpb b/data/maps/daedalus/rooms/J2 Vestibule.txtpb index a7f786d..57f5a4f 100644 --- a/data/maps/daedalus/rooms/J2 Vestibule.txtpb +++ b/data/maps/daedalus/rooms/J2 Vestibule.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "J2 Vestibule" | 1 | name: "J2 Vestibule" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "COLORFUL" | 4 | name: "COLORFUL" |
5 | path: "Panels/Entry/hotel_entry2" | 5 | path: "Panels/Entry/hotel_entry2" |
6 | clue: "colorful" | 6 | clue: "colorful" |
7 | answer: "vivid" | 7 | answer: "vivid" |
8 | symbols: SUN | 8 | symbols: SUN |
9 | display_name: "COLORFUL (2)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Magic Room.txtpb b/data/maps/daedalus/rooms/Magic Room.txtpb index c16dca6..66c63ca 100644 --- a/data/maps/daedalus/rooms/Magic Room.txtpb +++ b/data/maps/daedalus/rooms/Magic Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Magic Room" | 1 | name: "Magic Room" |
2 | display_name: "Maze" | 2 | panel_display_name: "Maze" |
3 | panels { | 3 | panels { |
4 | name: "1" | 4 | name: "1" |
5 | path: "Panels/Magic Maze/maze_1" | 5 | path: "Panels/Magic Maze/maze_1" |
diff --git a/data/maps/daedalus/rooms/Maze Paintings Area.txtpb b/data/maps/daedalus/rooms/Maze Paintings Area.txtpb index 42a45c5..3b070f7 100644 --- a/data/maps/daedalus/rooms/Maze Paintings Area.txtpb +++ b/data/maps/daedalus/rooms/Maze Paintings Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Paintings Area" | 1 | name: "Maze Paintings Area" |
2 | display_name: "Maze" | 2 | panel_display_name: "Maze" |
3 | panels { | 3 | panels { |
4 | name: "Paintings" | 4 | name: "Paintings" |
5 | path: "Panels/Halls/halls_28" | 5 | path: "Panels/Halls/halls_28" |
diff --git a/data/maps/daedalus/rooms/Maze.txtpb b/data/maps/daedalus/rooms/Maze.txtpb index 0329465..a2bb5a3 100644 --- a/data/maps/daedalus/rooms/Maze.txtpb +++ b/data/maps/daedalus/rooms/Maze.txtpb | |||
@@ -1,2 +1,2 @@ | |||
1 | name: "Maze" | 1 | name: "Maze" |
2 | display_name: "Maze" | 2 | panel_display_name: "Maze" |
diff --git a/data/maps/daedalus/rooms/Moat.txtpb b/data/maps/daedalus/rooms/Moat.txtpb index f834609..7bdb040 100644 --- a/data/maps/daedalus/rooms/Moat.txtpb +++ b/data/maps/daedalus/rooms/Moat.txtpb | |||
@@ -1,10 +1,13 @@ | |||
1 | name: "Moat" | 1 | name: "Moat" |
2 | display_name: "East Area" | 2 | panel_display_name: "East Area" |
3 | paintings { | 3 | paintings { |
4 | name: "CASTLE" | 4 | name: "CASTLE" |
5 | path: "Components/Paintings/Group1/castle" | 5 | path: "Components/Paintings/Group1/castle" |
6 | } | 6 | } |
7 | ports { | 7 | ports { |
8 | name: "HIVE" | 8 | name: "HIVE" |
9 | display_name: "Moat Worldport" | ||
9 | path: "Components/Warps/Worldports/worldport9" | 10 | path: "Components/Warps/Worldports/worldport9" |
11 | destination { x: 64 y: 1 z: 24.5 } | ||
12 | rotation: 0 | ||
10 | } | 13 | } |
diff --git a/data/maps/daedalus/rooms/North Castle Area.txtpb b/data/maps/daedalus/rooms/North Castle Area.txtpb index 6d177c9..a549245 100644 --- a/data/maps/daedalus/rooms/North Castle Area.txtpb +++ b/data/maps/daedalus/rooms/North Castle Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "North Castle Area" | 1 | name: "North Castle Area" |
2 | display_name: "North Area" | 2 | panel_display_name: "North Area" |
3 | panels { | 3 | panels { |
4 | name: "A" | 4 | name: "A" |
5 | path: "Panels/Castle Entrance/castle_north_helper" | 5 | path: "Panels/Castle Entrance/castle_north_helper" |
diff --git a/data/maps/daedalus/rooms/Number Paintings Area.txtpb b/data/maps/daedalus/rooms/Number Paintings Area.txtpb index fb01075..c89bfcf 100644 --- a/data/maps/daedalus/rooms/Number Paintings Area.txtpb +++ b/data/maps/daedalus/rooms/Number Paintings Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Number Paintings Area" | 1 | name: "Number Paintings Area" |
2 | display_name: "Northwest Area" | 2 | panel_display_name: "Northwest Area" |
3 | panels { | 3 | panels { |
4 | name: "GOING" | 4 | name: "GOING" |
5 | path: "Panels/Entry/g_hedge_1" | 5 | path: "Panels/Entry/g_hedge_1" |
@@ -17,6 +17,7 @@ panels { | |||
17 | keyholders { | 17 | keyholders { |
18 | name: "G" | 18 | name: "G" |
19 | path: "Components/KeyHolders/keyHolderG" | 19 | path: "Components/KeyHolders/keyHolderG" |
20 | key: "g" | ||
20 | } | 21 | } |
21 | paintings { | 22 | paintings { |
22 | name: "WON" | 23 | name: "WON" |
diff --git a/data/maps/daedalus/rooms/Nursery.txtpb b/data/maps/daedalus/rooms/Nursery.txtpb index cd1b5e3..c73072d 100644 --- a/data/maps/daedalus/rooms/Nursery.txtpb +++ b/data/maps/daedalus/rooms/Nursery.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Nursery" | 1 | name: "Nursery" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "Paintings" | 4 | name: "Paintings" |
5 | path: "Panels/Entry/entry_2" | 5 | path: "Panels/Entry/entry_2" |
@@ -12,6 +12,7 @@ panels { | |||
12 | path: "Panels/Halls/halls_17" | 12 | path: "Panels/Halls/halls_17" |
13 | clue: "" | 13 | clue: "" |
14 | answer: "welcome" | 14 | answer: "welcome" |
15 | display_name: "Nursery Behind" | ||
15 | } | 16 | } |
16 | paintings { | 17 | paintings { |
17 | name: "ARE" | 18 | name: "ARE" |
diff --git a/data/maps/daedalus/rooms/O2 Prize.txtpb b/data/maps/daedalus/rooms/O2 Prize.txtpb index 0a81954..a810182 100644 --- a/data/maps/daedalus/rooms/O2 Prize.txtpb +++ b/data/maps/daedalus/rooms/O2 Prize.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "O2 Prize" | 1 | name: "O2 Prize" |
2 | display_name: "O2 Room" | 2 | panel_display_name: "O2 Room" |
3 | letters { | 3 | letters { |
4 | key: "o" | 4 | key: "o" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/O2 Room.txtpb b/data/maps/daedalus/rooms/O2 Room.txtpb index 7ea3ce2..b1a839f 100644 --- a/data/maps/daedalus/rooms/O2 Room.txtpb +++ b/data/maps/daedalus/rooms/O2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "O2 Room" | 1 | name: "O2 Room" |
2 | display_name: "O2 Room" | 2 | panel_display_name: "O2 Room" |
3 | panels { | 3 | panels { |
4 | name: "LISTEN" | 4 | name: "LISTEN" |
5 | path: "Panels/The Big O/o_1" | 5 | path: "Panels/The Big O/o_1" |
diff --git a/data/maps/daedalus/rooms/Orange Room Hallway.txtpb b/data/maps/daedalus/rooms/Orange Room Hallway.txtpb new file mode 100644 index 0000000..915e698 --- /dev/null +++ b/data/maps/daedalus/rooms/Orange Room Hallway.txtpb | |||
@@ -0,0 +1,4 @@ | |||
1 | name: "Orange Room Hallway" | ||
2 | panel_display_name: "Orange Room" | ||
3 | # This has the same door at both sides, and mainly just connects Z2 Room and | ||
4 | # Orange Room. It's separate because you can also get here from the Roof. | ||
diff --git a/data/maps/daedalus/rooms/Orange Room.txtpb b/data/maps/daedalus/rooms/Orange Room.txtpb index ba1bedd..08a0ff2 100644 --- a/data/maps/daedalus/rooms/Orange Room.txtpb +++ b/data/maps/daedalus/rooms/Orange Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Orange Room" | 1 | name: "Orange Room" |
2 | display_name: "East Area" | 2 | panel_display_name: "Orange Room" |
3 | panels { | 3 | panels { |
4 | name: "FRANCE" | 4 | name: "FRANCE" |
5 | path: "Panels/Orange Room/panel_1" | 5 | path: "Panels/Orange Room/panel_1" |
diff --git a/data/maps/daedalus/rooms/Outside Book Room.txtpb b/data/maps/daedalus/rooms/Outside Book Room.txtpb index a8e647f..1592217 100644 --- a/data/maps/daedalus/rooms/Outside Book Room.txtpb +++ b/data/maps/daedalus/rooms/Outside Book Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Book Room" | 1 | name: "Outside Book Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | # This is behind a teal wall. | 3 | # This is behind a teal wall. |
4 | panels { | 4 | panels { |
5 | name: "TEAL" | 5 | name: "TEAL" |
diff --git a/data/maps/daedalus/rooms/Outside Eye Temple.txtpb b/data/maps/daedalus/rooms/Outside Eye Temple.txtpb index c7d35fd..85a9c19 100644 --- a/data/maps/daedalus/rooms/Outside Eye Temple.txtpb +++ b/data/maps/daedalus/rooms/Outside Eye Temple.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Eye Temple" | 1 | name: "Outside Eye Temple" |
2 | display_name: "Temple of the Eyes" | 2 | panel_display_name: "Temple of the Eyes" |
3 | panels { | 3 | panels { |
4 | name: "Entrance" | 4 | name: "Entrance" |
5 | path: "Panels/Halls/eye_temple_entry_1" | 5 | path: "Panels/Halls/eye_temple_entry_1" |
diff --git a/data/maps/daedalus/rooms/Outside Hedges.txtpb b/data/maps/daedalus/rooms/Outside Hedges.txtpb index b157beb..fc765d9 100644 --- a/data/maps/daedalus/rooms/Outside Hedges.txtpb +++ b/data/maps/daedalus/rooms/Outside Hedges.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Hedges" | 1 | name: "Outside Hedges" |
2 | display_name: "Hedges" | 2 | panel_display_name: "Hedges" |
3 | panels { | 3 | panels { |
4 | name: "GOURD (1)" | 4 | name: "GOURD (1)" |
5 | path: "Panels/Halls/halls_11" | 5 | path: "Panels/Halls/halls_11" |
@@ -76,5 +76,8 @@ paintings { | |||
76 | } | 76 | } |
77 | ports { | 77 | ports { |
78 | name: "REVITALIZED" | 78 | name: "REVITALIZED" |
79 | display_name: "Near Hedges Plum Hallway" | ||
79 | path: "Components/Warps/Worldports/worldport7" | 80 | path: "Components/Warps/Worldports/worldport7" |
81 | destination { x: 45 y: 0 z: 94 } | ||
82 | rotation: 270 | ||
80 | } | 83 | } |
diff --git a/data/maps/daedalus/rooms/Outside Hotel.txtpb b/data/maps/daedalus/rooms/Outside Hotel.txtpb index 62b5a41..7766c7d 100644 --- a/data/maps/daedalus/rooms/Outside Hotel.txtpb +++ b/data/maps/daedalus/rooms/Outside Hotel.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Outside Hotel" | 1 | name: "Outside Hotel" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "COLORFUL" | 4 | name: "COLORFUL" |
5 | path: "Panels/Entry/hotel_entry" | 5 | path: "Panels/Entry/hotel_entry" |
6 | clue: "colorful" | 6 | clue: "colorful" |
7 | answer: "bright" | 7 | answer: "bright" |
8 | symbols: SUN | 8 | symbols: SUN |
9 | display_name: "COLORFUL (1)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Outside House.txtpb b/data/maps/daedalus/rooms/Outside House.txtpb index 8a5e911..fed9dda 100644 --- a/data/maps/daedalus/rooms/Outside House.txtpb +++ b/data/maps/daedalus/rooms/Outside House.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside House" | 1 | name: "Outside House" |
2 | display_name: "Maze" | 2 | panel_display_name: "Maze" |
3 | panels { | 3 | panels { |
4 | name: "WHISPER" | 4 | name: "WHISPER" |
5 | path: "Panels/Beehalls/beehalls_1" | 5 | path: "Panels/Beehalls/beehalls_1" |
@@ -75,6 +75,7 @@ panels { | |||
75 | keyholders { | 75 | keyholders { |
76 | name: "H" | 76 | name: "H" |
77 | path: "Components/KeyHolders/keyHolderH" | 77 | path: "Components/KeyHolders/keyHolderH" |
78 | key: "h" | ||
78 | } | 79 | } |
79 | paintings { | 80 | paintings { |
80 | name: "CASTLE2" | 81 | name: "CASTLE2" |
diff --git a/data/maps/daedalus/rooms/Outside Magic Room.txtpb b/data/maps/daedalus/rooms/Outside Magic Room.txtpb index ef45563..2aa7848 100644 --- a/data/maps/daedalus/rooms/Outside Magic Room.txtpb +++ b/data/maps/daedalus/rooms/Outside Magic Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Magic Room" | 1 | name: "Outside Magic Room" |
2 | display_name: "Maze" | 2 | panel_display_name: "Maze" |
3 | panels { | 3 | panels { |
4 | name: "WIZARD" | 4 | name: "WIZARD" |
5 | path: "Panels/Magic Maze/maze_entry_1" | 5 | path: "Panels/Magic Maze/maze_entry_1" |
diff --git a/data/maps/daedalus/rooms/Outside Orange Room.txtpb b/data/maps/daedalus/rooms/Outside Orange Room.txtpb index a50db78..55efe34 100644 --- a/data/maps/daedalus/rooms/Outside Orange Room.txtpb +++ b/data/maps/daedalus/rooms/Outside Orange Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Orange Room" | 1 | name: "Outside Orange Room" |
2 | display_name: "East Area" | 2 | panel_display_name: "East Area" |
3 | panels { | 3 | panels { |
4 | name: "SMILE" | 4 | name: "SMILE" |
5 | path: "Panels/Smiley Rooms/orange" | 5 | path: "Panels/Smiley Rooms/orange" |
diff --git a/data/maps/daedalus/rooms/Outside Pyramid.txtpb b/data/maps/daedalus/rooms/Outside Pyramid.txtpb index fd7ef21..247d3a8 100644 --- a/data/maps/daedalus/rooms/Outside Pyramid.txtpb +++ b/data/maps/daedalus/rooms/Outside Pyramid.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Pyramid" | 1 | name: "Outside Pyramid" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "PEER" | 4 | name: "PEER" |
5 | path: "Panels/Pyramid/pyramid_entry" | 5 | path: "Panels/Pyramid/pyramid_entry" |
diff --git a/data/maps/daedalus/rooms/Outside Red Room.txtpb b/data/maps/daedalus/rooms/Outside Red Room.txtpb index e5be363..307633b 100644 --- a/data/maps/daedalus/rooms/Outside Red Room.txtpb +++ b/data/maps/daedalus/rooms/Outside Red Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Red Room" | 1 | name: "Outside Red Room" |
2 | display_name: "Red Room" | 2 | panel_display_name: "Red Room" |
3 | panels { | 3 | panels { |
4 | name: "ROCK" | 4 | name: "ROCK" |
5 | path: "Panels/Red Room/red_entry" | 5 | path: "Panels/Red Room/red_entry" |
diff --git a/data/maps/daedalus/rooms/Outside Salt Room.txtpb b/data/maps/daedalus/rooms/Outside Salt Room.txtpb index 3d374f8..f5c4833 100644 --- a/data/maps/daedalus/rooms/Outside Salt Room.txtpb +++ b/data/maps/daedalus/rooms/Outside Salt Room.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Outside Salt Room" | 1 | name: "Outside Salt Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "Colors" | 4 | name: "Colors" |
5 | path: "Panels/Color Reading/cr_1" | 5 | path: "Panels/Color Reading/cr_1" |
6 | clue: "" | 6 | clue: "" |
7 | answer: "rob" | 7 | answer: "rob" |
8 | symbols: LINGO | 8 | symbols: LINGO |
9 | display_name: "Colors (White)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Outside Snake Room.txtpb b/data/maps/daedalus/rooms/Outside Snake Room.txtpb index b65ee77..31f3281 100644 --- a/data/maps/daedalus/rooms/Outside Snake Room.txtpb +++ b/data/maps/daedalus/rooms/Outside Snake Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Snake Room" | 1 | name: "Outside Snake Room" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
3 | panels { | 3 | panels { |
4 | name: "TONGUE" | 4 | name: "TONGUE" |
5 | path: "Panels/Pairs Room/pairs_7" | 5 | path: "Panels/Pairs Room/pairs_7" |
diff --git a/data/maps/daedalus/rooms/Pains Room.txtpb b/data/maps/daedalus/rooms/Pains Room.txtpb index cc0c7bb..d5c9c4a 100644 --- a/data/maps/daedalus/rooms/Pains Room.txtpb +++ b/data/maps/daedalus/rooms/Pains Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pains Room" | 1 | name: "Pains Room" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "MOO" | 4 | name: "MOO" |
5 | path: "Panels/Gold/gold_1" | 5 | path: "Panels/Gold/gold_1" |
diff --git a/data/maps/daedalus/rooms/Pairs Room.txtpb b/data/maps/daedalus/rooms/Pairs Room.txtpb index ca5e885..ba484bf 100644 --- a/data/maps/daedalus/rooms/Pairs Room.txtpb +++ b/data/maps/daedalus/rooms/Pairs Room.txtpb | |||
@@ -1,2 +1,2 @@ | |||
1 | name: "Pairs Room" | 1 | name: "Pairs Room" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
diff --git a/data/maps/daedalus/rooms/Pepper Room.txtpb b/data/maps/daedalus/rooms/Pepper Room.txtpb index 074869f..104efa7 100644 --- a/data/maps/daedalus/rooms/Pepper Room.txtpb +++ b/data/maps/daedalus/rooms/Pepper Room.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Pepper Room" | 1 | name: "Pepper Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "SEASONING" | 4 | name: "SEASONING" |
5 | path: "Panels/Color Reading/cr_4" | 5 | path: "Panels/Color Reading/cr_4" |
6 | clue: "seasoning" | 6 | clue: "seasoning" |
7 | answer: "pepper" | 7 | answer: "pepper" |
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | display_name: "SEASONING (Black)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Plum Room.txtpb b/data/maps/daedalus/rooms/Plum Room.txtpb index 90243a4..36185b9 100644 --- a/data/maps/daedalus/rooms/Plum Room.txtpb +++ b/data/maps/daedalus/rooms/Plum Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Plum Room" | 1 | name: "Plum Room" |
2 | display_name: "Plum Room" | 2 | panel_display_name: "Plum Room" |
3 | panels { | 3 | panels { |
4 | name: "GOD" | 4 | name: "GOD" |
5 | path: "Panels/Plum Room/plum_1" | 5 | path: "Panels/Plum Room/plum_1" |
diff --git a/data/maps/daedalus/rooms/Post Orange Smiley Three Way.txtpb b/data/maps/daedalus/rooms/Post Orange Smiley Three Way.txtpb index 868ff86..63463f0 100644 --- a/data/maps/daedalus/rooms/Post Orange Smiley Three Way.txtpb +++ b/data/maps/daedalus/rooms/Post Orange Smiley Three Way.txtpb | |||
@@ -1,2 +1,2 @@ | |||
1 | name: "Post Orange Smiley Three Way" | 1 | name: "Post Orange Smiley Three Way" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
diff --git a/data/maps/daedalus/rooms/Pumpkin Entrance.txtpb b/data/maps/daedalus/rooms/Pumpkin Entrance.txtpb index c7fc3d1..a746746 100644 --- a/data/maps/daedalus/rooms/Pumpkin Entrance.txtpb +++ b/data/maps/daedalus/rooms/Pumpkin Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pumpkin Entrance" | 1 | name: "Pumpkin Entrance" |
2 | display_name: "East Area" | 2 | panel_display_name: "East Area" |
3 | panels { | 3 | panels { |
4 | name: "JACK" | 4 | name: "JACK" |
5 | path: "Panels/Pumpkin Room/pumpkin_2" | 5 | path: "Panels/Pumpkin Room/pumpkin_2" |
diff --git a/data/maps/daedalus/rooms/Pumpkin Room.txtpb b/data/maps/daedalus/rooms/Pumpkin Room.txtpb index 345b372..e40693b 100644 --- a/data/maps/daedalus/rooms/Pumpkin Room.txtpb +++ b/data/maps/daedalus/rooms/Pumpkin Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pumpkin Room" | 1 | name: "Pumpkin Room" |
2 | display_name: "East Area" | 2 | panel_display_name: "East Area" |
3 | panels { | 3 | panels { |
4 | name: "BONE" | 4 | name: "BONE" |
5 | path: "Panels/Pumpkin Room/pumpkin_3" | 5 | path: "Panels/Pumpkin Room/pumpkin_3" |
diff --git a/data/maps/daedalus/rooms/Purple Hallway From Great.txtpb b/data/maps/daedalus/rooms/Purple Hallway From Great.txtpb index fef68e9..73f8391 100644 --- a/data/maps/daedalus/rooms/Purple Hallway From Great.txtpb +++ b/data/maps/daedalus/rooms/Purple Hallway From Great.txtpb | |||
@@ -1,6 +1,9 @@ | |||
1 | name: "Purple Hallway From Great" | 1 | name: "Purple Hallway From Great" |
2 | display_name: "South Area" | 2 | panel_display_name: "South Area" |
3 | ports { | 3 | ports { |
4 | name: "GREAT" | 4 | name: "GREAT" |
5 | display_name: "Near Sweet Purple Hallway" | ||
5 | path: "Components/Warps/Worldports/worldport17" | 6 | path: "Components/Warps/Worldports/worldport17" |
7 | destination { x: -24 y: 0 z: 61 } | ||
8 | rotation: 270 | ||
6 | } | 9 | } |
diff --git a/data/maps/daedalus/rooms/Purple NW Vestibule.txtpb b/data/maps/daedalus/rooms/Purple NW Vestibule.txtpb index 6aedce9..0244e6c 100644 --- a/data/maps/daedalus/rooms/Purple NW Vestibule.txtpb +++ b/data/maps/daedalus/rooms/Purple NW Vestibule.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Purple NW Vestibule" | 1 | name: "Purple NW Vestibule" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "MESSAGES" | 4 | name: "MESSAGES" |
5 | path: "Panels/Purple Exterior/purple_8" | 5 | path: "Panels/Purple Exterior/purple_8" |
diff --git a/data/maps/daedalus/rooms/Purple Room East.txtpb b/data/maps/daedalus/rooms/Purple Room East.txtpb index a866868..6fa31bd 100644 --- a/data/maps/daedalus/rooms/Purple Room East.txtpb +++ b/data/maps/daedalus/rooms/Purple Room East.txtpb | |||
@@ -1,2 +1,2 @@ | |||
1 | name: "Purple Room East" | 1 | name: "Purple Room East" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
diff --git a/data/maps/daedalus/rooms/Purple Room South.txtpb b/data/maps/daedalus/rooms/Purple Room South.txtpb index b6a25e6..68a6264 100644 --- a/data/maps/daedalus/rooms/Purple Room South.txtpb +++ b/data/maps/daedalus/rooms/Purple Room South.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Purple Room South" | 1 | name: "Purple Room South" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "LITTLE" | 4 | name: "LITTLE" |
5 | path: "Panels/Halls/hof_1" | 5 | path: "Panels/Halls/hof_1" |
diff --git a/data/maps/daedalus/rooms/Purple Room West.txtpb b/data/maps/daedalus/rooms/Purple Room West.txtpb index 8c20399..9971cd2 100644 --- a/data/maps/daedalus/rooms/Purple Room West.txtpb +++ b/data/maps/daedalus/rooms/Purple Room West.txtpb | |||
@@ -1,2 +1,2 @@ | |||
1 | name: "Purple Room West" | 1 | name: "Purple Room West" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
diff --git a/data/maps/daedalus/rooms/Purple Room.txtpb b/data/maps/daedalus/rooms/Purple Room.txtpb index 612f8d8..f34d26c 100644 --- a/data/maps/daedalus/rooms/Purple Room.txtpb +++ b/data/maps/daedalus/rooms/Purple Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Purple Room" | 1 | name: "Purple Room" |
2 | display_name: "Central" | 2 | panel_display_name: "Purple Room" |
3 | panels { | 3 | panels { |
4 | name: "HOIST" | 4 | name: "HOIST" |
5 | path: "Panels/Purple Room/purple_1" | 5 | path: "Panels/Purple Room/purple_1" |
diff --git a/data/maps/daedalus/rooms/Purple SE Vestibule.txtpb b/data/maps/daedalus/rooms/Purple SE Vestibule.txtpb index 5f34151..be86861 100644 --- a/data/maps/daedalus/rooms/Purple SE Vestibule.txtpb +++ b/data/maps/daedalus/rooms/Purple SE Vestibule.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Purple SE Vestibule" | 1 | name: "Purple SE Vestibule" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "RUN" | 4 | name: "RUN" |
5 | path: "Panels/Purple Exterior/purple_1" | 5 | path: "Panels/Purple Exterior/purple_1" |
diff --git a/data/maps/daedalus/rooms/Purple SW Vestibule.txtpb b/data/maps/daedalus/rooms/Purple SW Vestibule.txtpb index 05acc75..fbc5fff 100644 --- a/data/maps/daedalus/rooms/Purple SW Vestibule.txtpb +++ b/data/maps/daedalus/rooms/Purple SW Vestibule.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Purple SW Vestibule" | 1 | name: "Purple SW Vestibule" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "LETTERS" | 4 | name: "LETTERS" |
5 | path: "Panels/Purple Exterior/purple_11" | 5 | path: "Panels/Purple Exterior/purple_11" |
diff --git a/data/maps/daedalus/rooms/Purple Smiley.txtpb b/data/maps/daedalus/rooms/Purple Smiley.txtpb index 515336f..5f6c989 100644 --- a/data/maps/daedalus/rooms/Purple Smiley.txtpb +++ b/data/maps/daedalus/rooms/Purple Smiley.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Purple Smiley" | 1 | name: "Purple Smiley" |
2 | display_name: "Northeast Area" | 2 | panel_display_name: "Northeast Area" |
3 | panels { | 3 | panels { |
4 | name: "SMILE" | 4 | name: "SMILE" |
5 | path: "Panels/Smiley Rooms/purple" | 5 | path: "Panels/Smiley Rooms/purple" |
diff --git a/data/maps/daedalus/rooms/Pyramid 3.txtpb b/data/maps/daedalus/rooms/Pyramid 3.txtpb index f760ab0..be862d1 100644 --- a/data/maps/daedalus/rooms/Pyramid 3.txtpb +++ b/data/maps/daedalus/rooms/Pyramid 3.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid 3" | 1 | name: "Pyramid 3" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "VEHICLE" | 4 | name: "VEHICLE" |
5 | path: "Panels/Pyramid/pyramid_3" | 5 | path: "Panels/Pyramid/pyramid_3" |
diff --git a/data/maps/daedalus/rooms/Pyramid 4.txtpb b/data/maps/daedalus/rooms/Pyramid 4.txtpb index 3247ffa..e67e1c6 100644 --- a/data/maps/daedalus/rooms/Pyramid 4.txtpb +++ b/data/maps/daedalus/rooms/Pyramid 4.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid 4" | 1 | name: "Pyramid 4" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "CAT" | 4 | name: "CAT" |
5 | path: "Panels/Pyramid/pyramid_4" | 5 | path: "Panels/Pyramid/pyramid_4" |
diff --git a/data/maps/daedalus/rooms/Pyramid 5.txtpb b/data/maps/daedalus/rooms/Pyramid 5.txtpb index fc05e50..42e8a52 100644 --- a/data/maps/daedalus/rooms/Pyramid 5.txtpb +++ b/data/maps/daedalus/rooms/Pyramid 5.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid 5" | 1 | name: "Pyramid 5" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "ROYAL" | 4 | name: "ROYAL" |
5 | path: "Panels/Pyramid/pyramid_5" | 5 | path: "Panels/Pyramid/pyramid_5" |
diff --git a/data/maps/daedalus/rooms/Pyramid 6.txtpb b/data/maps/daedalus/rooms/Pyramid 6.txtpb index 78efb0c..3a7346b 100644 --- a/data/maps/daedalus/rooms/Pyramid 6.txtpb +++ b/data/maps/daedalus/rooms/Pyramid 6.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid 6" | 1 | name: "Pyramid 6" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "TEA" | 4 | name: "TEA" |
5 | path: "Panels/Pyramid/pyramid_6" | 5 | path: "Panels/Pyramid/pyramid_6" |
diff --git a/data/maps/daedalus/rooms/Pyramid 7.txtpb b/data/maps/daedalus/rooms/Pyramid 7.txtpb index bf4ebc6..2db71ea 100644 --- a/data/maps/daedalus/rooms/Pyramid 7.txtpb +++ b/data/maps/daedalus/rooms/Pyramid 7.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid 7" | 1 | name: "Pyramid 7" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "ARTIST" | 4 | name: "ARTIST" |
5 | path: "Panels/Pyramid/pyramid_7" | 5 | path: "Panels/Pyramid/pyramid_7" |
diff --git a/data/maps/daedalus/rooms/Pyramid 8.txtpb b/data/maps/daedalus/rooms/Pyramid 8.txtpb index f65fc69..6f61340 100644 --- a/data/maps/daedalus/rooms/Pyramid 8.txtpb +++ b/data/maps/daedalus/rooms/Pyramid 8.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Pyramid 8" | 1 | name: "Pyramid 8" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "INSTRUMENT" | 4 | name: "INSTRUMENT" |
5 | path: "Panels/Pyramid/pyramid_8" | 5 | path: "Panels/Pyramid/pyramid_8" |
6 | clue: "instrument" | 6 | clue: "instrument" |
7 | answer: "drum" | 7 | answer: "drum" |
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | display_name: "INSTRUMENT (1F)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Pyramid Entry.txtpb b/data/maps/daedalus/rooms/Pyramid Entry.txtpb index 3bb531f..2c9e841 100644 --- a/data/maps/daedalus/rooms/Pyramid Entry.txtpb +++ b/data/maps/daedalus/rooms/Pyramid Entry.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid Entry" | 1 | name: "Pyramid Entry" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "TREE" | 4 | name: "TREE" |
5 | path: "Panels/Pyramid/pyramid_1" | 5 | path: "Panels/Pyramid/pyramid_1" |
diff --git a/data/maps/daedalus/rooms/Pyramid Second Floor.txtpb b/data/maps/daedalus/rooms/Pyramid Second Floor.txtpb index e7578e8..86f5f2a 100644 --- a/data/maps/daedalus/rooms/Pyramid Second Floor.txtpb +++ b/data/maps/daedalus/rooms/Pyramid Second Floor.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid Second Floor" | 1 | name: "Pyramid Second Floor" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | panels { | 3 | panels { |
4 | name: "TOOL" | 4 | name: "TOOL" |
5 | path: "Panels/Pyramid/pyramid_10" | 5 | path: "Panels/Pyramid/pyramid_10" |
@@ -36,6 +36,7 @@ panels { | |||
36 | answer: "organ" | 36 | answer: "organ" |
37 | symbols: EXAMPLE | 37 | symbols: EXAMPLE |
38 | required_door { name: "Pyramid 13 Blocker" } | 38 | required_door { name: "Pyramid 13 Blocker" } |
39 | display_name: "INSTRUMENT (2F)" | ||
39 | } | 40 | } |
40 | panels { | 41 | panels { |
41 | name: "BEVERAGE" | 42 | name: "BEVERAGE" |
diff --git a/data/maps/daedalus/rooms/Pyramid Top.txtpb b/data/maps/daedalus/rooms/Pyramid Top.txtpb index b3938fd..c017cd6 100644 --- a/data/maps/daedalus/rooms/Pyramid Top.txtpb +++ b/data/maps/daedalus/rooms/Pyramid Top.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pyramid Top" | 1 | name: "Pyramid Top" |
2 | display_name: "Pyramid" | 2 | panel_display_name: "Pyramid" |
3 | letters { | 3 | letters { |
4 | key: "r" | 4 | key: "r" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/Quiet Entrance.txtpb b/data/maps/daedalus/rooms/Quiet Entrance.txtpb index 21e0f68..cd0d0ed 100644 --- a/data/maps/daedalus/rooms/Quiet Entrance.txtpb +++ b/data/maps/daedalus/rooms/Quiet Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Quiet Entrance" | 1 | name: "Quiet Entrance" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "HIDDEN" | 4 | name: "HIDDEN" |
5 | path: "Panels/Halls/halls_7" | 5 | path: "Panels/Halls/halls_7" |
@@ -8,6 +8,7 @@ panels { | |||
8 | symbols: SUN | 8 | symbols: SUN |
9 | proxies { answer: "covert" path: "Panels/Halls/secret_proxy_3" } | 9 | proxies { answer: "covert" path: "Panels/Halls/secret_proxy_3" } |
10 | proxies { answer: "secret" path: "Panels/Halls/secret_proxy_4" } | 10 | proxies { answer: "secret" path: "Panels/Halls/secret_proxy_4" } |
11 | display_name: "HIDDEN (West)" | ||
11 | } | 12 | } |
12 | paintings { | 13 | paintings { |
13 | name: "PLANET2" | 14 | name: "PLANET2" |
@@ -15,5 +16,8 @@ paintings { | |||
15 | } | 16 | } |
16 | ports { | 17 | ports { |
17 | name: "QUIET" | 18 | name: "QUIET" |
19 | display_name: "Near Planet Painting Worldport" | ||
18 | path: "Components/Warps/Worldports/worldport5" | 20 | path: "Components/Warps/Worldports/worldport5" |
21 | destination { x: -32 y: 0 z: -40 } | ||
22 | rotation: 90 | ||
19 | } | 23 | } |
diff --git a/data/maps/daedalus/rooms/Rain Side.txtpb b/data/maps/daedalus/rooms/Rain Side.txtpb index 63e95c8..2a62525 100644 --- a/data/maps/daedalus/rooms/Rain Side.txtpb +++ b/data/maps/daedalus/rooms/Rain Side.txtpb | |||
@@ -1,13 +1,17 @@ | |||
1 | name: "Rain Side" | 1 | name: "Rain Side" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "?" | 4 | name: "?" |
5 | path: "Panels/Smiley Rooms/rain" | 5 | path: "Panels/Smiley Rooms/rain" |
6 | clue: "" | 6 | clue: "" |
7 | answer: "rain" | 7 | answer: "rain" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "? (1)" | ||
9 | } | 10 | } |
10 | ports { | 11 | ports { |
11 | name: "BEARER" | 12 | name: "BEARER" |
13 | display_name: "Rain Panel Worldport" | ||
12 | path: "Components/Warps/Worldports/worldport11" | 14 | path: "Components/Warps/Worldports/worldport11" |
15 | destination { x: 93.5 y: 0 z: 27 } | ||
16 | rotation: 90 | ||
13 | } | 17 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow Blue.txtpb b/data/maps/daedalus/rooms/Rainbow Blue.txtpb index b566cbb..516a9b6 100644 --- a/data/maps/daedalus/rooms/Rainbow Blue.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Blue.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Rainbow Blue" | 1 | name: "Rainbow Blue" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "THEME" | 4 | name: "THEME" |
5 | path: "Panels/Smiley Rooms/blue2" | 5 | path: "Panels/Smiley Rooms/blue2" |
6 | clue: "theme" | 6 | clue: "theme" |
7 | answer: "seasonings" | 7 | answer: "seasonings" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "THEME (Blue)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow Color Backside.txtpb b/data/maps/daedalus/rooms/Rainbow Color Backside.txtpb index 3fb3a5c..d9b49c5 100644 --- a/data/maps/daedalus/rooms/Rainbow Color Backside.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Color Backside.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Rainbow Color Backside" | 1 | name: "Rainbow Color Backside" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "BACKSIDE" | 4 | name: "BACKSIDE" |
5 | path: "Panels/Halls/halls_1" | 5 | path: "Panels/Halls/halls_1" |
@@ -11,4 +11,5 @@ panels { | |||
11 | path: "Panels/Halls/halls_4" | 11 | path: "Panels/Halls/halls_4" |
12 | clue: "" | 12 | clue: "" |
13 | answer: "side" | 13 | answer: "side" |
14 | display_name: "Backside Behind" | ||
14 | } | 15 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow Color Doors.txtpb b/data/maps/daedalus/rooms/Rainbow Color Doors.txtpb index 3204d28..df44979 100644 --- a/data/maps/daedalus/rooms/Rainbow Color Doors.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Color Doors.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Rainbow Color Doors" | 1 | name: "Rainbow Color Doors" |
2 | display_name: "East Area" | 2 | panel_display_name: "East Area" |
3 | panels { | 3 | panels { |
4 | name: "CROW" | 4 | name: "CROW" |
5 | path: "Panels/Blue Room/panel_entry" | 5 | path: "Panels/Blue Room/panel_entry" |
diff --git a/data/maps/daedalus/rooms/Rainbow Cyan.txtpb b/data/maps/daedalus/rooms/Rainbow Cyan.txtpb index 9ce8b3f..f55b0d2 100644 --- a/data/maps/daedalus/rooms/Rainbow Cyan.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Cyan.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Rainbow Cyan" | 1 | name: "Rainbow Cyan" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "THEME" | 4 | name: "THEME" |
5 | path: "Panels/Smiley Rooms/cyan" | 5 | path: "Panels/Smiley Rooms/cyan" |
6 | clue: "theme" | 6 | clue: "theme" |
7 | answer: "apocalypse" | 7 | answer: "apocalypse" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "THEME (Cyan)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow End.txtpb b/data/maps/daedalus/rooms/Rainbow End.txtpb index 27f3c4f..ec623c7 100644 --- a/data/maps/daedalus/rooms/Rainbow End.txtpb +++ b/data/maps/daedalus/rooms/Rainbow End.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Rainbow End" | 1 | name: "Rainbow End" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "POT" | 4 | name: "POT" |
5 | path: "Components/Warps/gold" | 5 | path: "Components/Warps/gold" |
diff --git a/data/maps/daedalus/rooms/Rainbow Green.txtpb b/data/maps/daedalus/rooms/Rainbow Green.txtpb index 84de8a5..85bb8be 100644 --- a/data/maps/daedalus/rooms/Rainbow Green.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Green.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Rainbow Green" | 1 | name: "Rainbow Green" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "THEME" | 4 | name: "THEME" |
5 | path: "Panels/Smiley Rooms/green2" | 5 | path: "Panels/Smiley Rooms/green2" |
6 | clue: "theme" | 6 | clue: "theme" |
7 | answer: "tea" | 7 | answer: "tea" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "THEME (Green)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow Orange.txtpb b/data/maps/daedalus/rooms/Rainbow Orange.txtpb index 290c061..785eda8 100644 --- a/data/maps/daedalus/rooms/Rainbow Orange.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Orange.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Rainbow Orange" | 1 | name: "Rainbow Orange" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "THEME" | 4 | name: "THEME" |
5 | path: "Panels/Smiley Rooms/orange2" | 5 | path: "Panels/Smiley Rooms/orange2" |
6 | clue: "theme" | 6 | clue: "theme" |
7 | answer: "fish" | 7 | answer: "fish" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "THEME (Orange)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow Purple.txtpb b/data/maps/daedalus/rooms/Rainbow Purple.txtpb index 698af59..1f585dd 100644 --- a/data/maps/daedalus/rooms/Rainbow Purple.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Purple.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Rainbow Purple" | 1 | name: "Rainbow Purple" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "THEME" | 4 | name: "THEME" |
5 | path: "Panels/Smiley Rooms/purple2" | 5 | path: "Panels/Smiley Rooms/purple2" |
6 | clue: "theme" | 6 | clue: "theme" |
7 | answer: "fruit" | 7 | answer: "fruit" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "THEME (Purple)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow Red.txtpb b/data/maps/daedalus/rooms/Rainbow Red.txtpb index 92dbda0..7ef4db3 100644 --- a/data/maps/daedalus/rooms/Rainbow Red.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Red.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Rainbow Red" | 1 | name: "Rainbow Red" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "THEME" | 4 | name: "THEME" |
5 | path: "Panels/Smiley Rooms/red2" | 5 | path: "Panels/Smiley Rooms/red2" |
6 | clue: "theme" | 6 | clue: "theme" |
7 | answer: "names" | 7 | answer: "names" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "THEME (Red)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Rainbow Start.txtpb b/data/maps/daedalus/rooms/Rainbow Start.txtpb index e0d5dc1..c46b762 100644 --- a/data/maps/daedalus/rooms/Rainbow Start.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Start.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Rainbow Start" | 1 | name: "Rainbow Start" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "PAINTING" | 4 | name: "PAINTING" |
5 | path: "Panels/Smiley Rooms/rainbow" | 5 | path: "Panels/Smiley Rooms/rainbow" |
diff --git a/data/maps/daedalus/rooms/Rainbow Yellow.txtpb b/data/maps/daedalus/rooms/Rainbow Yellow.txtpb index bbbdce4..bd2cfc5 100644 --- a/data/maps/daedalus/rooms/Rainbow Yellow.txtpb +++ b/data/maps/daedalus/rooms/Rainbow Yellow.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Rainbow Yellow" | 1 | name: "Rainbow Yellow" |
2 | display_name: "Rainbow" | 2 | panel_display_name: "Rainbow" |
3 | panels { | 3 | panels { |
4 | name: "THEME" | 4 | name: "THEME" |
5 | path: "Panels/Smiley Rooms/yellow2" | 5 | path: "Panels/Smiley Rooms/yellow2" |
6 | clue: "theme" | 6 | clue: "theme" |
7 | answer: "music" | 7 | answer: "music" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | display_name: "THEME (Yellow)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Red Color Door.txtpb b/data/maps/daedalus/rooms/Red Color Door.txtpb index a2f40a5..344193e 100644 --- a/data/maps/daedalus/rooms/Red Color Door.txtpb +++ b/data/maps/daedalus/rooms/Red Color Door.txtpb | |||
@@ -1,7 +1,7 @@ | |||
1 | name: "Red Color Door" | 1 | name: "Red Color Door" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "Left" | 4 | name: "Near Obscured Puzzles" |
5 | path: "Panels/Halls/wb_1" | 5 | path: "Panels/Halls/wb_1" |
6 | clue: "" | 6 | clue: "" |
7 | answer: "sidewalk" | 7 | answer: "sidewalk" |
@@ -67,4 +67,5 @@ panels { | |||
67 | clue: "" | 67 | clue: "" |
68 | answer: "bank" | 68 | answer: "bank" |
69 | symbols: LINGO | 69 | symbols: LINGO |
70 | display_name: "Colors (Black)" | ||
70 | } | 71 | } |
diff --git a/data/maps/daedalus/rooms/Red Room.txtpb b/data/maps/daedalus/rooms/Red Room.txtpb index 99f0a1e..d73f591 100644 --- a/data/maps/daedalus/rooms/Red Room.txtpb +++ b/data/maps/daedalus/rooms/Red Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Red Room" | 1 | name: "Red Room" |
2 | display_name: "Red Room" | 2 | panel_display_name: "Red Room" |
3 | panels { | 3 | panels { |
4 | name: "BLINDING" | 4 | name: "BLINDING" |
5 | path: "Panels/Red Room/red_1" | 5 | path: "Panels/Red Room/red_1" |
diff --git a/data/maps/daedalus/rooms/Red Smiley.txtpb b/data/maps/daedalus/rooms/Red Smiley.txtpb index 6f7c41c..28f2a03 100644 --- a/data/maps/daedalus/rooms/Red Smiley.txtpb +++ b/data/maps/daedalus/rooms/Red Smiley.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Red Smiley" | 1 | name: "Red Smiley" |
2 | display_name: "Northwest Area" | 2 | panel_display_name: "Northwest Area" |
3 | panels { | 3 | panels { |
4 | name: "SMILE" | 4 | name: "SMILE" |
5 | path: "Panels/Smiley Rooms/red" | 5 | path: "Panels/Smiley Rooms/red" |
diff --git a/data/maps/daedalus/rooms/Roof.txtpb b/data/maps/daedalus/rooms/Roof.txtpb index c027a72..3aba765 100644 --- a/data/maps/daedalus/rooms/Roof.txtpb +++ b/data/maps/daedalus/rooms/Roof.txtpb | |||
@@ -1,4 +1,5 @@ | |||
1 | name: "Roof" | 1 | name: "Roof" |
2 | panel_display_name: "Roof" | ||
2 | panels { | 3 | panels { |
3 | name: "?" | 4 | name: "?" |
4 | path: "Panels/Castle Entrance/moat" | 5 | path: "Panels/Castle Entrance/moat" |
diff --git a/data/maps/daedalus/rooms/Salt Room.txtpb b/data/maps/daedalus/rooms/Salt Room.txtpb index 0c7fe73..39c9c9f 100644 --- a/data/maps/daedalus/rooms/Salt Room.txtpb +++ b/data/maps/daedalus/rooms/Salt Room.txtpb | |||
@@ -1,9 +1,10 @@ | |||
1 | name: "Salt Room" | 1 | name: "Salt Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "SEASONING" | 4 | name: "SEASONING" |
5 | path: "Panels/Color Reading/cr_3" | 5 | path: "Panels/Color Reading/cr_3" |
6 | clue: "seasoning" | 6 | clue: "seasoning" |
7 | answer: "salt" | 7 | answer: "salt" |
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | display_name: "SEASONING (White)" | ||
9 | } | 10 | } |
diff --git a/data/maps/daedalus/rooms/Seasoning Room.txtpb b/data/maps/daedalus/rooms/Seasoning Room.txtpb index d3123b9..6159134 100644 --- a/data/maps/daedalus/rooms/Seasoning Room.txtpb +++ b/data/maps/daedalus/rooms/Seasoning Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Seasoning Room" | 1 | name: "Seasoning Room" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | panels { | 3 | panels { |
4 | name: "PARITY" | 4 | name: "PARITY" |
5 | path: "Panels/Color Reading/cr_5" | 5 | path: "Panels/Color Reading/cr_5" |
diff --git a/data/maps/daedalus/rooms/Snake Room.txtpb b/data/maps/daedalus/rooms/Snake Room.txtpb index f3cea2e..fb947ab 100644 --- a/data/maps/daedalus/rooms/Snake Room.txtpb +++ b/data/maps/daedalus/rooms/Snake Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Snake Room" | 1 | name: "Snake Room" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
3 | panels { | 3 | panels { |
4 | name: "HISS" | 4 | name: "HISS" |
5 | path: "Panels/Snake Room/snake_1" | 5 | path: "Panels/Snake Room/snake_1" |
diff --git a/data/maps/daedalus/rooms/South Castle Area.txtpb b/data/maps/daedalus/rooms/South Castle Area.txtpb index 9f620b7..4bb73f3 100644 --- a/data/maps/daedalus/rooms/South Castle Area.txtpb +++ b/data/maps/daedalus/rooms/South Castle Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "South Castle Area" | 1 | name: "South Castle Area" |
2 | display_name: "Outside Pumpkin" | 2 | panel_display_name: "Outside Pumpkin" |
3 | # There is a teal wall in the middle of this room. | 3 | # There is a teal wall in the middle of this room. |
4 | panels { | 4 | panels { |
5 | name: "AN" | 5 | name: "AN" |
@@ -107,5 +107,5 @@ paintings { | |||
107 | path: "Components/Paintings/Group2/triangle" | 107 | path: "Components/Paintings/Group2/triangle" |
108 | move: true | 108 | move: true |
109 | enter_only: true | 109 | enter_only: true |
110 | # TODO: required_door | 110 | required_door { name: "Tenacious Color Painting" } |
111 | } | 111 | } |
diff --git a/data/maps/daedalus/rooms/Starting Room.txtpb b/data/maps/daedalus/rooms/Starting Room.txtpb index 615104b..1b07eb4 100644 --- a/data/maps/daedalus/rooms/Starting Room.txtpb +++ b/data/maps/daedalus/rooms/Starting Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Starting Room" | 1 | name: "Starting Room" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "ENTRANCE" | 4 | name: "ENTRANCE" |
5 | path: "Panels/Entry/entry_1" | 5 | path: "Panels/Entry/entry_1" |
@@ -9,5 +9,8 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "GREAT" | 11 | name: "GREAT" |
12 | display_name: "Starting Room South Wall Middle Worldport" | ||
12 | path: "Components/Warps/Worldports/worldport" | 13 | path: "Components/Warps/Worldports/worldport" |
14 | destination { x: 0 y: 0 z: 11 } | ||
15 | rotation: 0 | ||
13 | } | 16 | } |
diff --git a/data/maps/daedalus/rooms/Sweet Foyer.txtpb b/data/maps/daedalus/rooms/Sweet Foyer.txtpb index d337e7e..d1167eb 100644 --- a/data/maps/daedalus/rooms/Sweet Foyer.txtpb +++ b/data/maps/daedalus/rooms/Sweet Foyer.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Sweet Foyer" | 1 | name: "Sweet Foyer" |
2 | display_name: "South Area" | 2 | panel_display_name: "South Area" |
3 | panels { | 3 | panels { |
4 | name: "QUALITY" | 4 | name: "QUALITY" |
5 | path: "Panels/Sweet Foyer/panel_1" | 5 | path: "Panels/Sweet Foyer/panel_1" |
@@ -51,9 +51,15 @@ paintings { | |||
51 | } | 51 | } |
52 | ports { | 52 | ports { |
53 | name: "SWEET1" | 53 | name: "SWEET1" |
54 | display_name: "Sweet East Entrance" | ||
54 | path: "Components/Warps/Worldports/worldport14" | 55 | path: "Components/Warps/Worldports/worldport14" |
56 | destination { x: -27 y: 0 z: 76.5 } | ||
57 | rotation: 270 | ||
55 | } | 58 | } |
56 | ports { | 59 | ports { |
57 | name: "SWEET2" | 60 | name: "SWEET2" |
61 | display_name: "Sweet West Entrance" | ||
58 | path: "Components/Warps/Worldports/worldport15" | 62 | path: "Components/Warps/Worldports/worldport15" |
63 | destination { x: -36 y: 0 z: 76.5 } | ||
64 | rotation: 90 | ||
59 | } | 65 | } |
diff --git a/data/maps/daedalus/rooms/Tree Entrance.txtpb b/data/maps/daedalus/rooms/Tree Entrance.txtpb index df2db7e..1453790 100644 --- a/data/maps/daedalus/rooms/Tree Entrance.txtpb +++ b/data/maps/daedalus/rooms/Tree Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Tree Entrance" | 1 | name: "Tree Entrance" |
2 | display_name: "Outside Pumpkin" | 2 | panel_display_name: "Outside Pumpkin" |
3 | panels { | 3 | panels { |
4 | name: "RAT" | 4 | name: "RAT" |
5 | path: "Panels/Hexes/lime_1" | 5 | path: "Panels/Hexes/lime_1" |
@@ -48,5 +48,8 @@ panels { | |||
48 | } | 48 | } |
49 | ports { | 49 | ports { |
50 | name: "TREE" | 50 | name: "TREE" |
51 | display_name: "Near Pumpkin Brown Hallway" | ||
51 | path: "Components/Warps/Worldports/worldport12" | 52 | path: "Components/Warps/Worldports/worldport12" |
53 | destination { x: 41 y: 0 z: 50.5 } | ||
54 | rotation: 0 | ||
52 | } | 55 | } |
diff --git a/data/maps/daedalus/rooms/U2 Prize.txtpb b/data/maps/daedalus/rooms/U2 Prize.txtpb index 947af67..571b0c8 100644 --- a/data/maps/daedalus/rooms/U2 Prize.txtpb +++ b/data/maps/daedalus/rooms/U2 Prize.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "U2 Prize" | 1 | name: "U2 Prize" |
2 | display_name: "U2 Room" | 2 | panel_display_name: "U2 Room" |
3 | letters { | 3 | letters { |
4 | key: "u" | 4 | key: "u" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/U2 Room.txtpb b/data/maps/daedalus/rooms/U2 Room.txtpb index c9907eb..1e5879a 100644 --- a/data/maps/daedalus/rooms/U2 Room.txtpb +++ b/data/maps/daedalus/rooms/U2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "U2 Room" | 1 | name: "U2 Room" |
2 | display_name: "U2 Room" | 2 | panel_display_name: "U2 Room" |
3 | panels { | 3 | panels { |
4 | name: "DREAMSCAPE" | 4 | name: "DREAMSCAPE" |
5 | path: "Panels/The Big U/o_1" | 5 | path: "Panels/The Big U/o_1" |
diff --git a/data/maps/daedalus/rooms/Unkempt Entrance.txtpb b/data/maps/daedalus/rooms/Unkempt Entrance.txtpb index 192ba9c..0a39ee0 100644 --- a/data/maps/daedalus/rooms/Unkempt Entrance.txtpb +++ b/data/maps/daedalus/rooms/Unkempt Entrance.txtpb | |||
@@ -1,6 +1,9 @@ | |||
1 | name: "Unkempt Entrance" | 1 | name: "Unkempt Entrance" |
2 | display_name: "O2 Room" | 2 | panel_display_name: "O2 Room" |
3 | ports { | 3 | ports { |
4 | name: "UNKEMPT" | 4 | name: "UNKEMPT" |
5 | display_name: "O2 Room Worldport" | ||
5 | path: "Components/Warps/Worldports/worldport6" | 6 | path: "Components/Warps/Worldports/worldport6" |
7 | destination { x: -61 y: 0 z: 95 } | ||
8 | rotation: 270 | ||
6 | } | 9 | } |
diff --git a/data/maps/daedalus/rooms/Welcome Back Area.txtpb b/data/maps/daedalus/rooms/Welcome Back Area.txtpb index 3f320a3..701baca 100644 --- a/data/maps/daedalus/rooms/Welcome Back Area.txtpb +++ b/data/maps/daedalus/rooms/Welcome Back Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Welcome Back Area" | 1 | name: "Welcome Back Area" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "FAREWELL LITTLE LAMB" | 4 | name: "FAREWELL LITTLE LAMB" |
5 | path: "Panels/Entry/wb_2" | 5 | path: "Panels/Entry/wb_2" |
diff --git a/data/maps/daedalus/rooms/Welcome Back Exit.txtpb b/data/maps/daedalus/rooms/Welcome Back Exit.txtpb index a4a23e2..ac221c7 100644 --- a/data/maps/daedalus/rooms/Welcome Back Exit.txtpb +++ b/data/maps/daedalus/rooms/Welcome Back Exit.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Welcome Back Exit" | 1 | name: "Welcome Back Exit" |
2 | display_name: "Central" | 2 | panel_display_name: "Central" |
3 | panels { | 3 | panels { |
4 | name: "WELCOME" | 4 | name: "WELCOME" |
5 | path: "Panels/Entry/wb_1" | 5 | path: "Panels/Entry/wb_1" |
@@ -7,4 +7,5 @@ panels { | |||
7 | answer: "welcome" | 7 | answer: "welcome" |
8 | symbols: QUESTION | 8 | symbols: QUESTION |
9 | proxies { answer: "back" path: "Panels/Entry/wb_proxy" } | 9 | proxies { answer: "back" path: "Panels/Entry/wb_proxy" } |
10 | display_name: "WELCOME (White)" | ||
10 | } | 11 | } |
diff --git a/data/maps/daedalus/rooms/West Castle Area.txtpb b/data/maps/daedalus/rooms/West Castle Area.txtpb index 88722f5..010e5d6 100644 --- a/data/maps/daedalus/rooms/West Castle Area.txtpb +++ b/data/maps/daedalus/rooms/West Castle Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "West Castle Area" | 1 | name: "West Castle Area" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
3 | panels { | 3 | panels { |
4 | name: "SONG (1)" | 4 | name: "SONG (1)" |
5 | path: "Panels/Castle Entrance/castle_west_helper" | 5 | path: "Panels/Castle Entrance/castle_west_helper" |
diff --git a/data/maps/daedalus/rooms/West Spire.txtpb b/data/maps/daedalus/rooms/West Spire.txtpb index fdf8f9a..7cc579f 100644 --- a/data/maps/daedalus/rooms/West Spire.txtpb +++ b/data/maps/daedalus/rooms/West Spire.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "West Spire" | 1 | name: "West Spire" |
2 | display_name: "West Area" | 2 | panel_display_name: "West Area" |
3 | panels { | 3 | panels { |
4 | name: "MISSING" | 4 | name: "MISSING" |
5 | path: "Panels/Entry/wb_5" | 5 | path: "Panels/Entry/wb_5" |
diff --git a/data/maps/daedalus/rooms/White Hallway From Entry.txtpb b/data/maps/daedalus/rooms/White Hallway From Entry.txtpb index 2af7584..d3659d3 100644 --- a/data/maps/daedalus/rooms/White Hallway From Entry.txtpb +++ b/data/maps/daedalus/rooms/White Hallway From Entry.txtpb | |||
@@ -1,12 +1,9 @@ | |||
1 | name: "White Hallway From Entry" | 1 | name: "White Hallway From Entry" |
2 | display_name: "Southwest Area" | 2 | panel_display_name: "Southwest Area" |
3 | # Not exactly sure what to do with this yet. In unshuffled connections, the door | ||
4 | # here should be paired with the door on the other end (which is vanilla) even | ||
5 | # if control center color doors are shuffled. But when connections are shuffled | ||
6 | # maybe this should be shuffled separately? I might also want to find a way to | ||
7 | # register when there's a door immediately outside of a connection so that when | ||
8 | # two connections behind doors are shuffled together, their doors can be paired. | ||
9 | ports { | 3 | ports { |
10 | name: "ENTRY" | 4 | name: "ENTRY" |
5 | display_name: "Near Globe White Hallway" | ||
11 | path: "Components/Warps/Worldports/worldport10" | 6 | path: "Components/Warps/Worldports/worldport10" |
7 | destination { x: -46 y: 0 z: 23 } | ||
8 | rotation: 90 | ||
12 | } | 9 | } |
diff --git a/data/maps/daedalus/rooms/Wisdom Panel.txtpb b/data/maps/daedalus/rooms/Wisdom Panel.txtpb index 5cbf051..d789f2b 100644 --- a/data/maps/daedalus/rooms/Wisdom Panel.txtpb +++ b/data/maps/daedalus/rooms/Wisdom Panel.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Wisdom Panel" | 1 | name: "Wisdom Panel" |
2 | display_name: "Castle" | 2 | panel_display_name: "Castle" |
3 | panels { | 3 | panels { |
4 | name: "INTELLIGENCE" | 4 | name: "INTELLIGENCE" |
5 | path: "Components/Warps/numbers" | 5 | path: "Components/Warps/numbers" |
diff --git a/data/maps/daedalus/rooms/Wonderland.txtpb b/data/maps/daedalus/rooms/Wonderland.txtpb index 99c124e..b4782d2 100644 --- a/data/maps/daedalus/rooms/Wonderland.txtpb +++ b/data/maps/daedalus/rooms/Wonderland.txtpb | |||
@@ -1,6 +1,5 @@ | |||
1 | name: "Wonderland" | 1 | name: "Wonderland" |
2 | display_name: "Northwest Area" | 2 | panel_display_name: "Northwest Area" |
3 | # TODO: There's a warp from The Entry into here. | ||
4 | panels { | 3 | panels { |
5 | name: "APRIL" | 4 | name: "APRIL" |
6 | path: "Panels/Wonderland/wonderland_1" | 5 | path: "Panels/Wonderland/wonderland_1" |
@@ -38,5 +37,8 @@ panels { | |||
38 | } | 37 | } |
39 | ports { | 38 | ports { |
40 | name: "WONDROUS" | 39 | name: "WONDROUS" |
40 | display_name: "Wonderland Worldport" | ||
41 | path: "Components/Warps/Worldports/worldport3" | 41 | path: "Components/Warps/Worldports/worldport3" |
42 | destination { x: -104 y: 0 z: -69 } | ||
43 | rotation: 180 | ||
42 | } | 44 | } |
diff --git a/data/maps/daedalus/rooms/Yellow Color Backside.txtpb b/data/maps/daedalus/rooms/Yellow Color Backside.txtpb index 931e501..1c29b43 100644 --- a/data/maps/daedalus/rooms/Yellow Color Backside.txtpb +++ b/data/maps/daedalus/rooms/Yellow Color Backside.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Yellow Color Backside" | 1 | name: "Yellow Color Backside" |
2 | display_name: "Northeast Area" | 2 | panel_display_name: "Northeast Area" |
3 | panels { | 3 | panels { |
4 | name: "WINDS" | 4 | name: "WINDS" |
5 | path: "Panels/Halls/halls_24" | 5 | path: "Panels/Halls/halls_24" |
diff --git a/data/maps/daedalus/rooms/Yellow Color Door.txtpb b/data/maps/daedalus/rooms/Yellow Color Door.txtpb index a098c91..61d206b 100644 --- a/data/maps/daedalus/rooms/Yellow Color Door.txtpb +++ b/data/maps/daedalus/rooms/Yellow Color Door.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Yellow Color Door" | 1 | name: "Yellow Color Door" |
2 | display_name: "Northeast Area" | 2 | panel_display_name: "Northeast Area" |
3 | panels { | 3 | panels { |
4 | name: "SUN" | 4 | name: "SUN" |
5 | path: "Panels/Yellow Room/panel_entry" | 5 | path: "Panels/Yellow Room/panel_entry" |
@@ -26,9 +26,12 @@ paintings { | |||
26 | path: "Components/Paintings/Temple of the Eyes/eyeRedStart" | 26 | path: "Components/Paintings/Temple of the Eyes/eyeRedStart" |
27 | move: true | 27 | move: true |
28 | enter_only: true | 28 | enter_only: true |
29 | # TODO: requires double letters | 29 | required_door { name: "Eye Painting" } |
30 | } | 30 | } |
31 | ports { | 31 | ports { |
32 | name: "FOURROOMS" | 32 | name: "FOURROOMS" |
33 | display_name: "Near Yellow Worldport" | ||
33 | path: "Components/Warps/Worldports/worldport8" | 34 | path: "Components/Warps/Worldports/worldport8" |
35 | destination { x: 92.5 y: 0 z: -62 } | ||
36 | rotation: 90 | ||
34 | } | 37 | } |
diff --git a/data/maps/daedalus/rooms/Yellow Room.txtpb b/data/maps/daedalus/rooms/Yellow Room.txtpb index 1e84965..b4d8ff0 100644 --- a/data/maps/daedalus/rooms/Yellow Room.txtpb +++ b/data/maps/daedalus/rooms/Yellow Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Yellow Room" | 1 | name: "Yellow Room" |
2 | display_name: "Northeast Area" | 2 | panel_display_name: "Yellow Room" |
3 | panels { | 3 | panels { |
4 | name: "FREE" | 4 | name: "FREE" |
5 | path: "Panels/Yellow Room/panel_1" | 5 | path: "Panels/Yellow Room/panel_1" |
diff --git a/data/maps/daedalus/rooms/Yellow Smiley Annex.txtpb b/data/maps/daedalus/rooms/Yellow Smiley Annex.txtpb index fa059c4..cb6c402 100644 --- a/data/maps/daedalus/rooms/Yellow Smiley Annex.txtpb +++ b/data/maps/daedalus/rooms/Yellow Smiley Annex.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Yellow Smiley Annex" | 1 | name: "Yellow Smiley Annex" |
2 | display_name: "Hedges" | 2 | panel_display_name: "Hedges" |
3 | panels { | 3 | panels { |
4 | name: "COW" | 4 | name: "COW" |
5 | path: "Panels/Miscellaneous/plum1" | 5 | path: "Panels/Miscellaneous/plum1" |
diff --git a/data/maps/daedalus/rooms/Z2 Prize.txtpb b/data/maps/daedalus/rooms/Z2 Prize.txtpb index a7dd8fb..7b1ceae 100644 --- a/data/maps/daedalus/rooms/Z2 Prize.txtpb +++ b/data/maps/daedalus/rooms/Z2 Prize.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Z2 Prize" | 1 | name: "Z2 Prize" |
2 | display_name: "Northwest Area" | 2 | panel_display_name: "Z2 Room" |
3 | letters { | 3 | letters { |
4 | key: "z" | 4 | key: "z" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/Z2 Room.txtpb b/data/maps/daedalus/rooms/Z2 Room.txtpb index 1e84dbc..513150a 100644 --- a/data/maps/daedalus/rooms/Z2 Room.txtpb +++ b/data/maps/daedalus/rooms/Z2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Z2 Room" | 1 | name: "Z2 Room" |
2 | display_name: "Northwest Area" | 2 | panel_display_name: "Z2 Room" |
3 | panels { | 3 | panels { |
4 | name: "EXHIBIT" | 4 | name: "EXHIBIT" |
5 | path: "Panels/V Maze/entry" | 5 | path: "Panels/V Maze/entry" |
diff --git a/data/maps/daedalus/rooms/Zoo Center.txtpb b/data/maps/daedalus/rooms/Zoo Center.txtpb index fcf72a1..5a788db 100644 --- a/data/maps/daedalus/rooms/Zoo Center.txtpb +++ b/data/maps/daedalus/rooms/Zoo Center.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Zoo Center" | 1 | name: "Zoo Center" |
2 | display_name: "Zoo" | 2 | panel_display_name: "Zoo" |
3 | letters { | 3 | letters { |
4 | key: "v" | 4 | key: "v" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/daedalus/rooms/Zoo E.txtpb b/data/maps/daedalus/rooms/Zoo E.txtpb index 59479dc..3195623 100644 --- a/data/maps/daedalus/rooms/Zoo E.txtpb +++ b/data/maps/daedalus/rooms/Zoo E.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Zoo E" | 1 | name: "Zoo E" |
2 | display_name: "Zoo" | 2 | panel_display_name: "Zoo" |
3 | panels { | 3 | panels { |
4 | name: "WING" | 4 | name: "WING" |
5 | path: "Panels/V Maze/four_1" | 5 | path: "Panels/V Maze/four_1" |
diff --git a/data/maps/daedalus/rooms/Zoo N.txtpb b/data/maps/daedalus/rooms/Zoo N.txtpb index e2c1f5d..d621ed4 100644 --- a/data/maps/daedalus/rooms/Zoo N.txtpb +++ b/data/maps/daedalus/rooms/Zoo N.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Zoo N" | 1 | name: "Zoo N" |
2 | display_name: "Zoo" | 2 | panel_display_name: "Zoo" |
3 | panels { | 3 | panels { |
4 | name: "BILL" | 4 | name: "BILL" |
5 | path: "Panels/V Maze/four_13" | 5 | path: "Panels/V Maze/four_13" |
@@ -13,6 +13,7 @@ panels { | |||
13 | clue: "fin" | 13 | clue: "fin" |
14 | answer: "whale" | 14 | answer: "whale" |
15 | symbols: BOXES | 15 | symbols: BOXES |
16 | display_name: "FIN (N)" | ||
16 | } | 17 | } |
17 | panels { | 18 | panels { |
18 | name: "BLOWHOLE" | 19 | name: "BLOWHOLE" |
diff --git a/data/maps/daedalus/rooms/Zoo NE.txtpb b/data/maps/daedalus/rooms/Zoo NE.txtpb index 155172d..89bedae 100644 --- a/data/maps/daedalus/rooms/Zoo NE.txtpb +++ b/data/maps/daedalus/rooms/Zoo NE.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Zoo NE" | 1 | name: "Zoo NE" |
2 | display_name: "Zoo" | 2 | panel_display_name: "Zoo" |
3 | panels { | 3 | panels { |
4 | name: "FANG" | 4 | name: "FANG" |
5 | path: "Panels/V Maze/four_5" | 5 | path: "Panels/V Maze/four_5" |
diff --git a/data/maps/daedalus/rooms/Zoo S.txtpb b/data/maps/daedalus/rooms/Zoo S.txtpb index f4ddaea..3f3a8de 100644 --- a/data/maps/daedalus/rooms/Zoo S.txtpb +++ b/data/maps/daedalus/rooms/Zoo S.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Zoo S" | 1 | name: "Zoo S" |
2 | display_name: "Zoo" | 2 | panel_display_name: "Zoo" |
3 | panels { | 3 | panels { |
4 | name: "SHELL" | 4 | name: "SHELL" |
5 | path: "Panels/V Maze/four_9" | 5 | path: "Panels/V Maze/four_9" |
@@ -13,6 +13,7 @@ panels { | |||
13 | clue: "fin" | 13 | clue: "fin" |
14 | answer: "fish" | 14 | answer: "fish" |
15 | symbols: BOXES | 15 | symbols: BOXES |
16 | display_name: "FIN (S)" | ||
16 | } | 17 | } |
17 | panels { | 18 | panels { |
18 | name: "PINCER" | 19 | name: "PINCER" |
diff --git a/data/maps/daedalus/rooms/Zoo SE.txtpb b/data/maps/daedalus/rooms/Zoo SE.txtpb index 906d009..199f234 100644 --- a/data/maps/daedalus/rooms/Zoo SE.txtpb +++ b/data/maps/daedalus/rooms/Zoo SE.txtpb | |||
@@ -1,2 +1,2 @@ | |||
1 | name: "Zoo SE" | 1 | name: "Zoo SE" |
2 | display_name: "Zoo" | 2 | panel_display_name: "Zoo" |
diff --git a/data/maps/four_rooms/doors.txtpb b/data/maps/four_rooms/doors.txtpb index f0bf060..e58adb2 100644 --- a/data/maps/four_rooms/doors.txtpb +++ b/data/maps/four_rooms/doors.txtpb | |||
@@ -11,6 +11,7 @@ doors { | |||
11 | panels { room: "Intensify Room" name: "INJURY" } | 11 | panels { room: "Intensify Room" name: "INJURY" } |
12 | panels { room: "Intensify Room" name: "SWAY" } | 12 | panels { room: "Intensify Room" name: "SWAY" } |
13 | location_room: "Intensify Room" | 13 | location_room: "Intensify Room" |
14 | location_name: "Intensify Room" | ||
14 | } | 15 | } |
15 | doors { | 16 | doors { |
16 | name: "Examples Door" | 17 | name: "Examples Door" |
@@ -25,6 +26,7 @@ doors { | |||
25 | panels { room: "Examples Room" name: "URN" } | 26 | panels { room: "Examples Room" name: "URN" } |
26 | panels { room: "Examples Room" name: "ART" } | 27 | panels { room: "Examples Room" name: "ART" } |
27 | location_room: "Examples Room" | 28 | location_room: "Examples Room" |
29 | location_name: "Examples Room" | ||
28 | } | 30 | } |
29 | doors { | 31 | doors { |
30 | name: "Synonyms Door" | 32 | name: "Synonyms Door" |
@@ -39,6 +41,7 @@ doors { | |||
39 | panels { room: "Synonyms Room" name: "SERIOUS" } | 41 | panels { room: "Synonyms Room" name: "SERIOUS" } |
40 | panels { room: "Synonyms Room" name: "FURY" } | 42 | panels { room: "Synonyms Room" name: "FURY" } |
41 | location_room: "Synonyms Room" | 43 | location_room: "Synonyms Room" |
44 | location_name: "Synonyms Room" | ||
42 | } | 45 | } |
43 | doors { | 46 | doors { |
44 | name: "Time Door" | 47 | name: "Time Door" |
@@ -53,6 +56,7 @@ doors { | |||
53 | panels { room: "Time Room" name: "HOLE" } | 56 | panels { room: "Time Room" name: "HOLE" } |
54 | panels { room: "Time Room" name: "RHYTHM" } | 57 | panels { room: "Time Room" name: "RHYTHM" } |
55 | location_room: "Time Room" | 58 | location_room: "Time Room" |
59 | location_name: "Time Room" | ||
56 | } | 60 | } |
57 | doors { | 61 | doors { |
58 | name: "A2 Door" | 62 | name: "A2 Door" |
diff --git a/data/maps/four_rooms/rooms/A2 Room.txtpb b/data/maps/four_rooms/rooms/A2 Room.txtpb index 236ce01..ea2ae64 100644 --- a/data/maps/four_rooms/rooms/A2 Room.txtpb +++ b/data/maps/four_rooms/rooms/A2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "A2 Room" | 1 | name: "A2 Room" |
2 | display_name: "Hallway" | ||
3 | letters { | 2 | letters { |
4 | key: "a" | 3 | key: "a" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/four_rooms/rooms/Examples Room.txtpb b/data/maps/four_rooms/rooms/Examples Room.txtpb index 3d82e22..4146120 100644 --- a/data/maps/four_rooms/rooms/Examples Room.txtpb +++ b/data/maps/four_rooms/rooms/Examples Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Examples Room" | 1 | name: "Examples Room" |
2 | display_name: "Examples Room" | ||
3 | panels { | 2 | panels { |
4 | name: "SIZE (1)" | 3 | name: "SIZE (1)" |
5 | path: "Panels/Room 2 Examples/entry_1" | 4 | path: "Panels/Room 2 Examples/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "DAEDALUS" | 59 | name: "DAEDALUS" |
60 | display_name: "Examples Room Worldport" | ||
61 | path: "Components/Warps/worldport2" | 61 | path: "Components/Warps/worldport2" |
62 | orientation: "north" | 62 | destination { x: 0 y: 0 z: -40.5 } |
63 | rotation: 180 | ||
63 | } | 64 | } |
diff --git a/data/maps/four_rooms/rooms/Hallway.txtpb b/data/maps/four_rooms/rooms/Hallway.txtpb index f80cf73..124a5b3 100644 --- a/data/maps/four_rooms/rooms/Hallway.txtpb +++ b/data/maps/four_rooms/rooms/Hallway.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Hallway" | 1 | name: "Hallway" |
2 | display_name: "Hallway" | ||
3 | panels { | 2 | panels { |
4 | name: "SUSPICION" | 3 | name: "SUSPICION" |
5 | path: "Panels/Reward Room/reward_1" | 4 | path: "Panels/Reward Room/reward_1" |
diff --git a/data/maps/four_rooms/rooms/Intensify Room.txtpb b/data/maps/four_rooms/rooms/Intensify Room.txtpb index fb95a1e..8c6924a 100644 --- a/data/maps/four_rooms/rooms/Intensify Room.txtpb +++ b/data/maps/four_rooms/rooms/Intensify Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Intensify Room" | 1 | name: "Intensify Room" |
2 | display_name: "Intensify Room" | ||
3 | panels { | 2 | panels { |
4 | name: "SMALL" | 3 | name: "SMALL" |
5 | path: "Panels/Room 1 Intensify/entry_1" | 4 | path: "Panels/Room 1 Intensify/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "IMPRESSIVE" | 59 | name: "IMPRESSIVE" |
60 | display_name: "Intensify Room Worldport" | ||
61 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | orientation: "south" | 62 | destination { x: 0 y: 0 z: 6.5 } |
63 | rotation: 0 | ||
63 | } | 64 | } |
diff --git a/data/maps/four_rooms/rooms/Keyholder Room.txtpb b/data/maps/four_rooms/rooms/Keyholder Room.txtpb index 9605fad..13c3dce 100644 --- a/data/maps/four_rooms/rooms/Keyholder Room.txtpb +++ b/data/maps/four_rooms/rooms/Keyholder Room.txtpb | |||
@@ -1,6 +1,6 @@ | |||
1 | name: "Keyholder Room" | 1 | name: "Keyholder Room" |
2 | display_name: "Hallway" | ||
3 | keyholders { | 2 | keyholders { |
4 | name: "A" | 3 | name: "A" |
5 | path: "Components/KeyHolders/keyHolderA" | 4 | path: "Components/KeyHolders/keyHolderA" |
5 | key: "a" | ||
6 | } | 6 | } |
diff --git a/data/maps/four_rooms/rooms/Synonyms Room.txtpb b/data/maps/four_rooms/rooms/Synonyms Room.txtpb index 054e4ef..bcbf64e 100644 --- a/data/maps/four_rooms/rooms/Synonyms Room.txtpb +++ b/data/maps/four_rooms/rooms/Synonyms Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Synonyms Room" | 1 | name: "Synonyms Room" |
2 | display_name: "Synonyms Room" | ||
3 | panels { | 2 | panels { |
4 | name: "MINUTE" | 3 | name: "MINUTE" |
5 | path: "Panels/Room 3 Synonyms/entry_1" | 4 | path: "Panels/Room 3 Synonyms/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "ENTRY" | 59 | name: "ENTRY" |
60 | display_name: "Synonyms Room Worldport" | ||
61 | path: "Components/Warps/worldport3" | 61 | path: "Components/Warps/worldport3" |
62 | orientation: "south" | 62 | destination { x: 20 y: 0 z: 6.5 } |
63 | rotation: 0 | ||
63 | } | 64 | } |
diff --git a/data/maps/four_rooms/rooms/Time Room.txtpb b/data/maps/four_rooms/rooms/Time Room.txtpb index 38f529d..74f951d 100644 --- a/data/maps/four_rooms/rooms/Time Room.txtpb +++ b/data/maps/four_rooms/rooms/Time Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Time Room" | 1 | name: "Time Room" |
2 | display_name: "Time Room" | ||
3 | panels { | 2 | panels { |
4 | name: "BROODING" | 3 | name: "BROODING" |
5 | path: "Panels/Room 4 Time/entry_1" | 4 | path: "Panels/Room 4 Time/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "OWL" | 59 | name: "OWL" |
60 | display_name: "Time Room Worldport" | ||
61 | path: "Components/Warps/worldport4" | 61 | path: "Components/Warps/worldport4" |
62 | orientation: "north" | 62 | destination { x: 20 y: 0 z: -40.5 } |
63 | rotation: 180 | ||
63 | } | 64 | } |
diff --git a/data/maps/the_ancient/doors.txtpb b/data/maps/the_ancient/doors.txtpb index 75c08f6..e550306 100644 --- a/data/maps/the_ancient/doors.txtpb +++ b/data/maps/the_ancient/doors.txtpb | |||
@@ -1,6 +1,7 @@ | |||
1 | doors { | 1 | doors { |
2 | name: "Front Door" | 2 | name: "Front Door" |
3 | type: STANDARD | 3 | type: STANDARD |
4 | receivers: "Components/Doors/Front N Tree" | ||
4 | panels { room: "Outside" name: "THIS" } | 5 | panels { room: "Outside" name: "THIS" } |
5 | location_room: "Outside" | 6 | location_room: "Outside" |
6 | } | 7 | } |
@@ -37,7 +38,8 @@ doors { | |||
37 | } | 38 | } |
38 | doors { | 39 | doors { |
39 | name: "Lavender Cubes" | 40 | name: "Lavender Cubes" |
40 | type: STANDARD | 41 | type: LOCATION_ONLY |
41 | panels { room: "Inside" name: "COLOR" } | 42 | panels { room: "Inside" name: "COLOR" } |
42 | location_room: "Inside" | 43 | location_room: "Inside" |
44 | location_name: "COLOR" | ||
43 | } | 45 | } |
diff --git a/data/maps/the_ancient/rooms/Ending.txtpb b/data/maps/the_ancient/rooms/Ending.txtpb index eea1228..df3fe01 100644 --- a/data/maps/the_ancient/rooms/Ending.txtpb +++ b/data/maps/the_ancient/rooms/Ending.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Ending" | 1 | name: "Ending" |
2 | display_name: "Ending" | ||
3 | endings { | 2 | endings { |
4 | name: "GREEN" | 3 | name: "GREEN" |
5 | path: "Components/Ending/green_ending" | 4 | path: "Components/Ending/green_ending" |
diff --git a/data/maps/the_ancient/rooms/Inside.txtpb b/data/maps/the_ancient/rooms/Inside.txtpb index d088682..3723b2d 100644 --- a/data/maps/the_ancient/rooms/Inside.txtpb +++ b/data/maps/the_ancient/rooms/Inside.txtpb | |||
@@ -1,10 +1,8 @@ | |||
1 | name: "Inside" | 1 | name: "Inside" |
2 | display_name: "Inside" | ||
3 | panels { | 2 | panels { |
4 | name: "COLOR" | 3 | name: "COLOR" |
5 | path: "Panels/panel_2" | 4 | path: "Panels/panel_2" |
6 | clue: "color" | 5 | clue: "color" |
7 | answer: "lavender" | 6 | answer: "lavender" |
8 | symbols: EXAMPLE | 7 | symbols: EXAMPLE |
9 | # TODO: how does this connect to the "lavender_cubes" switch? | ||
10 | } | 8 | } |
diff --git a/data/maps/the_ancient/rooms/Outside.txtpb b/data/maps/the_ancient/rooms/Outside.txtpb index 6f49bba..1458357 100644 --- a/data/maps/the_ancient/rooms/Outside.txtpb +++ b/data/maps/the_ancient/rooms/Outside.txtpb | |||
@@ -1,8 +1,8 @@ | |||
1 | name: "Outside" | 1 | name: "Outside" |
2 | display_name: "Outside" | ||
3 | panels { | 2 | panels { |
4 | name: "THIS" | 3 | name: "THIS" |
5 | path: "Panels/panel_1" | 4 | path: "Panels/panel_1" |
6 | clue: "this" | 5 | clue: "this" |
7 | answer: "sphinx" | 6 | answer: "sphinx" |
7 | symbols: QUESTION | ||
8 | } | 8 | } |
diff --git a/data/maps/the_bearer/connections.txtpb b/data/maps/the_bearer/connections.txtpb index 23410f0..ba14d83 100644 --- a/data/maps/the_bearer/connections.txtpb +++ b/data/maps/the_bearer/connections.txtpb | |||
@@ -263,3 +263,8 @@ connections { | |||
263 | to_room: "Butterfly Room" | 263 | to_room: "Butterfly Room" |
264 | door { name: "Butterfly Entrance" } | 264 | door { name: "Butterfly Entrance" } |
265 | } | 265 | } |
266 | connections { | ||
267 | from_room: "Back Area" | ||
268 | to_room: "Tree Entrance" | ||
269 | door { name: "Control Center Brown Door" } | ||
270 | } | ||
diff --git a/data/maps/the_bearer/doors.txtpb b/data/maps/the_bearer/doors.txtpb index 1faddef..f1f5a57 100644 --- a/data/maps/the_bearer/doors.txtpb +++ b/data/maps/the_bearer/doors.txtpb | |||
@@ -211,7 +211,7 @@ doors { | |||
211 | } | 211 | } |
212 | doors { | 212 | doors { |
213 | name: "Q2 Door" | 213 | name: "Q2 Door" |
214 | type: STANDARD | 214 | type: EVENT |
215 | receivers: "Components/Doors/entry_3" | 215 | receivers: "Components/Doors/entry_3" |
216 | panels { room: "Entry" name: "SQUISH" } | 216 | panels { room: "Entry" name: "SQUISH" } |
217 | panels { room: "Entry" name: "MANE" } | 217 | panels { room: "Entry" name: "MANE" } |
@@ -237,7 +237,6 @@ doors { | |||
237 | panels { room: "Red Vegetable" name: "CARD" } | 237 | panels { room: "Red Vegetable" name: "CARD" } |
238 | panels { room: "Yellow Planet" name: "ZEUS" } | 238 | panels { room: "Yellow Planet" name: "ZEUS" } |
239 | panels { room: "Yellow Vegetable" name: "CAKE" } | 239 | panels { room: "Yellow Vegetable" name: "CAKE" } |
240 | location_room: "Entry" | ||
241 | } | 240 | } |
242 | doors { | 241 | doors { |
243 | name: "Control Center Brown Door" | 242 | name: "Control Center Brown Door" |
@@ -249,5 +248,5 @@ doors { | |||
249 | name: "Butterfly Entrance" | 248 | name: "Butterfly Entrance" |
250 | type: ITEM_ONLY | 249 | type: ITEM_ONLY |
251 | receivers: "Components/Doors/brown_2" | 250 | receivers: "Components/Doors/brown_2" |
252 | switches: "double_letters" | 251 | double_letters: true |
253 | } | 252 | } |
diff --git a/data/maps/the_bearer/rooms/Back Area.txtpb b/data/maps/the_bearer/rooms/Back Area.txtpb index bd90b50..2be4cb4 100644 --- a/data/maps/the_bearer/rooms/Back Area.txtpb +++ b/data/maps/the_bearer/rooms/Back Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Back Area" | 1 | name: "Back Area" |
2 | display_name: "Back Area" | ||
3 | panels { | 2 | panels { |
4 | name: "COLOR" | 3 | name: "COLOR" |
5 | path: "Panels/Entry/panel_3" | 4 | path: "Panels/Entry/panel_3" |
@@ -8,13 +7,9 @@ panels { | |||
8 | symbols: EXAMPLE | 7 | symbols: EXAMPLE |
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "TREE" | ||
12 | path: "Components/Warps/worldport3" | ||
13 | orientation: "north" | ||
14 | required_door { name: "Control Center Brown Door" } | ||
15 | } | ||
16 | ports { | ||
17 | name: "DAEDALUS" | 10 | name: "DAEDALUS" |
11 | display_name: "Dark Hallway" | ||
18 | path: "Components/Warps/worldport2" | 12 | path: "Components/Warps/worldport2" |
19 | orientation: "north" | 13 | destination { x: 10 y: 0 z: -84.5 } |
14 | rotation: 180 | ||
20 | } | 15 | } |
diff --git a/data/maps/the_bearer/rooms/Blue Animal (View).txtpb b/data/maps/the_bearer/rooms/Blue Animal (View).txtpb index a13ce1d..33c278c 100644 --- a/data/maps/the_bearer/rooms/Blue Animal (View).txtpb +++ b/data/maps/the_bearer/rooms/Blue Animal (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Blue Animal (View)" | 1 | name: "Blue Animal (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "HALF" | 3 | name: "HALF" |
5 | path: "Panels/Blue/panel_2" | 4 | path: "Panels/Blue/panel_2" |
diff --git a/data/maps/the_bearer/rooms/Blue Animal.txtpb b/data/maps/the_bearer/rooms/Blue Animal.txtpb index 49ac048..e503c93 100644 --- a/data/maps/the_bearer/rooms/Blue Animal.txtpb +++ b/data/maps/the_bearer/rooms/Blue Animal.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Blue Animal" | name: "Blue Animal" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Blue Planet (View).txtpb b/data/maps/the_bearer/rooms/Blue Planet (View).txtpb index 172565b..e745718 100644 --- a/data/maps/the_bearer/rooms/Blue Planet (View).txtpb +++ b/data/maps/the_bearer/rooms/Blue Planet (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Blue Planet (View)" | 1 | name: "Blue Planet (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "TUNE" | 3 | name: "TUNE" |
5 | path: "Panels/Blue/panel_4" | 4 | path: "Panels/Blue/panel_4" |
diff --git a/data/maps/the_bearer/rooms/Blue Planet.txtpb b/data/maps/the_bearer/rooms/Blue Planet.txtpb index b291c35..b044590 100644 --- a/data/maps/the_bearer/rooms/Blue Planet.txtpb +++ b/data/maps/the_bearer/rooms/Blue Planet.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Blue Planet" | name: "Blue Planet" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Blue Town (View).txtpb b/data/maps/the_bearer/rooms/Blue Town (View).txtpb index f66eae9..f57fc9b 100644 --- a/data/maps/the_bearer/rooms/Blue Town (View).txtpb +++ b/data/maps/the_bearer/rooms/Blue Town (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Blue Town (View)" | 1 | name: "Blue Town (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "LICE" | 3 | name: "LICE" |
5 | path: "Panels/Blue/panel_3" | 4 | path: "Panels/Blue/panel_3" |
diff --git a/data/maps/the_bearer/rooms/Blue Town.txtpb b/data/maps/the_bearer/rooms/Blue Town.txtpb index b24af76..5ceed12 100644 --- a/data/maps/the_bearer/rooms/Blue Town.txtpb +++ b/data/maps/the_bearer/rooms/Blue Town.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Blue Town" | name: "Blue Town" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Blue Vegetable (View).txtpb b/data/maps/the_bearer/rooms/Blue Vegetable (View).txtpb index f9443fd..cf1ffd3 100644 --- a/data/maps/the_bearer/rooms/Blue Vegetable (View).txtpb +++ b/data/maps/the_bearer/rooms/Blue Vegetable (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Blue Vegetable (View)" | 1 | name: "Blue Vegetable (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "THORN" | 3 | name: "THORN" |
5 | path: "Panels/Blue/panel_1" | 4 | path: "Panels/Blue/panel_1" |
diff --git a/data/maps/the_bearer/rooms/Blue Vegetable.txtpb b/data/maps/the_bearer/rooms/Blue Vegetable.txtpb index 9034471..64ce77d 100644 --- a/data/maps/the_bearer/rooms/Blue Vegetable.txtpb +++ b/data/maps/the_bearer/rooms/Blue Vegetable.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Blue Vegetable" | name: "Blue Vegetable" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Butterfly Room.txtpb b/data/maps/the_bearer/rooms/Butterfly Room.txtpb index bd20505..a702737 100644 --- a/data/maps/the_bearer/rooms/Butterfly Room.txtpb +++ b/data/maps/the_bearer/rooms/Butterfly Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Butterfly Room" | 1 | name: "Butterfly Room" |
2 | display_name: "Back Area" | ||
3 | panels { | 2 | panels { |
4 | name: "VIBRANT" | 3 | name: "VIBRANT" |
5 | path: "Panels/Entry/panel_4" | 4 | path: "Panels/Entry/panel_4" |
diff --git a/data/maps/the_bearer/rooms/Entry.txtpb b/data/maps/the_bearer/rooms/Entry.txtpb index d7a8db6..517088d 100644 --- a/data/maps/the_bearer/rooms/Entry.txtpb +++ b/data/maps/the_bearer/rooms/Entry.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Entry" | 1 | name: "Entry" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "VIEW" | 3 | name: "VIEW" |
5 | path: "Panels/Entry/panel_1" | 4 | path: "Panels/Entry/panel_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "UNYIELDING" | 59 | name: "UNYIELDING" |
60 | display_name: "Main Entrance" | ||
61 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | orientation: "east" | 62 | destination { x: 3 y: 4 z: 15 } |
63 | rotation: 90 | ||
63 | } | 64 | } |
diff --git a/data/maps/the_bearer/rooms/Green Animal.txtpb b/data/maps/the_bearer/rooms/Green Animal.txtpb index 61522cc..147f825 100644 --- a/data/maps/the_bearer/rooms/Green Animal.txtpb +++ b/data/maps/the_bearer/rooms/Green Animal.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Green Animal" | name: "Green Animal" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Green Planet (View).txtpb b/data/maps/the_bearer/rooms/Green Planet (View).txtpb index 79363bc..4d9f449 100644 --- a/data/maps/the_bearer/rooms/Green Planet (View).txtpb +++ b/data/maps/the_bearer/rooms/Green Planet (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Green Planet (View)" | 1 | name: "Green Planet (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "SOIL" | 3 | name: "SOIL" |
5 | path: "Panels/Green/panel_4" | 4 | path: "Panels/Green/panel_4" |
diff --git a/data/maps/the_bearer/rooms/Green Planet.txtpb b/data/maps/the_bearer/rooms/Green Planet.txtpb index b97b731..efe000a 100644 --- a/data/maps/the_bearer/rooms/Green Planet.txtpb +++ b/data/maps/the_bearer/rooms/Green Planet.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Green Planet" | name: "Green Planet" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Green Town.txtpb b/data/maps/the_bearer/rooms/Green Town.txtpb index 184ded3..fd80201 100644 --- a/data/maps/the_bearer/rooms/Green Town.txtpb +++ b/data/maps/the_bearer/rooms/Green Town.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Green Town" | name: "Green Town" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Green Vegetable (View).txtpb b/data/maps/the_bearer/rooms/Green Vegetable (View).txtpb index 4bbab5d..98fbbe8 100644 --- a/data/maps/the_bearer/rooms/Green Vegetable (View).txtpb +++ b/data/maps/the_bearer/rooms/Green Vegetable (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Green Vegetable (View)" | 1 | name: "Green Vegetable (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "SPIN" | 3 | name: "SPIN" |
5 | path: "Panels/Green/panel_1" | 4 | path: "Panels/Green/panel_1" |
diff --git a/data/maps/the_bearer/rooms/Green Vegetable.txtpb b/data/maps/the_bearer/rooms/Green Vegetable.txtpb index ccb817a..051a6d3 100644 --- a/data/maps/the_bearer/rooms/Green Vegetable.txtpb +++ b/data/maps/the_bearer/rooms/Green Vegetable.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Green Vegetable" | name: "Green Vegetable" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Orange Planet.txtpb b/data/maps/the_bearer/rooms/Orange Planet.txtpb index 0fbd929..15fae66 100644 --- a/data/maps/the_bearer/rooms/Orange Planet.txtpb +++ b/data/maps/the_bearer/rooms/Orange Planet.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Orange Planet" | 1 | name: "Orange Planet" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "MAR" | 3 | name: "MAR" |
5 | path: "Panels/Red/panel_4" | 4 | path: "Panels/Red/panel_4" |
diff --git a/data/maps/the_bearer/rooms/Orange Vegetable.txtpb b/data/maps/the_bearer/rooms/Orange Vegetable.txtpb index d4f7b82..e4d59e6 100644 --- a/data/maps/the_bearer/rooms/Orange Vegetable.txtpb +++ b/data/maps/the_bearer/rooms/Orange Vegetable.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Orange Vegetable" | 1 | name: "Orange Vegetable" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "POTATO" | 3 | name: "POTATO" |
5 | path: "Panels/Red/panel_1" | 4 | path: "Panels/Red/panel_1" |
diff --git a/data/maps/the_bearer/rooms/Overlook.txtpb b/data/maps/the_bearer/rooms/Overlook.txtpb index 384802c..9eadf8f 100644 --- a/data/maps/the_bearer/rooms/Overlook.txtpb +++ b/data/maps/the_bearer/rooms/Overlook.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Overlook" | name: "Overlook" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Purple Animal (View).txtpb b/data/maps/the_bearer/rooms/Purple Animal (View).txtpb index 7122059..04ae0f8 100644 --- a/data/maps/the_bearer/rooms/Purple Animal (View).txtpb +++ b/data/maps/the_bearer/rooms/Purple Animal (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Purple Animal (View)" | 1 | name: "Purple Animal (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "SUNBASS" | 3 | name: "SUNBASS" |
5 | path: "Panels/Purple/panel_2" | 4 | path: "Panels/Purple/panel_2" |
diff --git a/data/maps/the_bearer/rooms/Purple Animal.txtpb b/data/maps/the_bearer/rooms/Purple Animal.txtpb index 9ddb70e..1c3a52c 100644 --- a/data/maps/the_bearer/rooms/Purple Animal.txtpb +++ b/data/maps/the_bearer/rooms/Purple Animal.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Purple Animal" | name: "Purple Animal" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Purple Planet (View).txtpb b/data/maps/the_bearer/rooms/Purple Planet (View).txtpb index 4ab506d..bacfae6 100644 --- a/data/maps/the_bearer/rooms/Purple Planet (View).txtpb +++ b/data/maps/the_bearer/rooms/Purple Planet (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Purple Planet (View)" | 1 | name: "Purple Planet (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "DOG" | 3 | name: "DOG" |
5 | path: "Panels/Purple/panel_4" | 4 | path: "Panels/Purple/panel_4" |
diff --git a/data/maps/the_bearer/rooms/Purple Planet.txtpb b/data/maps/the_bearer/rooms/Purple Planet.txtpb index 37f7ddc..03021d5 100644 --- a/data/maps/the_bearer/rooms/Purple Planet.txtpb +++ b/data/maps/the_bearer/rooms/Purple Planet.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Purple Planet" | name: "Purple Planet" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Purple Town (View).txtpb b/data/maps/the_bearer/rooms/Purple Town (View).txtpb index 40927f4..855e3ea 100644 --- a/data/maps/the_bearer/rooms/Purple Town (View).txtpb +++ b/data/maps/the_bearer/rooms/Purple Town (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Purple Town (View)" | 1 | name: "Purple Town (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "GRACEFUL" | 3 | name: "GRACEFUL" |
5 | path: "Panels/Purple/panel_3" | 4 | path: "Panels/Purple/panel_3" |
diff --git a/data/maps/the_bearer/rooms/Purple Town.txtpb b/data/maps/the_bearer/rooms/Purple Town.txtpb index 768f378..b077178 100644 --- a/data/maps/the_bearer/rooms/Purple Town.txtpb +++ b/data/maps/the_bearer/rooms/Purple Town.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Purple Town" | name: "Purple Town" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Purple Vegetable (View).txtpb b/data/maps/the_bearer/rooms/Purple Vegetable (View).txtpb index 182a5bb..1a6ab04 100644 --- a/data/maps/the_bearer/rooms/Purple Vegetable (View).txtpb +++ b/data/maps/the_bearer/rooms/Purple Vegetable (View).txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Purple Vegetable (View)" | 1 | name: "Purple Vegetable (View)" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "AUBERGINE" | 3 | name: "AUBERGINE" |
5 | path: "Panels/Purple/panel_1" | 4 | path: "Panels/Purple/panel_1" |
diff --git a/data/maps/the_bearer/rooms/Purple Vegetable.txtpb b/data/maps/the_bearer/rooms/Purple Vegetable.txtpb index ef5dd7e..380b909 100644 --- a/data/maps/the_bearer/rooms/Purple Vegetable.txtpb +++ b/data/maps/the_bearer/rooms/Purple Vegetable.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Purple Vegetable" | name: "Purple Vegetable" | |
2 | display_name: "Main Area" | ||
diff --git a/data/maps/the_bearer/rooms/Q2 Room.txtpb b/data/maps/the_bearer/rooms/Q2 Room.txtpb index ab5032a..5cdea80 100644 --- a/data/maps/the_bearer/rooms/Q2 Room.txtpb +++ b/data/maps/the_bearer/rooms/Q2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Q2 Room" | 1 | name: "Q2 Room" |
2 | display_name: "Back Area" | ||
3 | letters { | 2 | letters { |
4 | key: "q" | 3 | key: "q" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_bearer/rooms/Red Animal.txtpb b/data/maps/the_bearer/rooms/Red Animal.txtpb index 845fbed..d5ae244 100644 --- a/data/maps/the_bearer/rooms/Red Animal.txtpb +++ b/data/maps/the_bearer/rooms/Red Animal.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Red Animal" | 1 | name: "Red Animal" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "FOOLSHARK" | 3 | name: "FOOLSHARK" |
5 | path: "Panels/Orange/panel_2" | 4 | path: "Panels/Orange/panel_2" |
diff --git a/data/maps/the_bearer/rooms/Red Planet.txtpb b/data/maps/the_bearer/rooms/Red Planet.txtpb index 55a105d..dd3f2ec 100644 --- a/data/maps/the_bearer/rooms/Red Planet.txtpb +++ b/data/maps/the_bearer/rooms/Red Planet.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Red Planet" | 1 | name: "Red Planet" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "FUEL" | 3 | name: "FUEL" |
5 | path: "Panels/Red/panel_3" | 4 | path: "Panels/Red/panel_3" |
diff --git a/data/maps/the_bearer/rooms/Red Town.txtpb b/data/maps/the_bearer/rooms/Red Town.txtpb index 8a29ced..ed608cc 100644 --- a/data/maps/the_bearer/rooms/Red Town.txtpb +++ b/data/maps/the_bearer/rooms/Red Town.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Red Town" | 1 | name: "Red Town" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "DESTRUCTION" | 3 | name: "DESTRUCTION" |
5 | path: "Panels/Orange/panel_3" | 4 | path: "Panels/Orange/panel_3" |
diff --git a/data/maps/the_bearer/rooms/Red Vegetable.txtpb b/data/maps/the_bearer/rooms/Red Vegetable.txtpb index 1494e26..fb694db 100644 --- a/data/maps/the_bearer/rooms/Red Vegetable.txtpb +++ b/data/maps/the_bearer/rooms/Red Vegetable.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Red Vegetable" | 1 | name: "Red Vegetable" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "CARD" | 3 | name: "CARD" |
5 | path: "Panels/Red/panel_2" | 4 | path: "Panels/Red/panel_2" |
diff --git a/data/maps/the_bearer/rooms/Tree Entrance.txtpb b/data/maps/the_bearer/rooms/Tree Entrance.txtpb new file mode 100644 index 0000000..1b50ddd --- /dev/null +++ b/data/maps/the_bearer/rooms/Tree Entrance.txtpb | |||
@@ -0,0 +1,8 @@ | |||
1 | name: "Tree Entrance" | ||
2 | ports { | ||
3 | name: "TREE" | ||
4 | display_name: "Brown Hallway" | ||
5 | path: "Components/Warps/worldport3" | ||
6 | destination { x: -19 y: 0 z: -83.5 } | ||
7 | rotation: 180 | ||
8 | } | ||
diff --git a/data/maps/the_bearer/rooms/Yellow Planet.txtpb b/data/maps/the_bearer/rooms/Yellow Planet.txtpb index 9c6d39d..7f8a86b 100644 --- a/data/maps/the_bearer/rooms/Yellow Planet.txtpb +++ b/data/maps/the_bearer/rooms/Yellow Planet.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Yellow Planet" | 1 | name: "Yellow Planet" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "ZEUS" | 3 | name: "ZEUS" |
5 | path: "Panels/Orange/panel_4" | 4 | path: "Panels/Orange/panel_4" |
diff --git a/data/maps/the_bearer/rooms/Yellow Vegetable.txtpb b/data/maps/the_bearer/rooms/Yellow Vegetable.txtpb index 26ef491..f37faa5 100644 --- a/data/maps/the_bearer/rooms/Yellow Vegetable.txtpb +++ b/data/maps/the_bearer/rooms/Yellow Vegetable.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Yellow Vegetable" | 1 | name: "Yellow Vegetable" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "CAKE" | 3 | name: "CAKE" |
5 | path: "Panels/Orange/panel_1" | 4 | path: "Panels/Orange/panel_1" |
diff --git a/data/maps/the_between/rooms/B2 Back Room.txtpb b/data/maps/the_between/rooms/B2 Back Room.txtpb index 132ba56..0972ed9 100644 --- a/data/maps/the_between/rooms/B2 Back Room.txtpb +++ b/data/maps/the_between/rooms/B2 Back Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "B2 Back Room" | 1 | name: "B2 Back Room" |
2 | display_name: "B2 Room" | ||
3 | letters { | 2 | letters { |
4 | key: "b" | 3 | key: "b" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_between/rooms/B2 Front Room.txtpb b/data/maps/the_between/rooms/B2 Front Room.txtpb index 02c09fb..f23ed20 100644 --- a/data/maps/the_between/rooms/B2 Front Room.txtpb +++ b/data/maps/the_between/rooms/B2 Front Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "B2 Front Room" | 1 | name: "B2 Front Room" |
2 | display_name: "B2 Room" | ||
3 | paintings { | 2 | paintings { |
4 | name: "EYES" | 3 | name: "EYES" |
5 | path: "Components/Paintings/eyes" | 4 | path: "Components/Paintings/eyes" |
diff --git a/data/maps/the_between/rooms/Control Center Side.txtpb b/data/maps/the_between/rooms/Control Center Side.txtpb index 81bae60..b308586 100644 --- a/data/maps/the_between/rooms/Control Center Side.txtpb +++ b/data/maps/the_between/rooms/Control Center Side.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Control Center Side" | 1 | name: "Control Center Side" |
2 | display_name: "Control Center Side" | ||
3 | panels { | 2 | panels { |
4 | name: "RIGHT" | 3 | name: "RIGHT" |
5 | path: "Panels/Helpers/panel_1" | 4 | path: "Panels/Helpers/panel_1" |
@@ -14,11 +13,15 @@ paintings { | |||
14 | } | 13 | } |
15 | ports { | 14 | ports { |
16 | name: "CC" | 15 | name: "CC" |
16 | display_name: "Lavender Structure" | ||
17 | path: "Components/Warps/worldport3" | 17 | path: "Components/Warps/worldport3" |
18 | orientation: "north" | 18 | destination { x: 36 y: 0 z: 1 } |
19 | rotation: 180 | ||
19 | } | 20 | } |
20 | ports { | 21 | ports { |
21 | name: "LIVELY" | 22 | name: "LIVELY" |
23 | display_name: "Near Painting Worldport" | ||
22 | path: "Components/Warps/worldport2" | 24 | path: "Components/Warps/worldport2" |
23 | orientation: "south" | 25 | destination { x: 24 y: 0 z: 6.5 } |
26 | rotation: 0 | ||
24 | } | 27 | } |
diff --git a/data/maps/the_between/rooms/Main Area.txtpb b/data/maps/the_between/rooms/Main Area.txtpb index a8e15a9..898b265 100644 --- a/data/maps/the_between/rooms/Main Area.txtpb +++ b/data/maps/the_between/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "NEW" | 3 | name: "NEW" |
5 | path: "Panels/Room 1/panel_1" | 4 | path: "Panels/Room 1/panel_1" |
@@ -198,6 +197,8 @@ panels { | |||
198 | } | 197 | } |
199 | ports { | 198 | ports { |
200 | name: "GREAT" | 199 | name: "GREAT" |
200 | display_name: "Salmon Hallway" | ||
201 | path: "Components/Warps/worldport" | 201 | path: "Components/Warps/worldport" |
202 | orientation: "east" | 202 | destination { x: -1 y: 0 z: 20 } |
203 | rotation: 90 | ||
203 | } | 204 | } |
diff --git a/data/maps/the_between/rooms/Plaza Entrance.txtpb b/data/maps/the_between/rooms/Plaza Entrance.txtpb index b99081a..894ebae 100644 --- a/data/maps/the_between/rooms/Plaza Entrance.txtpb +++ b/data/maps/the_between/rooms/Plaza Entrance.txtpb | |||
@@ -1,7 +1,8 @@ | |||
1 | name: "Plaza Entrance" | 1 | name: "Plaza Entrance" |
2 | display_name: "Main Area" | ||
3 | ports { | 2 | ports { |
4 | name: "PLAZA" | 3 | name: "PLAZA" |
4 | display_name: "Trick or Treat Worldport" | ||
5 | path: "Components/Warps/worldport4" | 5 | path: "Components/Warps/worldport4" |
6 | orientation: "north" | 6 | destination { x: -38 y: 0 z: 1 } |
7 | rotation: 180 | ||
7 | } | 8 | } |
diff --git a/data/maps/the_butterfly/rooms/Main Area.txtpb b/data/maps/the_butterfly/rooms/Main Area.txtpb index 9a8b3d5..453e64a 100644 --- a/data/maps/the_butterfly/rooms/Main Area.txtpb +++ b/data/maps/the_butterfly/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "SPECIES" | 3 | name: "SPECIES" |
5 | path: "Panels/Room_1/panel_1" | 4 | path: "Panels/Room_1/panel_1" |
@@ -128,6 +127,8 @@ panels { | |||
128 | } | 127 | } |
129 | ports { | 128 | ports { |
130 | name: "GALLERY" | 129 | name: "GALLERY" |
130 | display_name: "Worldport" | ||
131 | path: "Components/Warps/worldport" | 131 | path: "Components/Warps/worldport" |
132 | orientation: "southwest" # uhhhh this is new | 132 | destination { x: -19 y: 0 z: 19 } |
133 | rotation: 315 | ||
133 | } | 134 | } |
diff --git a/data/maps/the_butterfly/rooms/Mastery.txtpb b/data/maps/the_butterfly/rooms/Mastery.txtpb index f494fde..bbe8742 100644 --- a/data/maps/the_butterfly/rooms/Mastery.txtpb +++ b/data/maps/the_butterfly/rooms/Mastery.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Mastery" | 1 | name: "Mastery" |
2 | display_name: "Main Area" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/collectable" | 4 | path: "Components/Collectables/collectable" |
diff --git a/data/maps/the_colorful/doors.txtpb b/data/maps/the_colorful/doors.txtpb index 32470b2..003c9a9 100644 --- a/data/maps/the_colorful/doors.txtpb +++ b/data/maps/the_colorful/doors.txtpb | |||
@@ -46,13 +46,14 @@ doors { | |||
46 | type: STANDARD | 46 | type: STANDARD |
47 | receivers: "Components/Doors/entry_7" | 47 | receivers: "Components/Doors/entry_7" |
48 | panels { room: "Yellow Room" name: "CIRCLE" } | 48 | panels { room: "Yellow Room" name: "CIRCLE" } |
49 | panels { room: "Purple Room" name: "FISH" } | 49 | panels { room: "Purple Room" name: "FISH" answer: "fish" } |
50 | location_room: "Purple Room" | 50 | location_room: "Purple Room" |
51 | } | 51 | } |
52 | doors { | 52 | doors { |
53 | name: "Purple Side Entrance" | 53 | name: "Purple Side Entrance" |
54 | type: STANDARD | 54 | type: STANDARD |
55 | receivers: "Components/Doors/entry_7b3" | 55 | receivers: "Components/Doors/entry_7b3" |
56 | receivers: "Components/Doors/entry_7b4" | ||
56 | panels { room: "Cyan Hallway" name: "KOI" } | 57 | panels { room: "Cyan Hallway" name: "KOI" } |
57 | panels { room: "Cyan Hallway" name: "WISH" } | 58 | panels { room: "Cyan Hallway" name: "WISH" } |
58 | location_room: "Cyan Hallway" | 59 | location_room: "Cyan Hallway" |
diff --git a/data/maps/the_colorful/rooms/Black Room.txtpb b/data/maps/the_colorful/rooms/Black Room.txtpb index 75aec81..21a0d41 100644 --- a/data/maps/the_colorful/rooms/Black Room.txtpb +++ b/data/maps/the_colorful/rooms/Black Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Black Room" | 1 | name: "Black Room" |
2 | display_name: "Black Room" | ||
3 | panels { | 2 | panels { |
4 | name: "STARK" | 3 | name: "STARK" |
5 | path: "Panels/Hallway/panel_2" | 4 | path: "Panels/Hallway/panel_2" |
diff --git a/data/maps/the_colorful/rooms/Blue Room.txtpb b/data/maps/the_colorful/rooms/Blue Room.txtpb index c334f6e..ec9337d 100644 --- a/data/maps/the_colorful/rooms/Blue Room.txtpb +++ b/data/maps/the_colorful/rooms/Blue Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Blue Room" | 1 | name: "Blue Room" |
2 | display_name: "Blue Room" | ||
3 | panels { | 2 | panels { |
4 | name: "VINE" | 3 | name: "VINE" |
5 | path: "Panels/Hallway/panel_4" | 4 | path: "Panels/Hallway/panel_4" |
diff --git a/data/maps/the_colorful/rooms/Brown Room.txtpb b/data/maps/the_colorful/rooms/Brown Room.txtpb index 8eec879..a5f590b 100644 --- a/data/maps/the_colorful/rooms/Brown Room.txtpb +++ b/data/maps/the_colorful/rooms/Brown Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Brown Room" | 1 | name: "Brown Room" |
2 | display_name: "Brown Room" | ||
3 | panels { | 2 | panels { |
4 | name: "FIRE" | 3 | name: "FIRE" |
5 | path: "Panels/Hallway/panel_9" | 4 | path: "Panels/Hallway/panel_9" |
diff --git a/data/maps/the_colorful/rooms/Cyan Hallway.txtpb b/data/maps/the_colorful/rooms/Cyan Hallway.txtpb index d6a2425..d94a0a6 100644 --- a/data/maps/the_colorful/rooms/Cyan Hallway.txtpb +++ b/data/maps/the_colorful/rooms/Cyan Hallway.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Cyan Hallway" | 1 | name: "Cyan Hallway" |
2 | display_name: "Cyan Hallway" | ||
3 | panels { | 2 | panels { |
4 | name: "KOI" | 3 | name: "KOI" |
5 | path: "Panels/Extra/panel_12" | 4 | path: "Panels/Extra/panel_12" |
@@ -24,11 +23,15 @@ panels { | |||
24 | } | 23 | } |
25 | ports { | 24 | ports { |
26 | name: "STURDY" | 25 | name: "STURDY" |
26 | display_name: "North Cyan Worldport" | ||
27 | path: "Components/Warps/worldport3" | 27 | path: "Components/Warps/worldport3" |
28 | orientation: "west" | 28 | destination { x: -17 y: 0 z: -75 } |
29 | rotation: 270 | ||
29 | } | 30 | } |
30 | ports { | 31 | ports { |
31 | name: "DARKROOM" | 32 | name: "DARKROOM" |
33 | display_name: "South Cyan Worldport" | ||
32 | path: "Components/Warps/worldport2" | 34 | path: "Components/Warps/worldport2" |
33 | orientation: "west" | 35 | destination { x: -17 y: 0 z: -51 } |
36 | rotation: 270 | ||
34 | } | 37 | } |
diff --git a/data/maps/the_colorful/rooms/Cyan Room.txtpb b/data/maps/the_colorful/rooms/Cyan Room.txtpb index 09150ab..3568ec1 100644 --- a/data/maps/the_colorful/rooms/Cyan Room.txtpb +++ b/data/maps/the_colorful/rooms/Cyan Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Cyan Room" | 1 | name: "Cyan Room" |
2 | display_name: "Cyan Room" | ||
3 | panels { | 2 | panels { |
4 | name: "BROTHER" | 3 | name: "BROTHER" |
5 | path: "Panels/Cyan/panel_cyan_1" | 4 | path: "Panels/Cyan/panel_cyan_1" |
diff --git a/data/maps/the_colorful/rooms/Ending.txtpb b/data/maps/the_colorful/rooms/Ending.txtpb index 060e72e..3aa2b3c 100644 --- a/data/maps/the_colorful/rooms/Ending.txtpb +++ b/data/maps/the_colorful/rooms/Ending.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Ending" | 1 | name: "Ending" |
2 | display_name: "Ending" | ||
3 | endings { | 2 | endings { |
4 | name: "GRAY" | 3 | name: "GRAY" |
5 | path: "Components/Endings/gray_ending" | 4 | path: "Components/Endings/gray_ending" |
diff --git a/data/maps/the_colorful/rooms/Gray Room.txtpb b/data/maps/the_colorful/rooms/Gray Room.txtpb index 9d62ebf..6ae6c9c 100644 --- a/data/maps/the_colorful/rooms/Gray Room.txtpb +++ b/data/maps/the_colorful/rooms/Gray Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Gray Room" | 1 | name: "Gray Room" |
2 | display_name: "Gray Room" | ||
3 | panels { | 2 | panels { |
4 | name: "MEND" | 3 | name: "MEND" |
5 | path: "Panels/Hallway/panel_11" | 4 | path: "Panels/Hallway/panel_11" |
diff --git a/data/maps/the_colorful/rooms/Green Room.txtpb b/data/maps/the_colorful/rooms/Green Room.txtpb index 3e9dfd5..e438176 100644 --- a/data/maps/the_colorful/rooms/Green Room.txtpb +++ b/data/maps/the_colorful/rooms/Green Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Green Room" | 1 | name: "Green Room" |
2 | display_name: "Green Room" | ||
3 | panels { | 2 | panels { |
4 | name: "MOTHER" | 3 | name: "MOTHER" |
5 | path: "Panels/Hallway/panel_5" | 4 | path: "Panels/Hallway/panel_5" |
diff --git a/data/maps/the_colorful/rooms/Orange Room.txtpb b/data/maps/the_colorful/rooms/Orange Room.txtpb index b8aa5f8..6728080 100644 --- a/data/maps/the_colorful/rooms/Orange Room.txtpb +++ b/data/maps/the_colorful/rooms/Orange Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Orange Room" | 1 | name: "Orange Room" |
2 | display_name: "Orange Room" | ||
3 | panels { | 2 | panels { |
4 | name: "CLOUD" | 3 | name: "CLOUD" |
5 | path: "Panels/Hallway/panel_8" | 4 | path: "Panels/Hallway/panel_8" |
diff --git a/data/maps/the_colorful/rooms/P2 Room.txtpb b/data/maps/the_colorful/rooms/P2 Room.txtpb index 85dbf20..054d4b4 100644 --- a/data/maps/the_colorful/rooms/P2 Room.txtpb +++ b/data/maps/the_colorful/rooms/P2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "P2 Room" | 1 | name: "P2 Room" |
2 | display_name: "Cyan Room" | ||
3 | letters { | 2 | letters { |
4 | key: "p" | 3 | key: "p" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_colorful/rooms/Purple Room.txtpb b/data/maps/the_colorful/rooms/Purple Room.txtpb index 4175c8d..71b6ad6 100644 --- a/data/maps/the_colorful/rooms/Purple Room.txtpb +++ b/data/maps/the_colorful/rooms/Purple Room.txtpb | |||
@@ -1,10 +1,10 @@ | |||
1 | name: "Purple Room" | 1 | name: "Purple Room" |
2 | display_name: "Purple Room" | ||
3 | panels { | 2 | panels { |
4 | name: "FISH" | 3 | name: "FISH" |
5 | path: "Panels/Hallway/panel_7" | 4 | path: "Panels/Hallway/panel_7" |
6 | clue: "fish" | 5 | clue: "fish" |
7 | answer: "fish" | 6 | answer: "fish" |
8 | symbols: PLANET | 7 | symbols: PLANET |
8 | proxies { answer: "fish" path: "Panels/Hallway/panel_7a" } | ||
9 | proxies { answer: "fishes" path: "Panels/Hallway/panel_7b" } | 9 | proxies { answer: "fishes" path: "Panels/Hallway/panel_7b" } |
10 | } | 10 | } |
diff --git a/data/maps/the_colorful/rooms/Red Room.txtpb b/data/maps/the_colorful/rooms/Red Room.txtpb index 4d262e4..53bbd3a 100644 --- a/data/maps/the_colorful/rooms/Red Room.txtpb +++ b/data/maps/the_colorful/rooms/Red Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Red Room" | 1 | name: "Red Room" |
2 | display_name: "Red Room" | ||
3 | panels { | 2 | panels { |
4 | name: "SANDWICH" | 3 | name: "SANDWICH" |
5 | path: "Panels/Hallway/panel_3" | 4 | path: "Panels/Hallway/panel_3" |
diff --git a/data/maps/the_colorful/rooms/White Room.txtpb b/data/maps/the_colorful/rooms/White Room.txtpb index 497ecff..73557ed 100644 --- a/data/maps/the_colorful/rooms/White Room.txtpb +++ b/data/maps/the_colorful/rooms/White Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "White Room" | 1 | name: "White Room" |
2 | display_name: "White Room" | ||
3 | panels { | 2 | panels { |
4 | name: "BRIGHT" | 3 | name: "BRIGHT" |
5 | path: "Panels/Hallway/panel_1" | 4 | path: "Panels/Hallway/panel_1" |
@@ -9,6 +8,8 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "GREAT" | 10 | name: "GREAT" |
11 | display_name: "Main Entrance" | ||
12 | path: "Components/Warps/worldport" | 12 | path: "Components/Warps/worldport" |
13 | orientation: "west" | 13 | destination { x: -3.5 y: 0 z: 19 } |
14 | rotation: 270 | ||
14 | } | 15 | } |
diff --git a/data/maps/the_colorful/rooms/Window Room.txtpb b/data/maps/the_colorful/rooms/Window Room.txtpb index 9e3f8f4..e11d88c 100644 --- a/data/maps/the_colorful/rooms/Window Room.txtpb +++ b/data/maps/the_colorful/rooms/Window Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Window Room" | 1 | name: "Window Room" |
2 | display_name: "Window Room" | ||
3 | panels { | 2 | panels { |
4 | name: "FADING" | 3 | name: "FADING" |
5 | path: "Panels/Hallway/panel_10" | 4 | path: "Panels/Hallway/panel_10" |
diff --git a/data/maps/the_colorful/rooms/Yellow Room.txtpb b/data/maps/the_colorful/rooms/Yellow Room.txtpb index c65e886..40a4b14 100644 --- a/data/maps/the_colorful/rooms/Yellow Room.txtpb +++ b/data/maps/the_colorful/rooms/Yellow Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Yellow Room" | 1 | name: "Yellow Room" |
2 | display_name: "Yellow Room" | ||
3 | panels { | 2 | panels { |
4 | name: "CIRCLE" | 3 | name: "CIRCLE" |
5 | path: "Panels/Hallway/panel_6" | 4 | path: "Panels/Hallway/panel_6" |
diff --git a/data/maps/the_congruent/doors.txtpb b/data/maps/the_congruent/doors.txtpb index 7c21f55..a714eba 100644 --- a/data/maps/the_congruent/doors.txtpb +++ b/data/maps/the_congruent/doors.txtpb | |||
@@ -17,6 +17,7 @@ doors { | |||
17 | panels { room: "Main Area" name: "LABS (1)" } | 17 | panels { room: "Main Area" name: "LABS (1)" } |
18 | panels { room: "Main Area" name: "LABS (2)" } | 18 | panels { room: "Main Area" name: "LABS (2)" } |
19 | location_room: "Main Area" | 19 | location_room: "Main Area" |
20 | location_name: "Obverse Cyan Large Room" | ||
20 | } | 21 | } |
21 | doors { | 22 | doors { |
22 | name: "Flipped Yellow Door" | 23 | name: "Flipped Yellow Door" |
@@ -33,6 +34,7 @@ doors { | |||
33 | panels { room: "Flipped Magenta Room" name: "LUST" } | 34 | panels { room: "Flipped Magenta Room" name: "LUST" } |
34 | panels { room: "Flipped Magenta Room" name: "LAND" } | 35 | panels { room: "Flipped Magenta Room" name: "LAND" } |
35 | location_room: "Flipped Magenta Room" | 36 | location_room: "Flipped Magenta Room" |
37 | location_name: "Flipped Magenta Room" | ||
36 | } | 38 | } |
37 | doors { | 39 | doors { |
38 | name: "C Keyholder Blocker" | 40 | name: "C Keyholder Blocker" |
@@ -47,6 +49,7 @@ doors { | |||
47 | panels { room: "Flipped Yellow Room" name: "CAVE (1)" } | 49 | panels { room: "Flipped Yellow Room" name: "CAVE (1)" } |
48 | panels { room: "Flipped Yellow Room" name: "CAVE (2)" } | 50 | panels { room: "Flipped Yellow Room" name: "CAVE (2)" } |
49 | location_room: "Flipped Yellow Room" | 51 | location_room: "Flipped Yellow Room" |
52 | location_name: "Flipped Yellow Room" | ||
50 | } | 53 | } |
51 | doors { | 54 | doors { |
52 | name: "C2 Door" | 55 | name: "C2 Door" |
@@ -59,6 +62,7 @@ doors { | |||
59 | key: "c" | 62 | key: "c" |
60 | } | 63 | } |
61 | location_room: "C Keyholder" | 64 | location_room: "C Keyholder" |
65 | location_name: "C Keyholder" | ||
62 | } | 66 | } |
63 | doors { | 67 | doors { |
64 | name: "Obverse Yellow Door" | 68 | name: "Obverse Yellow Door" |
@@ -111,10 +115,15 @@ doors { | |||
111 | key: "g" | 115 | key: "g" |
112 | } | 116 | } |
113 | location_room: "G Keyholder" | 117 | location_room: "G Keyholder" |
118 | location_name: "G Keyholder" | ||
114 | } | 119 | } |
115 | doors { | 120 | doors { |
116 | name: "T Keyholder Blocker" | 121 | name: "T Keyholder Blocker" |
117 | type: ITEM_ONLY | 122 | type: EVENT |
118 | receivers: "Components/Doors/magenta_enterer3" | 123 | receivers: "Components/Doors/magenta_enterer3" |
119 | switches: "lavender_cubes" | 124 | panels { |
125 | map: "the_ancient" | ||
126 | room: "Inside" | ||
127 | name: "COLOR" | ||
128 | } | ||
120 | } | 129 | } |
diff --git a/data/maps/the_congruent/rooms/C Keyholder.txtpb b/data/maps/the_congruent/rooms/C Keyholder.txtpb index 0af0f32..75ef920 100644 --- a/data/maps/the_congruent/rooms/C Keyholder.txtpb +++ b/data/maps/the_congruent/rooms/C Keyholder.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "C Keyholder" | 1 | name: "C Keyholder" |
2 | display_name: "Main Area" | ||
3 | keyholders { | 2 | keyholders { |
4 | name: "C" | 3 | name: "C" |
5 | path: "Components/KeyHolders/keyHolder" | 4 | path: "Components/KeyHolders/keyHolder" |
diff --git a/data/maps/the_congruent/rooms/C2 Room.txtpb b/data/maps/the_congruent/rooms/C2 Room.txtpb index 852d4e2..ff53ebd 100644 --- a/data/maps/the_congruent/rooms/C2 Room.txtpb +++ b/data/maps/the_congruent/rooms/C2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "C2 Room" | 1 | name: "C2 Room" |
2 | display_name: "Main Area" | ||
3 | letters { | 2 | letters { |
4 | key: "c" | 3 | key: "c" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_congruent/rooms/Flipped Magenta Room.txtpb b/data/maps/the_congruent/rooms/Flipped Magenta Room.txtpb index 402e9e0..a51b667 100644 --- a/data/maps/the_congruent/rooms/Flipped Magenta Room.txtpb +++ b/data/maps/the_congruent/rooms/Flipped Magenta Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Magenta Room" | 1 | name: "Flipped Magenta Room" |
2 | display_name: "Flipped Magenta Room" | ||
3 | panels { | 2 | panels { |
4 | name: "LOOK" | 3 | name: "LOOK" |
5 | path: "Panels/Side Up 1/panel_1" | 4 | path: "Panels/Side Up 1/panel_1" |
diff --git a/data/maps/the_congruent/rooms/Flipped Yellow Room.txtpb b/data/maps/the_congruent/rooms/Flipped Yellow Room.txtpb index 3952373..b407f0d 100644 --- a/data/maps/the_congruent/rooms/Flipped Yellow Room.txtpb +++ b/data/maps/the_congruent/rooms/Flipped Yellow Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Yellow Room" | 1 | name: "Flipped Yellow Room" |
2 | display_name: "Flipped Yellow Room" | ||
3 | panels { | 2 | panels { |
4 | name: "DANCER" | 3 | name: "DANCER" |
5 | path: "Panels/Back 1/panel_1" | 4 | path: "Panels/Back 1/panel_1" |
diff --git a/data/maps/the_congruent/rooms/G Keyholder.txtpb b/data/maps/the_congruent/rooms/G Keyholder.txtpb index c52d7ba..8184703 100644 --- a/data/maps/the_congruent/rooms/G Keyholder.txtpb +++ b/data/maps/the_congruent/rooms/G Keyholder.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "G Keyholder" | 1 | name: "G Keyholder" |
2 | display_name: "Obverse Yellow Room" | ||
3 | keyholders { | 2 | keyholders { |
4 | name: "G" | 3 | name: "G" |
5 | path: "Components/KeyHolders/keyHolder2" | 4 | path: "Components/KeyHolders/keyHolder2" |
diff --git a/data/maps/the_congruent/rooms/G2 Room.txtpb b/data/maps/the_congruent/rooms/G2 Room.txtpb index 80a23cb..25490a8 100644 --- a/data/maps/the_congruent/rooms/G2 Room.txtpb +++ b/data/maps/the_congruent/rooms/G2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "G2 Room" | 1 | name: "G2 Room" |
2 | display_name: "Main Area" | ||
3 | letters { | 2 | letters { |
4 | key: "g" | 3 | key: "g" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_congruent/rooms/Main Area.txtpb b/data/maps/the_congruent/rooms/Main Area.txtpb index a783eab..2b3f62e 100644 --- a/data/maps/the_congruent/rooms/Main Area.txtpb +++ b/data/maps/the_congruent/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "LANE (1)" | 3 | name: "LANE (1)" |
5 | path: "Panels/Main/panel_1" | 4 | path: "Panels/Main/panel_1" |
@@ -86,8 +85,10 @@ panels { | |||
86 | } | 85 | } |
87 | ports { | 86 | ports { |
88 | name: "DARKROOM" | 87 | name: "DARKROOM" |
88 | display_name: "Entrance" | ||
89 | path: "Components/Warps/worldport2" | 89 | path: "Components/Warps/worldport2" |
90 | orientation: "north" | 90 | destination { x: -19 y: 0 z: 7.5 } |
91 | rotation: 180 | ||
91 | } | 92 | } |
92 | paintings { | 93 | paintings { |
93 | name: "P" | 94 | name: "P" |
diff --git a/data/maps/the_congruent/rooms/Obverse Magenta Room.txtpb b/data/maps/the_congruent/rooms/Obverse Magenta Room.txtpb index b69a4d4..895c4da 100644 --- a/data/maps/the_congruent/rooms/Obverse Magenta Room.txtpb +++ b/data/maps/the_congruent/rooms/Obverse Magenta Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Magenta Room" | 1 | name: "Obverse Magenta Room" |
2 | display_name: "Obverse Magenta Room" | ||
3 | # TODO: Should these two maybe not be randomizable because they hint the keyholder? | 2 | # TODO: Should these two maybe not be randomizable because they hint the keyholder? |
4 | paintings { | 3 | paintings { |
5 | name: "TEA" | 4 | name: "TEA" |
diff --git a/data/maps/the_congruent/rooms/Obverse Yellow Room.txtpb b/data/maps/the_congruent/rooms/Obverse Yellow Room.txtpb index 334df67..c87efdf 100644 --- a/data/maps/the_congruent/rooms/Obverse Yellow Room.txtpb +++ b/data/maps/the_congruent/rooms/Obverse Yellow Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Yellow Room" | 1 | name: "Obverse Yellow Room" |
2 | display_name: "Obverse Yellow Room" | ||
3 | panels { | 2 | panels { |
4 | name: "CIVIL" | 3 | name: "CIVIL" |
5 | path: "Panels/Main/panel_6" | 4 | path: "Panels/Main/panel_6" |
diff --git a/data/maps/the_congruent/rooms/T Keyholder.txtpb b/data/maps/the_congruent/rooms/T Keyholder.txtpb index 1cfd2bd..143ea53 100644 --- a/data/maps/the_congruent/rooms/T Keyholder.txtpb +++ b/data/maps/the_congruent/rooms/T Keyholder.txtpb | |||
@@ -1,6 +1,6 @@ | |||
1 | name: "T Keyholder" | 1 | name: "T Keyholder" |
2 | display_name: "Obverse Magenta Room" | ||
3 | keyholders { | 2 | keyholders { |
4 | name: "T" | 3 | name: "T" |
5 | path: "Components/KeyHolders/keyHolderT" | 4 | path: "Components/KeyHolders/keyHolderT" |
5 | key: "t" | ||
6 | } | 6 | } |
diff --git a/data/maps/the_darkroom/connections.txtpb b/data/maps/the_darkroom/connections.txtpb index 4093585..43bca70 100644 --- a/data/maps/the_darkroom/connections.txtpb +++ b/data/maps/the_darkroom/connections.txtpb | |||
@@ -1,7 +1,12 @@ | |||
1 | connections { | 1 | connections { |
2 | from_room: "First Room" | ||
3 | to_room: "First Room Exit" | ||
4 | door { name: "Second Room Entrance" } | ||
5 | } | ||
6 | connections { | ||
2 | from { | 7 | from { |
3 | port { | 8 | port { |
4 | room: "First Room" | 9 | room: "First Room Exit" |
5 | name: "NEXT" | 10 | name: "NEXT" |
6 | } | 11 | } |
7 | } | 12 | } |
@@ -14,9 +19,14 @@ connections { | |||
14 | oneway: true | 19 | oneway: true |
15 | } | 20 | } |
16 | connections { | 21 | connections { |
22 | from_room: "Second Room" | ||
23 | to_room: "Second Room Exit" | ||
24 | door { name: "Third Room Entrance" } | ||
25 | } | ||
26 | connections { | ||
17 | from { | 27 | from { |
18 | port { | 28 | port { |
19 | room: "Second Room" | 29 | room: "Second Room Exit" |
20 | name: "NEXT" | 30 | name: "NEXT" |
21 | } | 31 | } |
22 | } | 32 | } |
@@ -33,3 +43,18 @@ connections { | |||
33 | to_room: "S Room" | 43 | to_room: "S Room" |
34 | door { name: "S1 Door" } | 44 | door { name: "S1 Door" } |
35 | } | 45 | } |
46 | connections { | ||
47 | from_room: "First Room" | ||
48 | to_room: "Cyan Hallway" | ||
49 | door { name: "Colorful Entrance" } | ||
50 | } | ||
51 | connections { | ||
52 | from_room: "Second Room" | ||
53 | to_room: "Congruent Entrance" | ||
54 | door { name: "Congruent Entrance" } | ||
55 | } | ||
56 | connections { | ||
57 | from_room: "First Room" | ||
58 | to_room: "Double Sided Entrance" | ||
59 | door { name: "Double Sided Entrance" } | ||
60 | } | ||
diff --git a/data/maps/the_darkroom/doors.txtpb b/data/maps/the_darkroom/doors.txtpb index bbf6a1d..047c7d0 100644 --- a/data/maps/the_darkroom/doors.txtpb +++ b/data/maps/the_darkroom/doors.txtpb | |||
@@ -1,11 +1,10 @@ | |||
1 | # TODO: gallery painting | 1 | # TODO: gallery painting |
2 | doors { | 2 | doors { |
3 | name: "Double Letter Panel Blockers" | 3 | name: "Double Letter Panel Blockers" |
4 | type: ITEM_ONLY | 4 | type: EVENT |
5 | receivers: "Panels/Room 1/panel_3/visibilityListener" | 5 | receivers: "Panels/Room 1/panel_3/visibilityListener" |
6 | receivers: "Panels/Room 2/panel_3/visibilityListener" | 6 | receivers: "Panels/Room 2/panel_3/visibilityListener" |
7 | # TODO: honestly idk if this should even exist | 7 | double_letters: true |
8 | switches: "double_letters" | ||
9 | } | 8 | } |
10 | doors { | 9 | doors { |
11 | name: "Second Room Entrance" | 10 | name: "Second Room Entrance" |
@@ -23,8 +22,7 @@ doors { | |||
23 | } | 22 | } |
24 | doors { | 23 | doors { |
25 | name: "S1 Door" | 24 | name: "S1 Door" |
26 | type: LOCATION_ONLY | 25 | type: EVENT |
27 | receivers: "Components/Doors/entry_3" | ||
28 | panels { room: "Third Room" name: "CULTS" } | 26 | panels { room: "Third Room" name: "CULTS" } |
29 | panels { room: "Third Room" name: "TURNS" } | 27 | panels { room: "Third Room" name: "TURNS" } |
30 | panels { room: "Third Room" name: "COINS" } | 28 | panels { room: "Third Room" name: "COINS" } |
@@ -34,7 +32,6 @@ doors { | |||
34 | panels { room: "Third Room" name: "LOCKS" } | 32 | panels { room: "Third Room" name: "LOCKS" } |
35 | panels { room: "Third Room" name: "TOUCHES" } | 33 | panels { room: "Third Room" name: "TOUCHES" } |
36 | panels { room: "Third Room" name: "KOI" } | 34 | panels { room: "Third Room" name: "KOI" } |
37 | location_room: "Third Room" | ||
38 | } | 35 | } |
39 | doors { | 36 | doors { |
40 | name: "Colorful Entrance" | 37 | name: "Colorful Entrance" |
@@ -46,6 +43,7 @@ doors { | |||
46 | panels { room: "First Room" name: "KOI" } | 43 | panels { room: "First Room" name: "KOI" } |
47 | panels { room: "First Room" name: "TUNA" } | 44 | panels { room: "First Room" name: "TUNA" } |
48 | location_room: "First Room" | 45 | location_room: "First Room" |
46 | location_name: "All Puzzles" | ||
49 | } | 47 | } |
50 | doors { | 48 | doors { |
51 | name: "Congruent Entrance" | 49 | name: "Congruent Entrance" |
@@ -57,6 +55,7 @@ doors { | |||
57 | panels { room: "Second Room" name: "KOI" } | 55 | panels { room: "Second Room" name: "KOI" } |
58 | panels { room: "Second Room" name: "TUNA" } | 56 | panels { room: "Second Room" name: "TUNA" } |
59 | location_room: "Second Room" | 57 | location_room: "Second Room" |
58 | location_name: "All Puzzles" | ||
60 | } | 59 | } |
61 | doors { | 60 | doors { |
62 | name: "Double Sided Entrance" | 61 | name: "Double Sided Entrance" |
diff --git a/data/maps/the_darkroom/rooms/Congruent Entrance.txtpb b/data/maps/the_darkroom/rooms/Congruent Entrance.txtpb new file mode 100644 index 0000000..e6600a2 --- /dev/null +++ b/data/maps/the_darkroom/rooms/Congruent Entrance.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Congruent Entrance" | ||
2 | panel_display_name: "Second Room" | ||
3 | ports { | ||
4 | name: "CONGRUENT" | ||
5 | display_name: "Second Room Gray Hallway" | ||
6 | path: "Components/Warps/worldport7" | ||
7 | destination { x: 51.5 y: 0 z: 29 } | ||
8 | rotation: 90 | ||
9 | } | ||
diff --git a/data/maps/the_darkroom/rooms/Cyan Hallway.txtpb b/data/maps/the_darkroom/rooms/Cyan Hallway.txtpb new file mode 100644 index 0000000..bce0e5b --- /dev/null +++ b/data/maps/the_darkroom/rooms/Cyan Hallway.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Cyan Hallway" | ||
2 | panel_display_name: "First Room" | ||
3 | ports { | ||
4 | name: "COLORFUL" | ||
5 | display_name: "First Room Cyan Hallway" | ||
6 | path: "Components/Warps/worldport8" | ||
7 | destination { x: 20 y: 0 z: -12 } | ||
8 | rotation: 180 | ||
9 | } | ||
diff --git a/data/maps/the_darkroom/rooms/Double Sided Entrance.txtpb b/data/maps/the_darkroom/rooms/Double Sided Entrance.txtpb new file mode 100644 index 0000000..79ca839 --- /dev/null +++ b/data/maps/the_darkroom/rooms/Double Sided Entrance.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Double Sided Entrance" | ||
2 | panel_display_name: "First Room" | ||
3 | ports { | ||
4 | name: "DOUBLESIDED" | ||
5 | display_name: "First Room White Hallway" | ||
6 | path: "Components/Warps/worldport6" | ||
7 | destination { x: 15 y: 0 z: 23 } | ||
8 | rotation: 90 | ||
9 | } | ||
diff --git a/data/maps/the_darkroom/rooms/First Room Exit.txtpb b/data/maps/the_darkroom/rooms/First Room Exit.txtpb new file mode 100644 index 0000000..4a7ebc2 --- /dev/null +++ b/data/maps/the_darkroom/rooms/First Room Exit.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "First Room Exit" | ||
2 | panel_display_name: "First Room" | ||
3 | ports { | ||
4 | name: "NEXT" | ||
5 | display_name: "First Room Exit" | ||
6 | path: "Components/Warps/worldport2" | ||
7 | destination { x: 0 y: 0 z: -15 } | ||
8 | rotation: 180 | ||
9 | } | ||
diff --git a/data/maps/the_darkroom/rooms/First Room.txtpb b/data/maps/the_darkroom/rooms/First Room.txtpb index f79d055..1113435 100644 --- a/data/maps/the_darkroom/rooms/First Room.txtpb +++ b/data/maps/the_darkroom/rooms/First Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "First Room" | 1 | name: "First Room" |
2 | display_name: "First Room" | 2 | panel_display_name: "First Room" |
3 | panels { | 3 | panels { |
4 | name: "BISON" | 4 | name: "BISON" |
5 | path: "Panels/Room 1/panel_1" | 5 | path: "Panels/Room 1/panel_1" |
@@ -33,24 +33,8 @@ panels { | |||
33 | } | 33 | } |
34 | ports { | 34 | ports { |
35 | name: "ENTRY" | 35 | name: "ENTRY" |
36 | display_name: "First Room Entrance" | ||
36 | path: "Components/Warps/worldport" | 37 | path: "Components/Warps/worldport" |
37 | orientation: "south" | 38 | destination { x: -10 y: 0 z: 10 } |
38 | } | 39 | rotation: 0 |
39 | ports { | ||
40 | name: "NEXT" | ||
41 | path: "Components/Warps/worldport2" | ||
42 | orientation: "north" | ||
43 | required_door { name: "Second Room Entrance" } | ||
44 | } | ||
45 | ports { | ||
46 | name: "COLORFUL" | ||
47 | path: "Components/Warps/worldport8" | ||
48 | orientation: "north" | ||
49 | required_door { name: "Colorful Entrance" } | ||
50 | } | ||
51 | ports { | ||
52 | name: "DOUBLESIDED" | ||
53 | path: "Components/Warps/worldport6" | ||
54 | orientation: "east" | ||
55 | required_door { name: "Double Sided Entrance" } | ||
56 | } | 40 | } |
diff --git a/data/maps/the_darkroom/rooms/S Room.txtpb b/data/maps/the_darkroom/rooms/S Room.txtpb index 0f56af1..9960b86 100644 --- a/data/maps/the_darkroom/rooms/S Room.txtpb +++ b/data/maps/the_darkroom/rooms/S Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "S Room" | 1 | name: "S Room" |
2 | display_name: "Third Room" | ||
3 | letters { | 2 | letters { |
4 | key: "s" | 3 | key: "s" |
5 | path: "Components/Collectables/collectable" | 4 | path: "Components/Collectables/collectable" |
diff --git a/data/maps/the_darkroom/rooms/Second Room Exit.txtpb b/data/maps/the_darkroom/rooms/Second Room Exit.txtpb new file mode 100644 index 0000000..d500691 --- /dev/null +++ b/data/maps/the_darkroom/rooms/Second Room Exit.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Second Room Exit" | ||
2 | panel_display_name: "Second Room" | ||
3 | ports { | ||
4 | name: "NEXT" | ||
5 | display_name: "Second Room Exit" | ||
6 | path: "Components/Warps/worldport4" | ||
7 | destination { x: 48 y: 0 z: -15 } | ||
8 | rotation: 180 | ||
9 | } | ||
diff --git a/data/maps/the_darkroom/rooms/Second Room.txtpb b/data/maps/the_darkroom/rooms/Second Room.txtpb index ce780f3..2219895 100644 --- a/data/maps/the_darkroom/rooms/Second Room.txtpb +++ b/data/maps/the_darkroom/rooms/Second Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Second Room" | 1 | name: "Second Room" |
2 | display_name: "Second Room" | 2 | panel_display_name: "Second Room" |
3 | panels { | 3 | panels { |
4 | name: "BISON" | 4 | name: "BISON" |
5 | path: "Panels/Room 2/panel_1" | 5 | path: "Panels/Room 2/panel_1" |
@@ -38,18 +38,8 @@ panels { | |||
38 | } | 38 | } |
39 | ports { | 39 | ports { |
40 | name: "ENTRY" | 40 | name: "ENTRY" |
41 | display_name: "Second Room Entrance" | ||
41 | path: "Components/Warps/worldport3" | 42 | path: "Components/Warps/worldport3" |
42 | orientation: "south" | 43 | destination { x: 38 y: 0 z: 10 } |
43 | } | 44 | rotation: 0 |
44 | ports { | ||
45 | name: "NEXT" | ||
46 | path: "Components/Warps/worldport4" | ||
47 | orientation: "north" | ||
48 | required_door { name: "Third Room Entrance" } | ||
49 | } | ||
50 | ports { | ||
51 | name: "CONGRUENT" | ||
52 | path: "Components/Warps/worldport7" | ||
53 | orientation: "east" | ||
54 | required_door { name: "Congruent Entrance" } | ||
55 | } | 45 | } |
diff --git a/data/maps/the_darkroom/rooms/Third Room.txtpb b/data/maps/the_darkroom/rooms/Third Room.txtpb index 5202243..0400476 100644 --- a/data/maps/the_darkroom/rooms/Third Room.txtpb +++ b/data/maps/the_darkroom/rooms/Third Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Third Room" | 1 | name: "Third Room" |
2 | display_name: "Third Room" | 2 | panel_display_name: "Third Room" |
3 | panels { | 3 | panels { |
4 | name: "CULTS" | 4 | name: "CULTS" |
5 | path: "Panels/Room 3/panel_1" | 5 | path: "Panels/Room 3/panel_1" |
@@ -65,6 +65,8 @@ panels { | |||
65 | } | 65 | } |
66 | ports { | 66 | ports { |
67 | name: "ENTRY" | 67 | name: "ENTRY" |
68 | display_name: "Third Room Entrance" | ||
68 | path: "Components/Warps/worldport5" | 69 | path: "Components/Warps/worldport5" |
69 | orientation: "south" | 70 | destination { x: 97 y: 0 z: 10 } |
71 | rotation: 0 | ||
70 | } | 72 | } |
diff --git a/data/maps/the_digital/connections.txtpb b/data/maps/the_digital/connections.txtpb index 67cd4dc..a4b02a5 100644 --- a/data/maps/the_digital/connections.txtpb +++ b/data/maps/the_digital/connections.txtpb | |||
@@ -24,11 +24,6 @@ connections { | |||
24 | door { name: "Gallery Entrance" } | 24 | door { name: "Gallery Entrance" } |
25 | } | 25 | } |
26 | connections { | 26 | connections { |
27 | from_room: "Gallery Maze" | ||
28 | to_room: "Main Area" | ||
29 | oneway: true | ||
30 | } | ||
31 | connections { | ||
32 | from_room: "Tree Area" | 27 | from_room: "Tree Area" |
33 | to_room: "Main Area" | 28 | to_room: "Main Area" |
34 | door { name: "Tree Entrance" } | 29 | door { name: "Tree Entrance" } |
diff --git a/data/maps/the_digital/rooms/C Room.txtpb b/data/maps/the_digital/rooms/C Room.txtpb index 5fdc526..050f090 100644 --- a/data/maps/the_digital/rooms/C Room.txtpb +++ b/data/maps/the_digital/rooms/C Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "C Room" | 1 | name: "C Room" |
2 | display_name: "Chamber" | ||
3 | letters { | 2 | letters { |
4 | key: "c" | 3 | key: "c" |
5 | path: "Components/Collectables/c" | 4 | path: "Components/Collectables/c" |
diff --git a/data/maps/the_digital/rooms/Chamber.txtpb b/data/maps/the_digital/rooms/Chamber.txtpb index 19d4b27..d731372 100644 --- a/data/maps/the_digital/rooms/Chamber.txtpb +++ b/data/maps/the_digital/rooms/Chamber.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Chamber" | 1 | name: "Chamber" |
2 | display_name: "Chamber" | ||
3 | panels { | 2 | panels { |
4 | name: "I" | 3 | name: "I" |
5 | path: "Panels/c1" | 4 | path: "Panels/c1" |
diff --git a/data/maps/the_digital/rooms/Gallery Maze.txtpb b/data/maps/the_digital/rooms/Gallery Maze.txtpb index 9190728..31fa98d 100644 --- a/data/maps/the_digital/rooms/Gallery Maze.txtpb +++ b/data/maps/the_digital/rooms/Gallery Maze.txtpb | |||
@@ -1,7 +1,8 @@ | |||
1 | name: "Gallery Maze" | 1 | name: "Gallery Maze" |
2 | display_name: "Main Area" | ||
3 | ports { | 2 | ports { |
4 | name: "GALLERY" | 3 | name: "GALLERY" |
4 | display_name: "Gallery Maze Worldport" | ||
5 | path: "Components/Warps/worldport4" | 5 | path: "Components/Warps/worldport4" |
6 | orientation: "east" | 6 | destination { x: -58 y: 0 z: -76 } |
7 | rotation: 90 | ||
7 | } | 8 | } |
diff --git a/data/maps/the_digital/rooms/Main Area.txtpb b/data/maps/the_digital/rooms/Main Area.txtpb index ee5c208..26770c2 100644 --- a/data/maps/the_digital/rooms/Main Area.txtpb +++ b/data/maps/the_digital/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "HIT" | 3 | name: "HIT" |
5 | path: "Panels/open_c" | 4 | path: "Panels/open_c" |
@@ -28,16 +27,22 @@ panels { | |||
28 | } | 27 | } |
29 | ports { | 28 | ports { |
30 | name: "ENTRY1" | 29 | name: "ENTRY1" |
30 | display_name: "Maze NW Worldport" | ||
31 | path: "Components/Worldports/worldport3" | 31 | path: "Components/Worldports/worldport3" |
32 | orientation: "west" | 32 | destination { x: -33 y: 0 z: 28 } |
33 | rotation: 270 | ||
33 | } | 34 | } |
34 | ports { | 35 | ports { |
35 | name: "ENTRY2" | 36 | name: "ENTRY2" |
37 | display_name: "Maze SW Worldport" | ||
36 | path: "Components/Worldports/worldport" | 38 | path: "Components/Worldports/worldport" |
37 | orientation: "south" | 39 | destination { x: -30 y: 0 z: 51 } |
40 | rotation: 0 | ||
38 | } | 41 | } |
39 | ports { | 42 | ports { |
40 | name: "ENTRY3" | 43 | name: "ENTRY3" |
44 | display_name: "Maze SE Worldport" | ||
41 | path: "Components/Worldports/worldport2" | 45 | path: "Components/Worldports/worldport2" |
42 | orientation: "south" | 46 | destination { x: 0 y: 0 z: 51 } |
47 | rotation: 0 | ||
43 | } | 48 | } |
diff --git a/data/maps/the_digital/rooms/Tree Area.txtpb b/data/maps/the_digital/rooms/Tree Area.txtpb index fb90353..c2dc6b9 100644 --- a/data/maps/the_digital/rooms/Tree Area.txtpb +++ b/data/maps/the_digital/rooms/Tree Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Tree Area" | 1 | name: "Tree Area" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "TREE" | 3 | name: "TREE" |
5 | path: "Panels/open_tree" | 4 | path: "Panels/open_tree" |
@@ -9,7 +8,8 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "TREE" | 10 | name: "TREE" |
11 | display_name: "Brown Hallway" | ||
12 | path: "Components/Worldports/worldport4" | 12 | path: "Components/Worldports/worldport4" |
13 | orientation: "east" | 13 | destination { x: -16 y: 0 z: -31 } |
14 | # This is double sided. | 14 | rotation: 270 |
15 | } | 15 | } |
diff --git a/data/maps/the_digital/rooms/U Room.txtpb b/data/maps/the_digital/rooms/U Room.txtpb index 5b3e1cb..6b657d5 100644 --- a/data/maps/the_digital/rooms/U Room.txtpb +++ b/data/maps/the_digital/rooms/U Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "U Room" | 1 | name: "U Room" |
2 | display_name: "Chamber" | ||
3 | letters { | 2 | letters { |
4 | key: "u" | 3 | key: "u" |
5 | path: "Components/Collectables/u" | 4 | path: "Components/Collectables/u" |
diff --git a/data/maps/the_digital/rooms/Unyielding Entrance.txtpb b/data/maps/the_digital/rooms/Unyielding Entrance.txtpb index 0370928..f4bc663 100644 --- a/data/maps/the_digital/rooms/Unyielding Entrance.txtpb +++ b/data/maps/the_digital/rooms/Unyielding Entrance.txtpb | |||
@@ -1,6 +1,8 @@ | |||
1 | name: "Unyielding Entrance" | 1 | name: "Unyielding Entrance" |
2 | ports { | 2 | ports { |
3 | name: "UNYIELDING" | 3 | name: "UNYIELDING" |
4 | display_name: "Blue Door Worldport" | ||
4 | path: "Components/Warps/worldport5" | 5 | path: "Components/Warps/worldport5" |
5 | orientation: "east" | 6 | destination { x: 14 y: 0 z: 5 } |
7 | rotation: 90 | ||
6 | } | 8 | } |
diff --git a/data/maps/the_door/rooms/Ending.txtpb b/data/maps/the_door/rooms/Ending.txtpb index 4a4a995..37737e3 100644 --- a/data/maps/the_door/rooms/Ending.txtpb +++ b/data/maps/the_door/rooms/Ending.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Ending" | 1 | name: "Ending" |
2 | display_name: "Main Area" | ||
3 | endings { | 2 | endings { |
4 | name: "PLUM" | 3 | name: "PLUM" |
5 | path: "Components/plum_ending" | 4 | path: "Components/plum_ending" |
diff --git a/data/maps/the_door/rooms/Main Area.txtpb b/data/maps/the_door/rooms/Main Area.txtpb index eb8944f..71e99b1 100644 --- a/data/maps/the_door/rooms/Main Area.txtpb +++ b/data/maps/the_door/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | ||
3 | panels { | 2 | panels { |
4 | name: "HAIR" | 3 | name: "HAIR" |
5 | path: "Panels/Room_1/panel" | 4 | path: "Panels/Room_1/panel" |
diff --git a/data/maps/the_double_sided/rooms/Brown Area.txtpb b/data/maps/the_double_sided/rooms/Brown Area.txtpb index 079a8f2..1752257 100644 --- a/data/maps/the_double_sided/rooms/Brown Area.txtpb +++ b/data/maps/the_double_sided/rooms/Brown Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Brown Area" | 1 | name: "Brown Area" |
2 | display_name: "Maze" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/smiley" | 4 | path: "Components/Collectables/smiley" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Black Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Black Area.txtpb index 38eeee6..082d889 100644 --- a/data/maps/the_double_sided/rooms/Flipped Black Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Black Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Black Area" | 1 | name: "Flipped Black Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "SEAPLANE" | 3 | name: "SEAPLANE" |
5 | path: "Panels/Maze/panel_15" | 4 | path: "Panels/Maze/panel_15" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Blue Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Blue Area.txtpb index 7a285b9..f650be9 100644 --- a/data/maps/the_double_sided/rooms/Flipped Blue Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Blue Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Blue Area" | 1 | name: "Flipped Blue Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "SKY" | 3 | name: "SKY" |
5 | path: "Panels/Maze/panel_5" | 4 | path: "Panels/Maze/panel_5" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Green Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Green Area.txtpb index 68ac4c7..2621f6f 100644 --- a/data/maps/the_double_sided/rooms/Flipped Green Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Green Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Green Area" | 1 | name: "Flipped Green Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "HIGH" | 3 | name: "HIGH" |
5 | path: "Panels/Maze/panel_3" | 4 | path: "Panels/Maze/panel_3" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Orange Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Orange Area.txtpb index 30c62f1..58f1a76 100644 --- a/data/maps/the_double_sided/rooms/Flipped Orange Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Orange Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Orange Area" | 1 | name: "Flipped Orange Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "HEAVEN" | 3 | name: "HEAVEN" |
5 | path: "Panels/Maze/panel_6" | 4 | path: "Panels/Maze/panel_6" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Pink Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Pink Area.txtpb index dce2880..976dd58 100644 --- a/data/maps/the_double_sided/rooms/Flipped Pink Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Pink Area.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Flipped Pink Area" | name: "Flipped Pink Area" | |
2 | display_name: "Maze" | ||
diff --git a/data/maps/the_double_sided/rooms/Flipped Purple Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Purple Area.txtpb index 6228004..02697a8 100644 --- a/data/maps/the_double_sided/rooms/Flipped Purple Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Purple Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Purple Area" | 1 | name: "Flipped Purple Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "CEILING" | 3 | name: "CEILING" |
5 | path: "Panels/Maze/panel_8" | 4 | path: "Panels/Maze/panel_8" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Red Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Red Area.txtpb index 9ca8571..9f10cb2 100644 --- a/data/maps/the_double_sided/rooms/Flipped Red Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Red Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Red Area" | 1 | name: "Flipped Red Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "RAISED" | 3 | name: "RAISED" |
5 | path: "Panels/Maze/panel_12" | 4 | path: "Panels/Maze/panel_12" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Yellow Back Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Yellow Back Area.txtpb index 81cf7ad..1c3193a 100644 --- a/data/maps/the_double_sided/rooms/Flipped Yellow Back Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Yellow Back Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Flipped Yellow Back Area" | 1 | name: "Flipped Yellow Back Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "ANGELS" | 3 | name: "ANGELS" |
5 | path: "Panels/Maze/panel_13" | 4 | path: "Panels/Maze/panel_13" |
diff --git a/data/maps/the_double_sided/rooms/Flipped Yellow Front Area.txtpb b/data/maps/the_double_sided/rooms/Flipped Yellow Front Area.txtpb index 00b26b8..00a221d 100644 --- a/data/maps/the_double_sided/rooms/Flipped Yellow Front Area.txtpb +++ b/data/maps/the_double_sided/rooms/Flipped Yellow Front Area.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Flipped Yellow Front Area" | name: "Flipped Yellow Front Area" | |
2 | display_name: "Maze" | ||
diff --git a/data/maps/the_double_sided/rooms/Obverse Black Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Black Area.txtpb index e0f631d..ece5789 100644 --- a/data/maps/the_double_sided/rooms/Obverse Black Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Black Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Black Area" | 1 | name: "Obverse Black Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "MOUNTAIN" | 3 | name: "MOUNTAIN" |
5 | path: "Panels/Maze/panel_16" | 4 | path: "Panels/Maze/panel_16" |
diff --git a/data/maps/the_double_sided/rooms/Obverse Blue Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Blue Area.txtpb index d576195..1a21952 100644 --- a/data/maps/the_double_sided/rooms/Obverse Blue Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Blue Area.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Obverse Blue Area" | name: "Obverse Blue Area" | |
2 | display_name: "Maze" | ||
diff --git a/data/maps/the_double_sided/rooms/Obverse Green Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Green Area.txtpb index 5fe37cf..d66361e 100644 --- a/data/maps/the_double_sided/rooms/Obverse Green Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Green Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Green Area" | 1 | name: "Obverse Green Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "UPSIDE" | 3 | name: "UPSIDE" |
5 | path: "Panels/Maze/panel_7" | 4 | path: "Panels/Maze/panel_7" |
diff --git a/data/maps/the_double_sided/rooms/Obverse Orange Back Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Orange Back Area.txtpb index 724e56b..43642f9 100644 --- a/data/maps/the_double_sided/rooms/Obverse Orange Back Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Orange Back Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Orange Back Area" | 1 | name: "Obverse Orange Back Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "OVER" | 3 | name: "OVER" |
5 | path: "Panels/Maze/panel_2b" | 4 | path: "Panels/Maze/panel_2b" |
diff --git a/data/maps/the_double_sided/rooms/Obverse Orange Front Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Orange Front Area.txtpb index ff393b6..28ec555 100644 --- a/data/maps/the_double_sided/rooms/Obverse Orange Front Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Orange Front Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Orange Front Area" | 1 | name: "Obverse Orange Front Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "UP" | 3 | name: "UP" |
5 | path: "Panels/Maze/panel_2" | 4 | path: "Panels/Maze/panel_2" |
diff --git a/data/maps/the_double_sided/rooms/Obverse Orange Isolated Section.txtpb b/data/maps/the_double_sided/rooms/Obverse Orange Isolated Section.txtpb index 713d737..b563be9 100644 --- a/data/maps/the_double_sided/rooms/Obverse Orange Isolated Section.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Orange Isolated Section.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Orange Isolated Section" | 1 | name: "Obverse Orange Isolated Section" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "TOP" | 3 | name: "TOP" |
5 | path: "Panels/Maze/panel_4" | 4 | path: "Panels/Maze/panel_4" |
diff --git a/data/maps/the_double_sided/rooms/Obverse Pink Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Pink Area.txtpb index 936be17..2e64a37 100644 --- a/data/maps/the_double_sided/rooms/Obverse Pink Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Pink Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Pink Area" | 1 | name: "Obverse Pink Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "CLOUD" | 3 | name: "CLOUD" |
5 | path: "Panels/Maze/panel_14" | 4 | path: "Panels/Maze/panel_14" |
diff --git a/data/maps/the_double_sided/rooms/Obverse Purple Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Purple Area.txtpb index c77032e..ffe3b80 100644 --- a/data/maps/the_double_sided/rooms/Obverse Purple Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Purple Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Purple Area" | 1 | name: "Obverse Purple Area" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "DRAGON" | 3 | name: "DRAGON" |
5 | path: "Panels/Maze/panel_18" | 4 | path: "Panels/Maze/panel_18" |
diff --git a/data/maps/the_double_sided/rooms/Obverse Red Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Red Area.txtpb index 509a997..90ad07d 100644 --- a/data/maps/the_double_sided/rooms/Obverse Red Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Red Area.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Obverse Red Area" | name: "Obverse Red Area" | |
2 | display_name: "Maze" | ||
diff --git a/data/maps/the_double_sided/rooms/Obverse Yellow Area.txtpb b/data/maps/the_double_sided/rooms/Obverse Yellow Area.txtpb index 0e40a34..801fa28 100644 --- a/data/maps/the_double_sided/rooms/Obverse Yellow Area.txtpb +++ b/data/maps/the_double_sided/rooms/Obverse Yellow Area.txtpb | |||
@@ -1,2 +1 @@ | |||
1 | name: "Obverse Yellow Area" | name: "Obverse Yellow Area" | |
2 | display_name: "Maze" | ||
diff --git a/data/maps/the_double_sided/rooms/Start.txtpb b/data/maps/the_double_sided/rooms/Start.txtpb index f47580f..54efb93 100644 --- a/data/maps/the_double_sided/rooms/Start.txtpb +++ b/data/maps/the_double_sided/rooms/Start.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Start" | 1 | name: "Start" |
2 | display_name: "Maze" | ||
3 | panels { | 2 | panels { |
4 | name: "ATTIC" | 3 | name: "ATTIC" |
5 | path: "Panels/Maze/panel_11" | 4 | path: "Panels/Maze/panel_11" |
@@ -16,6 +15,8 @@ panels { | |||
16 | } | 15 | } |
17 | ports { | 16 | ports { |
18 | name: "DARKROOM" | 17 | name: "DARKROOM" |
18 | display_name: "Entrance" | ||
19 | path: "Components/Warps/worldport" | 19 | path: "Components/Warps/worldport" |
20 | orientation: "west" | 20 | destination { x: -3 y: 0 z: 8 } |
21 | rotation: 270 | ||
21 | } | 22 | } |
diff --git a/data/maps/the_entry/connections.txtpb b/data/maps/the_entry/connections.txtpb index 68aa344..6260665 100644 --- a/data/maps/the_entry/connections.txtpb +++ b/data/maps/the_entry/connections.txtpb | |||
@@ -64,6 +64,16 @@ connections { | |||
64 | door { name: "Flipped Pyramid Area Entrance" } | 64 | door { name: "Flipped Pyramid Area Entrance" } |
65 | } | 65 | } |
66 | connections { | 66 | connections { |
67 | from_room: "Flipped Pyramid Area" | ||
68 | to_room: "Liberated Entrance Panel" | ||
69 | oneway: true | ||
70 | } | ||
71 | connections { | ||
72 | from_room: "Flipped Pyramid Area" | ||
73 | to_room: "Literate Entrance Panel" | ||
74 | oneway: true | ||
75 | } | ||
76 | connections { | ||
67 | from_room: "Right Eye" | 77 | from_room: "Right Eye" |
68 | to_room: "Least Blue Last" | 78 | to_room: "Least Blue Last" |
69 | door { name: "Red Blue Area Left Door" } | 79 | door { name: "Red Blue Area Left Door" } |
@@ -90,8 +100,19 @@ connections { | |||
90 | } | 100 | } |
91 | connections { | 101 | connections { |
92 | from_room: "Red Blue Halls" | 102 | from_room: "Red Blue Halls" |
103 | to_room: "Least Blue Last" | ||
104 | oneway: true | ||
105 | } | ||
106 | connections { | ||
107 | from_room: "Red Blue Halls" | ||
93 | to_room: "Wrath Room" | 108 | to_room: "Wrath Room" |
94 | door { name: "Noon Door" } | 109 | door { name: "Noon Door" } |
110 | oneway: true | ||
111 | } | ||
112 | connections { | ||
113 | from_room: "Wrath Room" | ||
114 | to_room: "Least Blue Last" | ||
115 | oneway: true | ||
95 | } | 116 | } |
96 | connections { | 117 | connections { |
97 | from_room: "Red Blue Halls" | 118 | from_room: "Red Blue Halls" |
@@ -100,6 +121,11 @@ connections { | |||
100 | } | 121 | } |
101 | connections { | 122 | connections { |
102 | from_room: "Wrath Room" | 123 | from_room: "Wrath Room" |
124 | to_room: "Rabbit Hole Lock" | ||
125 | door { name: "Noon Door" } | ||
126 | } | ||
127 | connections { | ||
128 | from_room: "Wrath Room" | ||
103 | to_room: "Rabbit Hole" | 129 | to_room: "Rabbit Hole" |
104 | door { name: "Rabbithole Door" } | 130 | door { name: "Rabbithole Door" } |
105 | } | 131 | } |
@@ -116,7 +142,7 @@ connections { | |||
116 | connections { | 142 | connections { |
117 | from_room: "Blue Alcove" | 143 | from_room: "Blue Alcove" |
118 | to_room: "Least Blue Last" | 144 | to_room: "Least Blue Last" |
119 | door { name: "Red Alcove Exit" } | 145 | door { name: "Blue Alcove Exit" } |
120 | } | 146 | } |
121 | connections { | 147 | connections { |
122 | from_room: "Parthenon Return" | 148 | from_room: "Parthenon Return" |
@@ -144,6 +170,11 @@ connections { | |||
144 | door { name: "Lime Room Entrance" } | 170 | door { name: "Lime Room Entrance" } |
145 | } | 171 | } |
146 | connections { | 172 | connections { |
173 | from_room: "Lime Room" | ||
174 | to_room: "Revitalized Entrance" | ||
175 | door { name: "Revitalized Entrance" } | ||
176 | } | ||
177 | connections { | ||
147 | from { painting { room: "Link Area" name: "NEAR" } } | 178 | from { painting { room: "Link Area" name: "NEAR" } } |
148 | to { painting { room: "Flipped Link Area" name: "NEAR" } } | 179 | to { painting { room: "Flipped Link Area" name: "NEAR" } } |
149 | oneway: true | 180 | oneway: true |
@@ -162,12 +193,12 @@ connections { | |||
162 | from_room: "Starting Room" | 193 | from_room: "Starting Room" |
163 | to_room: "Digital Entrance" | 194 | to_room: "Digital Entrance" |
164 | door { name: "Second Room Left Door" } | 195 | door { name: "Second Room Left Door" } |
165 | oneway: true | ||
166 | } | 196 | } |
167 | connections { | 197 | connections { |
168 | from_room: "Digital Entrance" | 198 | from_room: "Digital Entrance" |
169 | to_room: "Starting Room" | 199 | to_room: "Starting Room" |
170 | oneway: true | 200 | oneway: true |
201 | vanilla_only: true | ||
171 | } | 202 | } |
172 | connections { | 203 | connections { |
173 | from_room: "Starting Room" | 204 | from_room: "Starting Room" |
@@ -182,10 +213,35 @@ connections { | |||
182 | connections { | 213 | connections { |
183 | from_room: "Starting Room" | 214 | from_room: "Starting Room" |
184 | to_room: "Repetitive Entrance" | 215 | to_room: "Repetitive Entrance" |
185 | door { name: "Repetitive Entrance" } | 216 | door { name: "Starting Room West Wall North Door" } |
186 | } | 217 | } |
187 | connections { | 218 | connections { |
188 | from_room: "Lime Room" | 219 | from_room: "Lime Room" |
189 | to_room: "White Hallway To Daedalus" | 220 | to_room: "White Hallway To Daedalus" |
190 | door { name: "Control Center White Door" } | 221 | door { name: "Control Center White Door" } |
191 | } | 222 | } |
223 | connections { | ||
224 | from_room: "Flipped Second Room" | ||
225 | to_room: "Four Rooms Entrance" | ||
226 | door { name: "Flipped Second Room Right Door" } | ||
227 | } | ||
228 | connections { | ||
229 | from_room: "Link Area" | ||
230 | to_room: "Liberated Entrance" | ||
231 | door { name: "Liberated Entrance" } | ||
232 | } | ||
233 | connections { | ||
234 | from_room: "Link Area" | ||
235 | to_room: "Literate Entrance" | ||
236 | door { name: "Literate Entrance" } | ||
237 | } | ||
238 | connections { | ||
239 | from_room: "Liberated Entrance" | ||
240 | to_room: "Liberated Entrance Panel" | ||
241 | oneway: true | ||
242 | } | ||
243 | connections { | ||
244 | from_room: "Literate Entrance" | ||
245 | to_room: "Literate Entrance Panel" | ||
246 | oneway: true | ||
247 | } | ||
diff --git a/data/maps/the_entry/doors.txtpb b/data/maps/the_entry/doors.txtpb index 917edc7..40e486a 100644 --- a/data/maps/the_entry/doors.txtpb +++ b/data/maps/the_entry/doors.txtpb | |||
@@ -62,9 +62,9 @@ doors { | |||
62 | name: "Rabbithole Door" | 62 | name: "Rabbithole Door" |
63 | type: STANDARD | 63 | type: STANDARD |
64 | receivers: "Components/Doors/second_right8" | 64 | receivers: "Components/Doors/second_right8" |
65 | panels { room: "Wrath Room" name: "RABBIT" } | 65 | panels { room: "Rabbit Hole Lock" name: "RABBIT" } |
66 | panels { room: "Wrath Room" name: "HOLE" } | 66 | panels { room: "Rabbit Hole Lock" name: "HOLE" } |
67 | location_room: "Wrath Room" | 67 | location_room: "Rabbit Hole Lock" |
68 | } | 68 | } |
69 | # second_right is vanilla because it's like LOST door. | 69 | # second_right is vanilla because it's like LOST door. |
70 | doors { | 70 | doors { |
@@ -113,10 +113,9 @@ doors { | |||
113 | } | 113 | } |
114 | doors { | 114 | doors { |
115 | name: "Right Eye Entrance" | 115 | name: "Right Eye Entrance" |
116 | type: STANDARD | 116 | type: ITEM_ONLY |
117 | receivers: "Components/Doors/third_right" | 117 | receivers: "Components/Doors/third_right" |
118 | panels { room: "Trick Room" name: "INK" } | 118 | panels { room: "Trick Room" name: "INK" } |
119 | location_room: "Trick Room" | ||
120 | } | 119 | } |
121 | doors { | 120 | doors { |
122 | name: "Red Blue Area Left Door" | 121 | name: "Red Blue Area Left Door" |
@@ -138,8 +137,10 @@ doors { | |||
138 | type: STANDARD | 137 | type: STANDARD |
139 | receivers: "Components/Doors/back_left_2" | 138 | receivers: "Components/Doors/back_left_2" |
140 | panels { room: "Colored Doors Area" name: "OPEN" answer: "orange" } | 139 | panels { room: "Colored Doors Area" name: "OPEN" answer: "orange" } |
141 | # "wall" is supposed to also work. idk man | 140 | panels { room: "Colored Doors Area" name: "OPEN" answer: "wall" } |
141 | complete_at: 1 | ||
142 | location_room: "Colored Doors Area" | 142 | location_room: "Colored Doors Area" |
143 | location_name: "OPEN" | ||
143 | } | 144 | } |
144 | doors { | 145 | doors { |
145 | name: "Lime Room Entrance" | 146 | name: "Lime Room Entrance" |
@@ -194,10 +195,10 @@ doors { | |||
194 | location_room: "Starting Room" | 195 | location_room: "Starting Room" |
195 | } | 196 | } |
196 | doors { | 197 | doors { |
197 | name: "Repetitive Entrance" | 198 | name: "Starting Room West Wall North Door" |
198 | type: ITEM_ONLY | 199 | type: ITEM_ONLY |
199 | receivers: "Components/Doors/Entry/entry_proxied_9" | 200 | receivers: "Components/Doors/Entry/entry_proxied_9" |
200 | switches: "double_letters" | 201 | double_letters: true |
201 | } | 202 | } |
202 | doors { | 203 | doors { |
203 | name: "Shop Entrance" | 204 | name: "Shop Entrance" |
@@ -210,20 +211,20 @@ doors { | |||
210 | name: "Liberated Entrance" | 211 | name: "Liberated Entrance" |
211 | type: STANDARD | 212 | type: STANDARD |
212 | receivers: "Components/Doors/Entry/entry_proxied_10" | 213 | receivers: "Components/Doors/Entry/entry_proxied_10" |
213 | panels { room: "Flipped Pyramid Area" name: "TURN (1)" } | 214 | panels { room: "Liberated Entrance Panel" name: "TURN (1)" } |
214 | location_room: "Flipped Pyramid Area" | 215 | location_room: "Flipped Pyramid Area" |
215 | } | 216 | } |
216 | doors { | 217 | doors { |
217 | name: "Flipped Pyramid Area Entrance" | 218 | name: "Flipped Pyramid Area Entrance" |
218 | type: ITEM_ONLY | 219 | type: EVENT |
219 | receivers: "Components/Doors/Entry/entry_proxied_12" | 220 | receivers: "Components/Doors/Entry/entry_proxied_12" |
220 | switches: "double_letters" | 221 | double_letters: true |
221 | } | 222 | } |
222 | doors { | 223 | doors { |
223 | name: "Literate Entrance" | 224 | name: "Literate Entrance" |
224 | type: STANDARD | 225 | type: STANDARD |
225 | receivers: "Components/Doors/Entry/entry_proxied_11" | 226 | receivers: "Components/Doors/Entry/entry_proxied_11" |
226 | panels { room: "Flipped Pyramid Area" name: "TURN (2)" } | 227 | panels { room: "Literate Entrance Panel" name: "TURN (2)" } |
227 | location_room: "Flipped Pyramid Area" | 228 | location_room: "Flipped Pyramid Area" |
228 | } | 229 | } |
229 | doors { | 230 | doors { |
@@ -252,7 +253,7 @@ doors { | |||
252 | type: ITEM_ONLY | 253 | type: ITEM_ONLY |
253 | receivers: "Components/Doors/Entry/d_3" | 254 | receivers: "Components/Doors/Entry/d_3" |
254 | receivers: "Components/Doors/Entry/d_4" | 255 | receivers: "Components/Doors/Entry/d_4" |
255 | switches: "double_letters" | 256 | double_letters: true |
256 | } | 257 | } |
257 | doors { | 258 | doors { |
258 | name: "D Room Panels" | 259 | name: "D Room Panels" |
@@ -287,7 +288,8 @@ doors { | |||
287 | doors { | 288 | doors { |
288 | name: "Least Blue Last Panels" | 289 | name: "Least Blue Last Panels" |
289 | type: EVENT | 290 | type: EVENT |
290 | move_paintings { room: "Starting Room" name: "OWL" } | 291 | #move_paintings { room: "Starting Room" name: "OWL" } |
292 | #receivers: "Components/Paintings/owl/visibilityListener" | ||
291 | panels { room: "Least Blue Last" name: "CAPABLE (1)" } | 293 | panels { room: "Least Blue Last" name: "CAPABLE (1)" } |
292 | panels { room: "Least Blue Last" name: "CAPABLE (2)" } | 294 | panels { room: "Least Blue Last" name: "CAPABLE (2)" } |
293 | panels { room: "Least Blue Last" name: "LUSTRE" } | 295 | panels { room: "Least Blue Last" name: "LUSTRE" } |
@@ -301,7 +303,8 @@ doors { | |||
301 | doors { | 303 | doors { |
302 | name: "Red Room Painting" | 304 | name: "Red Room Painting" |
303 | type: STANDARD | 305 | type: STANDARD |
304 | move_paintings { room: "Right Eye" name: "PSYCHIC" } | 306 | #move_paintings { room: "Right Eye" name: "PSYCHIC" } |
307 | receivers: "Components/Paintings/psychic/teleportListener" | ||
305 | panels { room: "Right Eye" name: "FAINT" } | 308 | panels { room: "Right Eye" name: "FAINT" } |
306 | location_room: "Right Eye" | 309 | location_room: "Right Eye" |
307 | } | 310 | } |
diff --git a/data/maps/the_entry/metadata.txtpb b/data/maps/the_entry/metadata.txtpb index 679454a..0eeb29a 100644 --- a/data/maps/the_entry/metadata.txtpb +++ b/data/maps/the_entry/metadata.txtpb | |||
@@ -9,3 +9,5 @@ excluded_nodes: "Panels/Back Left/backleft_3_proxied_1" | |||
9 | excluded_nodes: "Panels/Back Left/backleft_3_proxied_2" | 9 | excluded_nodes: "Panels/Back Left/backleft_3_proxied_2" |
10 | excluded_nodes: "Panels/Back Left/backleft_4_proxied_1" | 10 | excluded_nodes: "Panels/Back Left/backleft_4_proxied_1" |
11 | excluded_nodes: "Panels/Back Left/backleft_4_proxied_2" | 11 | excluded_nodes: "Panels/Back Left/backleft_4_proxied_2" |
12 | # This is a proxy related to the first panel and it doesn't seem useful. | ||
13 | excluded_nodes: "Panels/Entry/entry_proxied_fake" | ||
diff --git a/data/maps/the_entry/rooms/Blue Alcove.txtpb b/data/maps/the_entry/rooms/Blue Alcove.txtpb index 4c2c48c..3df58b9 100644 --- a/data/maps/the_entry/rooms/Blue Alcove.txtpb +++ b/data/maps/the_entry/rooms/Blue Alcove.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Blue Alcove" | 1 | name: "Blue Alcove" |
2 | display_name: "Red Blue Area" | 2 | panel_display_name: "Red Blue Area" |
3 | panels { | 3 | panels { |
4 | name: "BLUE" | 4 | name: "BLUE" |
5 | path: "Panels/Back Right/br_11" | 5 | path: "Panels/Back Right/br_11" |
diff --git a/data/maps/the_entry/rooms/Colored Doors Area.txtpb b/data/maps/the_entry/rooms/Colored Doors Area.txtpb index 29e89b5..4767387 100644 --- a/data/maps/the_entry/rooms/Colored Doors Area.txtpb +++ b/data/maps/the_entry/rooms/Colored Doors Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Colored Doors Area" | 1 | name: "Colored Doors Area" |
2 | display_name: "Colored Doors Area" | 2 | panel_display_name: "Colored Doors Area" |
3 | panels { | 3 | panels { |
4 | name: "OPEN" | 4 | name: "OPEN" |
5 | path: "Panels/Back Left/backleft_proxying_1" | 5 | path: "Panels/Back Left/backleft_proxying_1" |
diff --git a/data/maps/the_entry/rooms/Composite Room Entrance.txtpb b/data/maps/the_entry/rooms/Composite Room Entrance.txtpb index 4c18625..ca9e7f4 100644 --- a/data/maps/the_entry/rooms/Composite Room Entrance.txtpb +++ b/data/maps/the_entry/rooms/Composite Room Entrance.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Composite Room Entrance" | 1 | name: "Composite Room Entrance" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | ports { | 3 | ports { |
4 | name: "COMPOSITE" | 4 | name: "COMPOSITE" |
5 | display_name: "Starting Room NE Worldport" | ||
5 | path: "Components/Warps/worldport12" | 6 | path: "Components/Warps/worldport12" |
6 | orientation: "east" | 7 | destination { x: 16 y: 0 z: -20 } |
8 | rotation: 90 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_entry/rooms/Ctrl Tutorial.txtpb b/data/maps/the_entry/rooms/Ctrl Tutorial.txtpb index 0819953..fabcd60 100644 --- a/data/maps/the_entry/rooms/Ctrl Tutorial.txtpb +++ b/data/maps/the_entry/rooms/Ctrl Tutorial.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Ctrl Tutorial" | 1 | name: "Ctrl Tutorial" |
2 | display_name: "Colored Doors Area" | 2 | panel_display_name: "Colored Doors Area" |
3 | panels { | 3 | panels { |
4 | name: "RIGHT" | 4 | name: "RIGHT" |
5 | path: "Panels/Back Left/backleft_proxying_2" | 5 | path: "Panels/Back Left/backleft_proxying_2" |
diff --git a/data/maps/the_entry/rooms/D Room Final.txtpb b/data/maps/the_entry/rooms/D Room Final.txtpb index 960cb1c..bb8ee87 100644 --- a/data/maps/the_entry/rooms/D Room Final.txtpb +++ b/data/maps/the_entry/rooms/D Room Final.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "D Room Final" | 1 | name: "D Room Final" |
2 | display_name: "D Room" | 2 | panel_display_name: "D Room" |
3 | letters { | 3 | letters { |
4 | key: "d" | 4 | key: "d" |
5 | path: "Components/Collectables/d" | 5 | path: "Components/Collectables/d" |
diff --git a/data/maps/the_entry/rooms/D Room.txtpb b/data/maps/the_entry/rooms/D Room.txtpb index 27a975b..fdf6846 100644 --- a/data/maps/the_entry/rooms/D Room.txtpb +++ b/data/maps/the_entry/rooms/D Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "D Room" | 1 | name: "D Room" |
2 | display_name: "D Room" | 2 | panel_display_name: "D Room" |
3 | panels { | 3 | panels { |
4 | name: "BASEBALL" | 4 | name: "BASEBALL" |
5 | path: "Panels/D/d_2" | 5 | path: "Panels/D/d_2" |
diff --git a/data/maps/the_entry/rooms/Daedalus Entrance.txtpb b/data/maps/the_entry/rooms/Daedalus Entrance.txtpb index 60b41cb..76dc278 100644 --- a/data/maps/the_entry/rooms/Daedalus Entrance.txtpb +++ b/data/maps/the_entry/rooms/Daedalus Entrance.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Daedalus Entrance" | 1 | name: "Daedalus Entrance" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | ports { | 3 | ports { |
4 | name: "DAEDALUS" | 4 | name: "DAEDALUS" |
5 | display_name: "Starting Room North Wall West Worldport" | ||
5 | path: "Components/Warps/worldport6" | 6 | path: "Components/Warps/worldport6" |
6 | orientation: "west" | 7 | destination { x: -16 y: 0 z: -20 } |
8 | rotation: 270 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_entry/rooms/Digital Entrance.txtpb b/data/maps/the_entry/rooms/Digital Entrance.txtpb index 5713a8d..b7689bd 100644 --- a/data/maps/the_entry/rooms/Digital Entrance.txtpb +++ b/data/maps/the_entry/rooms/Digital Entrance.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Digital Entrance" | 1 | name: "Digital Entrance" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | ports { | 3 | ports { |
4 | name: "DIGITAL" | 4 | name: "DIGITAL" |
5 | display_name: "Second Room Left Worldport" | ||
5 | path: "Components/Warps/worldport" | 6 | path: "Components/Warps/worldport" |
6 | orientation: "west" | 7 | destination { x: -78 y: 0 z: -24 } |
8 | rotation: 270 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_entry/rooms/Entry Exit.txtpb b/data/maps/the_entry/rooms/Entry Exit.txtpb index 6b4fadd..e270bf8 100644 --- a/data/maps/the_entry/rooms/Entry Exit.txtpb +++ b/data/maps/the_entry/rooms/Entry Exit.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Entry Exit" | 1 | name: "Entry Exit" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | ports { | 3 | ports { |
4 | name: "GREAT" | 4 | name: "GREAT" |
5 | display_name: "Second Room Right Worldport" | ||
5 | path: "Components/Warps/worldport2" | 6 | path: "Components/Warps/worldport2" |
6 | orientation: "north" | 7 | destination { x: 18 y: 0 z: -36 } |
8 | rotation: 180 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_entry/rooms/Eye Room.txtpb b/data/maps/the_entry/rooms/Eye Room.txtpb index 8c6290b..00f2534 100644 --- a/data/maps/the_entry/rooms/Eye Room.txtpb +++ b/data/maps/the_entry/rooms/Eye Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Eye Room" | 1 | name: "Eye Room" |
2 | display_name: "Eye Room" | 2 | panel_display_name: "Eye Room" |
3 | panels { | 3 | panels { |
4 | name: "I" | 4 | name: "I" |
5 | path: "Panels/Entry/eyes_1" | 5 | path: "Panels/Entry/eyes_1" |
@@ -31,6 +31,8 @@ paintings { | |||
31 | } | 31 | } |
32 | ports { | 32 | ports { |
33 | name: "LIONIZED" | 33 | name: "LIONIZED" |
34 | display_name: "Eye Room Worldport" | ||
34 | path: "Components/Warps/worldport10" | 35 | path: "Components/Warps/worldport10" |
35 | orientation: "north" | 36 | destination { x: 18 y: 0 z: -88.5 } |
37 | rotation: 180 | ||
36 | } | 38 | } |
diff --git a/data/maps/the_entry/rooms/Flipped Link Area.txtpb b/data/maps/the_entry/rooms/Flipped Link Area.txtpb index 5251023..950e9b1 100644 --- a/data/maps/the_entry/rooms/Flipped Link Area.txtpb +++ b/data/maps/the_entry/rooms/Flipped Link Area.txtpb | |||
@@ -1,18 +1,19 @@ | |||
1 | name: "Flipped Link Area" | 1 | name: "Flipped Link Area" |
2 | display_name: "Pyramid Area" | 2 | panel_display_name: "Pyramid Area" |
3 | panels { | 3 | panels { |
4 | name: "WANDER" | 4 | name: "WANDER" |
5 | path: "Panels/Pilgrimage/cream_4" | 5 | path: "Panels/Pilgrimage/cream_4" |
6 | clue: "wander" | 6 | clue: "wander" |
7 | answer: "roam" | 7 | answer: "roam" |
8 | symbols: SUN | 8 | symbols: SUN |
9 | display_name: "WANDER (Flipped)" | ||
9 | } | 10 | } |
10 | paintings { | 11 | paintings { |
11 | name: "NEAR" | 12 | name: "NEAR" |
12 | path: "Components/Paintings/aches2" | 13 | path: "Components/Paintings/aches2" |
13 | orientation: "north" | 14 | orientation: "north" |
14 | gravity: Y_PLUS | 15 | gravity: Y_PLUS |
15 | display_name: "Flipper Near Painting" | 16 | display_name: "Flipped Near Painting" |
16 | } | 17 | } |
17 | paintings { | 18 | paintings { |
18 | name: "FAR" | 19 | name: "FAR" |
diff --git a/data/maps/the_entry/rooms/Flipped Pyramid Area.txtpb b/data/maps/the_entry/rooms/Flipped Pyramid Area.txtpb index e2dd992..30e737f 100644 --- a/data/maps/the_entry/rooms/Flipped Pyramid Area.txtpb +++ b/data/maps/the_entry/rooms/Flipped Pyramid Area.txtpb | |||
@@ -1,16 +1,6 @@ | |||
1 | name: "Flipped Pyramid Area" | 1 | name: "Flipped Pyramid Area" |
2 | display_name: "Pyramid Area" | 2 | panel_display_name: "Pyramid Area" |
3 | panels { | 3 | # The fact that the doors here cover up the panels once they open is a problem |
4 | name: "TURN (1)" | 4 | # since you're not guaranteed to have access to the lower area if painting |
5 | path: "Panels/Entry/l_opener_3" | 5 | # shuffle is a thing. So we need to edit these doors so that they don't cover up |
6 | clue: "turn" | 6 | # the panels. |
7 | answer: "flip" | ||
8 | symbols: SUN | ||
9 | } | ||
10 | panels { | ||
11 | name: "TURN (2)" | ||
12 | path: "Panels/Entry/l_opener_4" | ||
13 | clue: "turn" | ||
14 | answer: "spin" | ||
15 | symbols: SUN | ||
16 | } \ No newline at end of file | ||
diff --git a/data/maps/the_entry/rooms/Flipped Right Eye.txtpb b/data/maps/the_entry/rooms/Flipped Right Eye.txtpb index 429d63e..14f3f5a 100644 --- a/data/maps/the_entry/rooms/Flipped Right Eye.txtpb +++ b/data/maps/the_entry/rooms/Flipped Right Eye.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Flipped Right Eye" | 1 | name: "Flipped Right Eye" |
2 | display_name: "Flip Area" | 2 | panel_display_name: "Flip Area" |
3 | panels { | 3 | panels { |
4 | name: "WHERE" | 4 | name: "WHERE" |
5 | path: "Panels/Pilgrimage/cream_5" | 5 | path: "Panels/Pilgrimage/cream_5" |
diff --git a/data/maps/the_entry/rooms/Flipped Second Room.txtpb b/data/maps/the_entry/rooms/Flipped Second Room.txtpb index d4ee780..0d518bb 100644 --- a/data/maps/the_entry/rooms/Flipped Second Room.txtpb +++ b/data/maps/the_entry/rooms/Flipped Second Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Flipped Second Room" | 1 | name: "Flipped Second Room" |
2 | display_name: "Flip Area" | 2 | panel_display_name: "Flip Area" |
3 | panels { | 3 | panels { |
4 | name: "CLUE" | 4 | name: "CLUE" |
5 | path: "Panels/Entry/second_right_top" | 5 | path: "Panels/Entry/second_right_top" |
@@ -21,10 +21,3 @@ paintings { | |||
21 | gravity: Y_PLUS | 21 | gravity: Y_PLUS |
22 | display_name: "Eye Painting" | 22 | display_name: "Eye Painting" |
23 | } | 23 | } |
24 | ports { | ||
25 | name: "FOUR" | ||
26 | path: "Components/Warps/worldport9" | ||
27 | orientation: "south" | ||
28 | gravity: Y_PLUS | ||
29 | required_door { name: "Flipped Second Room Right Door" } | ||
30 | } \ No newline at end of file | ||
diff --git a/data/maps/the_entry/rooms/Four Rooms Entrance.txtpb b/data/maps/the_entry/rooms/Four Rooms Entrance.txtpb new file mode 100644 index 0000000..4d94d5a --- /dev/null +++ b/data/maps/the_entry/rooms/Four Rooms Entrance.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Four Rooms Entrance" | ||
2 | ports { | ||
3 | name: "FOUR" | ||
4 | display_name: "Flipped Second Room Right Worldport" | ||
5 | path: "Components/Warps/worldport9" | ||
6 | destination { x: -41 y: 6 z: -17.5 } | ||
7 | rotation: 0 | ||
8 | gravity: Y_PLUS | ||
9 | } | ||
diff --git a/data/maps/the_entry/rooms/Gallery Return.txtpb b/data/maps/the_entry/rooms/Gallery Return.txtpb index 1273928..7235d80 100644 --- a/data/maps/the_entry/rooms/Gallery Return.txtpb +++ b/data/maps/the_entry/rooms/Gallery Return.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Gallery Return" | 1 | name: "Gallery Return" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Gallery Return" |
3 | panels { | 3 | panels { |
4 | name: "RETURN" | 4 | name: "RETURN" |
5 | path: "Panels/Entry/gallery_return" | 5 | path: "Panels/Entry/gallery_return" |
@@ -9,6 +9,8 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "GALLERY" | 11 | name: "GALLERY" |
12 | display_name: "Gallery Return" | ||
12 | path: "Components/Warps/worldport4" | 13 | path: "Components/Warps/worldport4" |
13 | orientation: "north" | 14 | destination { x: -38 y: 0 z: 8.5 } |
15 | rotation: 180 | ||
14 | } \ No newline at end of file | 16 | } \ No newline at end of file |
diff --git a/data/maps/the_entry/rooms/Least Blue Last.txtpb b/data/maps/the_entry/rooms/Least Blue Last.txtpb index 0f198b7..dde203a 100644 --- a/data/maps/the_entry/rooms/Least Blue Last.txtpb +++ b/data/maps/the_entry/rooms/Least Blue Last.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Least Blue Last" | 1 | name: "Least Blue Last" |
2 | display_name: "Red Blue Area" | 2 | panel_display_name: "Red Blue Area" |
3 | panels { | 3 | panels { |
4 | name: "CAPABLE (1)" | 4 | name: "CAPABLE (1)" |
5 | path: "Panels/LBL/lbl_1" | 5 | path: "Panels/LBL/lbl_1" |
@@ -72,8 +72,10 @@ panels { | |||
72 | } | 72 | } |
73 | ports { | 73 | ports { |
74 | name: "DARKROOM" | 74 | name: "DARKROOM" |
75 | display_name: "Near L1 Worldport" | ||
75 | path: "Components/Warps/worldport5" | 76 | path: "Components/Warps/worldport5" |
76 | orientation: "south" | 77 | destination { x: 43 y: 0 z: -10 } |
78 | rotation: 0 | ||
77 | } | 79 | } |
78 | paintings { | 80 | paintings { |
79 | name: "PAINS" | 81 | name: "PAINS" |
diff --git a/data/maps/the_entry/rooms/Liberated Entrance Panel.txtpb b/data/maps/the_entry/rooms/Liberated Entrance Panel.txtpb new file mode 100644 index 0000000..7c5ef71 --- /dev/null +++ b/data/maps/the_entry/rooms/Liberated Entrance Panel.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Liberated Entrance Panel" | ||
2 | panel_display_name: "Pyramid Area" | ||
3 | panels { | ||
4 | name: "TURN (1)" | ||
5 | path: "Panels/Entry/l_opener_3" | ||
6 | clue: "turn" | ||
7 | answer: "flip" | ||
8 | symbols: SUN | ||
9 | } | ||
diff --git a/data/maps/the_entry/rooms/Liberated Entrance.txtpb b/data/maps/the_entry/rooms/Liberated Entrance.txtpb new file mode 100644 index 0000000..56cc597 --- /dev/null +++ b/data/maps/the_entry/rooms/Liberated Entrance.txtpb | |||
@@ -0,0 +1,8 @@ | |||
1 | name: "Liberated Entrance" | ||
2 | ports { | ||
3 | name: "BLUE" | ||
4 | display_name: "Pyramid Area Blue Worldport" | ||
5 | path: "worldport8" | ||
6 | destination { x: 18 y: 0 z: 55 } | ||
7 | rotation: 270 | ||
8 | } | ||
diff --git a/data/maps/the_entry/rooms/Lime Room.txtpb b/data/maps/the_entry/rooms/Lime Room.txtpb index 6054dd7..603fbdc 100644 --- a/data/maps/the_entry/rooms/Lime Room.txtpb +++ b/data/maps/the_entry/rooms/Lime Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Lime Room" | 1 | name: "Lime Room" |
2 | display_name: "Colored Doors Area" | 2 | panel_display_name: "Colored Doors Area" |
3 | panels { | 3 | panels { |
4 | name: "HIDE" | 4 | name: "HIDE" |
5 | path: "Panels/Back Left/backleft_proxying_3" | 5 | path: "Panels/Back Left/backleft_proxying_3" |
@@ -19,9 +19,3 @@ panels { | |||
19 | answer: "white" | 19 | answer: "white" |
20 | symbols: EXAMPLE | 20 | symbols: EXAMPLE |
21 | } | 21 | } |
22 | ports { | ||
23 | name: "REVITALIZED" | ||
24 | path: "worldport7" | ||
25 | orientation: "north" | ||
26 | required_door { name: "Revitalized Entrance" } | ||
27 | } \ No newline at end of file | ||
diff --git a/data/maps/the_entry/rooms/Link Area.txtpb b/data/maps/the_entry/rooms/Link Area.txtpb index 2866abd..5b68279 100644 --- a/data/maps/the_entry/rooms/Link Area.txtpb +++ b/data/maps/the_entry/rooms/Link Area.txtpb | |||
@@ -1,11 +1,12 @@ | |||
1 | name: "Link Area" | 1 | name: "Link Area" |
2 | display_name: "Pyramid Area" | 2 | panel_display_name: "Pyramid Area" |
3 | panels { | 3 | panels { |
4 | name: "WANDER" | 4 | name: "WANDER" |
5 | path: "Panels/Pilgrimage/cream_3" | 5 | path: "Panels/Pilgrimage/cream_3" |
6 | clue: "wander" | 6 | clue: "wander" |
7 | answer: "amble" | 7 | answer: "amble" |
8 | symbols: SUN | 8 | symbols: SUN |
9 | display_name: "WANDER (Obverse)" | ||
9 | } | 10 | } |
10 | paintings { | 11 | paintings { |
11 | name: "NEAR" | 12 | name: "NEAR" |
@@ -25,15 +26,3 @@ paintings { | |||
25 | orientation: "south" | 26 | orientation: "south" |
26 | display_name: "Center Painting" | 27 | display_name: "Center Painting" |
27 | } | 28 | } |
28 | ports { | ||
29 | name: "BLUE" | ||
30 | path: "worldport8" | ||
31 | orientation: "west" | ||
32 | required_door { name: "Liberated Entrance" } | ||
33 | } | ||
34 | ports { | ||
35 | name: "BROWN" | ||
36 | path: "worldport9" | ||
37 | orientation: "east" | ||
38 | required_door { name: "Literate Entrance" } | ||
39 | } \ No newline at end of file | ||
diff --git a/data/maps/the_entry/rooms/Literate Entrance Panel.txtpb b/data/maps/the_entry/rooms/Literate Entrance Panel.txtpb new file mode 100644 index 0000000..676598b --- /dev/null +++ b/data/maps/the_entry/rooms/Literate Entrance Panel.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Literate Entrance Panel" | ||
2 | panel_display_name: "Pyramid Area" | ||
3 | panels { | ||
4 | name: "TURN (2)" | ||
5 | path: "Panels/Entry/l_opener_4" | ||
6 | clue: "turn" | ||
7 | answer: "spin" | ||
8 | symbols: SUN | ||
9 | } | ||
diff --git a/data/maps/the_entry/rooms/Literate Entrance.txtpb b/data/maps/the_entry/rooms/Literate Entrance.txtpb new file mode 100644 index 0000000..b86ac80 --- /dev/null +++ b/data/maps/the_entry/rooms/Literate Entrance.txtpb | |||
@@ -0,0 +1,8 @@ | |||
1 | name: "Literate Entrance" | ||
2 | ports { | ||
3 | name: "BROWN" | ||
4 | display_name: "Pyramid Area Brown Worldport" | ||
5 | path: "worldport9" | ||
6 | destination { x: 39 y: 0 z: 55 } | ||
7 | rotation: 90 | ||
8 | } | ||
diff --git a/data/maps/the_entry/rooms/Parthenon Return.txtpb b/data/maps/the_entry/rooms/Parthenon Return.txtpb index 5a7f6b8..bb12964 100644 --- a/data/maps/the_entry/rooms/Parthenon Return.txtpb +++ b/data/maps/the_entry/rooms/Parthenon Return.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Parthenon Return" | 1 | name: "Parthenon Return" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Parthenon Return" |
3 | panels { | 3 | panels { |
4 | name: "RETURN" | 4 | name: "RETURN" |
5 | path: "Panels/Back Left/backleft_return" | 5 | path: "Panels/Back Left/backleft_return" |
@@ -9,6 +9,8 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "PARTHENON" | 11 | name: "PARTHENON" |
12 | display_name: "Parthenon Return" | ||
12 | path: "Components/Warps/worldport8" | 13 | path: "Components/Warps/worldport8" |
13 | orientation: "north" | 14 | destination { x: -5.5 y: 0 z: 18 } |
14 | } \ No newline at end of file | 15 | rotation: 180 |
16 | } | ||
diff --git a/data/maps/the_entry/rooms/Rabbit Hole Lock.txtpb b/data/maps/the_entry/rooms/Rabbit Hole Lock.txtpb new file mode 100644 index 0000000..78b4f3b --- /dev/null +++ b/data/maps/the_entry/rooms/Rabbit Hole Lock.txtpb | |||
@@ -0,0 +1,18 @@ | |||
1 | name: "Rabbit Hole Lock" | ||
2 | panel_display_name: "Red Blue Area" | ||
3 | panels { | ||
4 | name: "RABBIT" | ||
5 | path: "Panels/Back Right/br_4" | ||
6 | clue: "rabbit" | ||
7 | answer: "hair" | ||
8 | symbols: SUN | ||
9 | symbols: ZERO | ||
10 | } | ||
11 | panels { | ||
12 | name: "HOLE" | ||
13 | path: "Panels/Back Right/br_5" | ||
14 | clue: "hole" | ||
15 | answer: "part" | ||
16 | symbols: ZERO | ||
17 | symbols: BOXES | ||
18 | } | ||
diff --git a/data/maps/the_entry/rooms/Rabbit Hole.txtpb b/data/maps/the_entry/rooms/Rabbit Hole.txtpb index 9b18bc8..4ffeb84 100644 --- a/data/maps/the_entry/rooms/Rabbit Hole.txtpb +++ b/data/maps/the_entry/rooms/Rabbit Hole.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Rabbit Hole" | 1 | name: "Rabbit Hole" |
2 | display_name: "Red Blue Area" | 2 | panel_display_name: "Red Blue Area" |
3 | panels { | 3 | panels { |
4 | name: "PUZZLE" | 4 | name: "PUZZLE" |
5 | path: "Panels/Back Right/br_6" | 5 | path: "Panels/Back Right/br_6" |
@@ -8,6 +8,8 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "HOLE" | 10 | name: "HOLE" |
11 | display_name: "Rabbit Hole" | ||
11 | path: "worldport4" | 12 | path: "worldport4" |
12 | orientation: "down" | 13 | destination { x: 74 y: 0 z: -43 } |
13 | } \ No newline at end of file | 14 | rotation: 0 |
15 | } | ||
diff --git a/data/maps/the_entry/rooms/Red Alcove.txtpb b/data/maps/the_entry/rooms/Red Alcove.txtpb index 5c4085e..503b4a9 100644 --- a/data/maps/the_entry/rooms/Red Alcove.txtpb +++ b/data/maps/the_entry/rooms/Red Alcove.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Red Alcove" | 1 | name: "Red Alcove" |
2 | display_name: "Red Blue Area" | 2 | panel_display_name: "Red Blue Area" |
3 | panels { | 3 | panels { |
4 | name: "BROW" | 4 | name: "BROW" |
5 | path: "Panels/Back Right/br_10" | 5 | path: "Panels/Back Right/br_10" |
diff --git a/data/maps/the_entry/rooms/Red Blue Halls.txtpb b/data/maps/the_entry/rooms/Red Blue Halls.txtpb index 7d07f9e..789ca42 100644 --- a/data/maps/the_entry/rooms/Red Blue Halls.txtpb +++ b/data/maps/the_entry/rooms/Red Blue Halls.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Red Blue Halls" | 1 | name: "Red Blue Halls" |
2 | display_name: "Red Blue Area" | 2 | panel_display_name: "Red Blue Area" |
3 | panels { | 3 | panels { |
4 | name: "CENTER" | 4 | name: "CENTER" |
5 | path: "Panels/Back Right/br_1" | 5 | path: "Panels/Back Right/br_1" |
diff --git a/data/maps/the_entry/rooms/Repetitive Entrance.txtpb b/data/maps/the_entry/rooms/Repetitive Entrance.txtpb index 982e3f3..25c3307 100644 --- a/data/maps/the_entry/rooms/Repetitive Entrance.txtpb +++ b/data/maps/the_entry/rooms/Repetitive Entrance.txtpb | |||
@@ -1,7 +1,12 @@ | |||
1 | name: "Repetitive Entrance" | 1 | name: "Repetitive Entrance" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | ports { | 3 | ports { |
4 | name: "REPETITIVE" | 4 | name: "REPETITIVE" |
5 | display_name: "Starting Room West Wall North Worldport" | ||
5 | path: "Components/Warps/worldport7" | 6 | path: "Components/Warps/worldport7" |
6 | orientation: "north" | 7 | destination { x: -20 y: 0 z: -16 } |
8 | rotation: 180 | ||
9 | # TODO: this is part of what makes the keyholder dependent connection from CC | ||
10 | # safe in vanilla doors | ||
11 | no_shuffle: true | ||
7 | } | 12 | } |
diff --git a/data/maps/the_entry/rooms/Revitalized Entrance.txtpb b/data/maps/the_entry/rooms/Revitalized Entrance.txtpb new file mode 100644 index 0000000..fb5e7e0 --- /dev/null +++ b/data/maps/the_entry/rooms/Revitalized Entrance.txtpb | |||
@@ -0,0 +1,9 @@ | |||
1 | name: "Revitalized Entrance" | ||
2 | panel_display_name: "Colored Doors Area" | ||
3 | ports { | ||
4 | name: "REVITALIZED" | ||
5 | display_name: "Plum Hallway" | ||
6 | path: "worldport7" | ||
7 | destination { x: -58 y: 0 z: 31.5 } | ||
8 | rotation: 180 | ||
9 | } | ||
diff --git a/data/maps/the_entry/rooms/Right Eye.txtpb b/data/maps/the_entry/rooms/Right Eye.txtpb index 1c7bf68..8f6c431 100644 --- a/data/maps/the_entry/rooms/Right Eye.txtpb +++ b/data/maps/the_entry/rooms/Right Eye.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Right Eye" | 1 | name: "Right Eye" |
2 | display_name: "Right Eye Area" | 2 | panel_display_name: "Right Eye Area" |
3 | panels { | 3 | panels { |
4 | name: "EYE" | 4 | name: "EYE" |
5 | path: "Panels/Entry/front_2" | 5 | path: "Panels/Entry/front_2" |
diff --git a/data/maps/the_entry/rooms/Shop Entrance.txtpb b/data/maps/the_entry/rooms/Shop Entrance.txtpb index b52cde7..4a99efa 100644 --- a/data/maps/the_entry/rooms/Shop Entrance.txtpb +++ b/data/maps/the_entry/rooms/Shop Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Shop Entrance" | 1 | name: "Shop Entrance" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Shop Entrance" |
3 | panels { | 3 | panels { |
4 | name: "TURN" | 4 | name: "TURN" |
5 | path: "Panels/Entry/l_opener_2" | 5 | path: "Panels/Entry/l_opener_2" |
@@ -9,6 +9,8 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "SHOP" | 11 | name: "SHOP" |
12 | display_name: "Shop Entrance" | ||
12 | path: "Components/Warps/worldport13" | 13 | path: "Components/Warps/worldport13" |
13 | orientation: "east" | 14 | destination { x: 18 y: 0 z: 49 } |
15 | rotation: 90 | ||
14 | } \ No newline at end of file | 16 | } \ No newline at end of file |
diff --git a/data/maps/the_entry/rooms/Starting Room.txtpb b/data/maps/the_entry/rooms/Starting Room.txtpb index aeb66ab..8e8373b 100644 --- a/data/maps/the_entry/rooms/Starting Room.txtpb +++ b/data/maps/the_entry/rooms/Starting Room.txtpb | |||
@@ -1,10 +1,11 @@ | |||
1 | name: "Starting Room" | 1 | name: "Starting Room" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | panels { | 3 | panels { |
4 | name: "HI" | 4 | name: "HI" |
5 | path: "Panels/Entry/entry_proxying_1" | 5 | path: "Panels/Entry/entry_proxying_1" |
6 | clue: "hi" | 6 | clue: "hi" |
7 | answer: "hi" | 7 | answer: "hi" |
8 | proxies { answer: "hi" path: "Panels/Entry/entry_proxied_1" } | ||
8 | proxies { answer: "bye" path: "Panels/Entry/entry_proxied_2" } | 9 | proxies { answer: "bye" path: "Panels/Entry/entry_proxied_2" } |
9 | proxies { answer: "hidden" path: "Panels/Entry/entry_proxied_5" } | 10 | proxies { answer: "hidden" path: "Panels/Entry/entry_proxied_5" } |
10 | proxies { answer: "high" path: "Panels/Entry/entry_proxied_3" } | 11 | proxies { answer: "high" path: "Panels/Entry/entry_proxied_3" } |
@@ -23,7 +24,9 @@ panels { | |||
23 | path: "Panels/Entry/front_1" | 24 | path: "Panels/Entry/front_1" |
24 | clue: "eye" | 25 | clue: "eye" |
25 | answer: "i" | 26 | answer: "i" |
26 | symbols: ZERO | 27 | #symbols: ZERO |
28 | # This panel blocks getting N1 and T1. We will mod it to be I/I with no symbol | ||
29 | # when symbol shuffle is on. | ||
27 | } | 30 | } |
28 | panels { | 31 | panels { |
29 | name: "HINT" | 32 | name: "HINT" |
diff --git a/data/maps/the_entry/rooms/Trick Room.txtpb b/data/maps/the_entry/rooms/Trick Room.txtpb index ff9be38..d20502e 100644 --- a/data/maps/the_entry/rooms/Trick Room.txtpb +++ b/data/maps/the_entry/rooms/Trick Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Trick Room" | 1 | name: "Trick Room" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | panels { | 3 | panels { |
4 | name: "INK" | 4 | name: "INK" |
5 | path: "Panels/Entry/l_opener_1" | 5 | path: "Panels/Entry/l_opener_1" |
diff --git a/data/maps/the_entry/rooms/White Hallway To Daedalus.txtpb b/data/maps/the_entry/rooms/White Hallway To Daedalus.txtpb index bf1398d..de0cec2 100644 --- a/data/maps/the_entry/rooms/White Hallway To Daedalus.txtpb +++ b/data/maps/the_entry/rooms/White Hallway To Daedalus.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "White Hallway To Daedalus" | 1 | name: "White Hallway To Daedalus" |
2 | display_name: "Colored Doors Area" | 2 | panel_display_name: "Colored Doors Area" |
3 | ports { | 3 | ports { |
4 | name: "DAEDALUS" | 4 | name: "DAEDALUS" |
5 | display_name: "White Control Center Hallway" | ||
5 | path: "Components/Warps/worldport11" | 6 | path: "Components/Warps/worldport11" |
6 | orientation: "west" | 7 | destination { x: -45 y: 0 z: 24 } |
8 | rotation: 270 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_entry/rooms/Wrath Room.txtpb b/data/maps/the_entry/rooms/Wrath Room.txtpb index 29bd1cb..903a0b7 100644 --- a/data/maps/the_entry/rooms/Wrath Room.txtpb +++ b/data/maps/the_entry/rooms/Wrath Room.txtpb | |||
@@ -1,21 +1,5 @@ | |||
1 | name: "Wrath Room" | 1 | name: "Wrath Room" |
2 | display_name: "Red Blue Area" | 2 | panel_display_name: "Red Blue Area" |
3 | panels { | ||
4 | name: "RABBIT" | ||
5 | path: "Panels/Back Right/br_4" | ||
6 | clue: "rabbit" | ||
7 | answer: "hair" | ||
8 | symbols: SUN | ||
9 | symbols: ZERO | ||
10 | } | ||
11 | panels { | ||
12 | name: "HOLE" | ||
13 | path: "Panels/Back Right/br_5" | ||
14 | clue: "hole" | ||
15 | answer: "part" | ||
16 | symbols: ZERO | ||
17 | symbols: BOXES | ||
18 | } | ||
19 | panels { | 3 | panels { |
20 | name: "WREATH" | 4 | name: "WREATH" |
21 | path: "Panels/Back Right/br_17" | 5 | path: "Panels/Back Right/br_17" |
diff --git a/data/maps/the_entry/rooms/X Area.txtpb b/data/maps/the_entry/rooms/X Area.txtpb index ada16f8..8388b4e 100644 --- a/data/maps/the_entry/rooms/X Area.txtpb +++ b/data/maps/the_entry/rooms/X Area.txtpb | |||
@@ -1,11 +1,13 @@ | |||
1 | name: "X Area" | 1 | name: "X Area" |
2 | display_name: "Starting Room" | 2 | panel_display_name: "Starting Room" |
3 | letters { | 3 | letters { |
4 | key: "x" | 4 | key: "x" |
5 | path: "Components/Collectables/x" | 5 | path: "Components/Collectables/x" |
6 | } | 6 | } |
7 | ports { | 7 | ports { |
8 | name: "CC" | 8 | name: "CC" |
9 | display_name: "Near X1 Worldport" | ||
9 | path: "Components/Warps/worldport3" | 10 | path: "Components/Warps/worldport3" |
10 | orientation: "west" | 11 | destination { x: -12.5 y: 0 z: 60 } |
12 | rotation: 270 | ||
11 | } | 13 | } |
diff --git a/data/maps/the_extravagant/rooms/E Room.txtpb b/data/maps/the_extravagant/rooms/E Room.txtpb index 4b1f284..2f91764 100644 --- a/data/maps/the_extravagant/rooms/E Room.txtpb +++ b/data/maps/the_extravagant/rooms/E Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "E Room" | 1 | name: "E Room" |
2 | display_name: "3" | ||
3 | letters { | 2 | letters { |
4 | key: "e" | 3 | key: "e" |
5 | path: "Components/Collectables/e" | 4 | path: "Components/Collectables/e" |
diff --git a/data/maps/the_extravagant/rooms/Engine Room.txtpb b/data/maps/the_extravagant/rooms/Engine Room.txtpb index 79b60fc..7157757 100644 --- a/data/maps/the_extravagant/rooms/Engine Room.txtpb +++ b/data/maps/the_extravagant/rooms/Engine Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Engine Room" | 1 | name: "Engine Room" |
2 | display_name: "Engine Room" | ||
3 | panels { | 2 | panels { |
4 | name: "ENGINE" | 3 | name: "ENGINE" |
5 | path: "Panels/panel_8" | 4 | path: "Panels/panel_8" |
@@ -23,7 +22,9 @@ paintings { | |||
23 | } | 22 | } |
24 | ports { | 23 | ports { |
25 | name: "GALLERY" | 24 | name: "GALLERY" |
25 | display_name: "Engine Room Worldport" | ||
26 | path: "Components/Warps/worldport2" | 26 | path: "Components/Warps/worldport2" |
27 | gravity: Z_PLUS | 27 | gravity: Z_PLUS |
28 | # TODO: orientation is not well defined with Z-axis gravity | 28 | # TODO: entrance shuffling for non Y axis gravity |
29 | no_shuffle: true | ||
29 | } | 30 | } |
diff --git a/data/maps/the_extravagant/rooms/Hat Chamber.txtpb b/data/maps/the_extravagant/rooms/Hat Chamber.txtpb index 049959c..a100130 100644 --- a/data/maps/the_extravagant/rooms/Hat Chamber.txtpb +++ b/data/maps/the_extravagant/rooms/Hat Chamber.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Hat Chamber" | 1 | name: "Hat Chamber" |
2 | display_name: "3" | ||
3 | panels { | 2 | panels { |
4 | name: "BRIM" | 3 | name: "BRIM" |
5 | path: "Panels/panel_14" | 4 | path: "Panels/panel_14" |
diff --git a/data/maps/the_extravagant/rooms/X Minus Middle Leg.txtpb b/data/maps/the_extravagant/rooms/X Minus Middle Leg.txtpb index 660a7dd..1455a4b 100644 --- a/data/maps/the_extravagant/rooms/X Minus Middle Leg.txtpb +++ b/data/maps/the_extravagant/rooms/X Minus Middle Leg.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "X Minus Middle Leg" | 1 | name: "X Minus Middle Leg" |
2 | display_name: "W" | ||
3 | panels { | 2 | panels { |
4 | name: "ANTENNA" | 3 | name: "ANTENNA" |
5 | path: "Panels/panel_7" | 4 | path: "Panels/panel_7" |
diff --git a/data/maps/the_extravagant/rooms/X Minus Right Leg.txtpb b/data/maps/the_extravagant/rooms/X Minus Right Leg.txtpb index ce731b6..ea45e10 100644 --- a/data/maps/the_extravagant/rooms/X Minus Right Leg.txtpb +++ b/data/maps/the_extravagant/rooms/X Minus Right Leg.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "X Minus Right Leg" | 1 | name: "X Minus Right Leg" |
2 | display_name: "W" | ||
3 | panels { | 2 | panels { |
4 | name: "ROWBOAT" | 3 | name: "ROWBOAT" |
5 | path: "Panels/panel_13" | 4 | path: "Panels/panel_13" |
diff --git a/data/maps/the_extravagant/rooms/X Minus.txtpb b/data/maps/the_extravagant/rooms/X Minus.txtpb index 3f389f1..92b15dc 100644 --- a/data/maps/the_extravagant/rooms/X Minus.txtpb +++ b/data/maps/the_extravagant/rooms/X Minus.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "X Minus" | 1 | name: "X Minus" |
2 | display_name: "W" | ||
3 | panels { | 2 | panels { |
4 | name: "DUO" | 3 | name: "DUO" |
5 | path: "Panels/panel_1" | 4 | path: "Panels/panel_1" |
diff --git a/data/maps/the_extravagant/rooms/X Plus Middle Leg.txtpb b/data/maps/the_extravagant/rooms/X Plus Middle Leg.txtpb index c656593..cb7cba6 100644 --- a/data/maps/the_extravagant/rooms/X Plus Middle Leg.txtpb +++ b/data/maps/the_extravagant/rooms/X Plus Middle Leg.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "X Plus Middle Leg" | 1 | name: "X Plus Middle Leg" |
2 | display_name: "M" | ||
3 | panels { | 2 | panels { |
4 | name: "COLONY" | 3 | name: "COLONY" |
5 | path: "Panels/panel_10" | 4 | path: "Panels/panel_10" |
diff --git a/data/maps/the_extravagant/rooms/X Plus Right Leg.txtpb b/data/maps/the_extravagant/rooms/X Plus Right Leg.txtpb index 7c75550..98dfad6 100644 --- a/data/maps/the_extravagant/rooms/X Plus Right Leg.txtpb +++ b/data/maps/the_extravagant/rooms/X Plus Right Leg.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "X Plus Right Leg" | 1 | name: "X Plus Right Leg" |
2 | display_name: "M" | ||
3 | panels { | 2 | panels { |
4 | name: "HEAD" | 3 | name: "HEAD" |
5 | path: "Panels/panel_4" | 4 | path: "Panels/panel_4" |
diff --git a/data/maps/the_extravagant/rooms/X Plus.txtpb b/data/maps/the_extravagant/rooms/X Plus.txtpb index db42770..a1c4b9d 100644 --- a/data/maps/the_extravagant/rooms/X Plus.txtpb +++ b/data/maps/the_extravagant/rooms/X Plus.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "X Plus" | 1 | name: "X Plus" |
2 | display_name: "M" | ||
3 | panels { | 2 | panels { |
4 | name: "ROSE" | 3 | name: "ROSE" |
5 | path: "Panels/panel_16" | 4 | path: "Panels/panel_16" |
@@ -24,4 +23,5 @@ paintings { | |||
24 | keyholders { | 23 | keyholders { |
25 | name: "M" | 24 | name: "M" |
26 | path: "Components/KeyHolders/keyHolderM" | 25 | path: "Components/KeyHolders/keyHolderM" |
26 | key: "m" | ||
27 | } | 27 | } |
diff --git a/data/maps/the_extravagant/rooms/Y Minus First Floor.txtpb b/data/maps/the_extravagant/rooms/Y Minus First Floor.txtpb index 1429fa8..f80d68a 100644 --- a/data/maps/the_extravagant/rooms/Y Minus First Floor.txtpb +++ b/data/maps/the_extravagant/rooms/Y Minus First Floor.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Y Minus First Floor" | 1 | name: "Y Minus First Floor" |
2 | display_name: "3" | ||
3 | panels { | 2 | panels { |
4 | name: "RHINO" | 3 | name: "RHINO" |
5 | path: "Panels/panel_2" | 4 | path: "Panels/panel_2" |
diff --git a/data/maps/the_extravagant/rooms/Y Minus Second Floor.txtpb b/data/maps/the_extravagant/rooms/Y Minus Second Floor.txtpb index be3238a..34a3c9d 100644 --- a/data/maps/the_extravagant/rooms/Y Minus Second Floor.txtpb +++ b/data/maps/the_extravagant/rooms/Y Minus Second Floor.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Y Minus Second Floor" | 1 | name: "Y Minus Second Floor" |
2 | display_name: "3" | ||
3 | panels { | 2 | panels { |
4 | name: "COMPASS" | 3 | name: "COMPASS" |
5 | path: "Panels/panel_5" | 4 | path: "Panels/panel_5" |
diff --git a/data/maps/the_extravagant/rooms/Y Minus Third Floor.txtpb b/data/maps/the_extravagant/rooms/Y Minus Third Floor.txtpb index 881d42d..7aa5e1c 100644 --- a/data/maps/the_extravagant/rooms/Y Minus Third Floor.txtpb +++ b/data/maps/the_extravagant/rooms/Y Minus Third Floor.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Y Minus Third Floor" | 1 | name: "Y Minus Third Floor" |
2 | display_name: "3" | ||
3 | panels { | 2 | panels { |
4 | name: "WHISKERS" | 3 | name: "WHISKERS" |
5 | path: "Panels/panel_11" | 4 | path: "Panels/panel_11" |
diff --git a/data/maps/the_extravagant/rooms/Y Plus First Floor.txtpb b/data/maps/the_extravagant/rooms/Y Plus First Floor.txtpb index 9c8120c..6226aa6 100644 --- a/data/maps/the_extravagant/rooms/Y Plus First Floor.txtpb +++ b/data/maps/the_extravagant/rooms/Y Plus First Floor.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Y Plus First Floor" | 1 | name: "Y Plus First Floor" |
2 | display_name: "E" | ||
3 | paintings { | 2 | paintings { |
4 | name: "UNDUE" | 3 | name: "UNDUE" |
5 | path: "Components/Paintings/undue4" | 4 | path: "Components/Paintings/undue4" |
diff --git a/data/maps/the_extravagant/rooms/Y Plus Third Floor.txtpb b/data/maps/the_extravagant/rooms/Y Plus Third Floor.txtpb index bdc45b9..1cf0480 100644 --- a/data/maps/the_extravagant/rooms/Y Plus Third Floor.txtpb +++ b/data/maps/the_extravagant/rooms/Y Plus Third Floor.txtpb | |||
@@ -1,6 +1,5 @@ | |||
1 | name: "Y Plus Third Floor" | 1 | name: "Y Plus Third Floor" |
2 | # It's the second floor too... | 2 | # It's the second floor too... |
3 | display_name: "E" | ||
4 | panels { | 3 | panels { |
5 | name: "CACTUS" | 4 | name: "CACTUS" |
6 | path: "Panels/panel_6" | 5 | path: "Panels/panel_6" |
diff --git a/data/maps/the_gallery/doors.txtpb b/data/maps/the_gallery/doors.txtpb index e269daf..adbc766 100644 --- a/data/maps/the_gallery/doors.txtpb +++ b/data/maps/the_gallery/doors.txtpb | |||
@@ -1,8 +1,9 @@ | |||
1 | # The Gallery is interesting because there's so many cross-map requirements. | 1 | # The Gallery is interesting because there's so many cross-map requirements. |
2 | doors { | 2 | doors { |
3 | name: "Darkroom Painting" | 3 | name: "Darkroom Painting" |
4 | type: ITEM_ONLY | 4 | type: GALLERY_PAINTING |
5 | move_paintings { room: "Main Area" name: "DARKROOM" } | 5 | #move_paintings { room: "Main Area" name: "DARKROOM" } |
6 | receivers: "Components/Paintings/darkroom/teleportListener" | ||
6 | panels { map: "the_darkroom" room: "First Room" name: "BISON" } | 7 | panels { map: "the_darkroom" room: "First Room" name: "BISON" } |
7 | panels { map: "the_darkroom" room: "First Room" name: "FISH" } | 8 | panels { map: "the_darkroom" room: "First Room" name: "FISH" } |
8 | panels { map: "the_darkroom" room: "First Room" name: "SHEEP" } | 9 | panels { map: "the_darkroom" room: "First Room" name: "SHEEP" } |
@@ -26,14 +27,16 @@ doors { | |||
26 | } | 27 | } |
27 | doors { | 28 | doors { |
28 | name: "Butterfly Painting" | 29 | name: "Butterfly Painting" |
29 | type: ITEM_ONLY | 30 | type: GALLERY_PAINTING |
30 | move_paintings { room: "Main Area" name: "BUTTERFLY" } | 31 | #move_paintings { room: "Main Area" name: "BUTTERFLY" } |
32 | receivers: "Components/Paintings/butterfly/teleportListener" | ||
31 | rooms { map: "the_butterfly" name: "Main Area" } | 33 | rooms { map: "the_butterfly" name: "Main Area" } |
32 | } | 34 | } |
33 | doors { | 35 | doors { |
34 | name: "Between Painting" | 36 | name: "Between Painting" |
35 | type: ITEM_ONLY | 37 | type: GALLERY_PAINTING |
36 | move_paintings { room: "Main Area" name: "BETWEEN" } | 38 | #move_paintings { room: "Main Area" name: "BETWEEN" } |
39 | receivers: "Components/Paintings/between/teleportListener" | ||
37 | panels { map: "the_between" room: "Main Area" name: "SUN" } | 40 | panels { map: "the_between" room: "Main Area" name: "SUN" } |
38 | panels { map: "the_between" room: "Main Area" name: "KOI" } | 41 | panels { map: "the_between" room: "Main Area" name: "KOI" } |
39 | panels { map: "the_between" room: "Main Area" name: "SUN KOI" } | 42 | panels { map: "the_between" room: "Main Area" name: "SUN KOI" } |
@@ -67,14 +70,16 @@ doors { | |||
67 | } | 70 | } |
68 | doors { | 71 | doors { |
69 | name: "Entry Painting" | 72 | name: "Entry Painting" |
70 | type: ITEM_ONLY | 73 | type: GALLERY_PAINTING |
71 | move_paintings { room: "Main Area" name: "ENTRY" } | 74 | #move_paintings { room: "Main Area" name: "ENTRY" } |
75 | receivers: "Components/Paintings/eyes/teleportListener" | ||
72 | panels { map: "the_entry" room: "Eye Room" name: "I" } | 76 | panels { map: "the_entry" room: "Eye Room" name: "I" } |
73 | } | 77 | } |
74 | doors { | 78 | doors { |
75 | name: "Wise Painting" | 79 | name: "Wise Painting" |
76 | type: ITEM_ONLY | 80 | type: GALLERY_PAINTING |
77 | move_paintings { room: "Main Area" name: "WISE" } | 81 | #move_paintings { room: "Main Area" name: "WISE" } |
82 | receivers: "Components/Paintings/triangle/teleportListener" | ||
78 | panels { map: "the_wise" room: "Entry" name: "INK" } | 83 | panels { map: "the_wise" room: "Entry" name: "INK" } |
79 | panels { map: "the_wise" room: "Puzzles" name: "STORY" } | 84 | panels { map: "the_wise" room: "Puzzles" name: "STORY" } |
80 | panels { map: "the_wise" room: "Puzzles" name: "VENTURE" } | 85 | panels { map: "the_wise" room: "Puzzles" name: "VENTURE" } |
@@ -100,8 +105,9 @@ doors { | |||
100 | } | 105 | } |
101 | doors { | 106 | doors { |
102 | name: "Tree Painting" | 107 | name: "Tree Painting" |
103 | type: ITEM_ONLY | 108 | type: GALLERY_PAINTING |
104 | move_paintings { room: "Main Area" name: "TREE" } | 109 | #move_paintings { room: "Main Area" name: "TREE" } |
110 | receivers: "Components/Paintings/Clue Maps/tree/teleportListener" | ||
105 | panels { map: "the_tree" room: "Main Area" name: "COLOR" } | 111 | panels { map: "the_tree" room: "Main Area" name: "COLOR" } |
106 | panels { map: "the_tree" room: "Main Area" name: "DAMAGE (1)" } | 112 | panels { map: "the_tree" room: "Main Area" name: "DAMAGE (1)" } |
107 | panels { map: "the_tree" room: "Main Area" name: "DAMAGE (2)" } | 113 | panels { map: "the_tree" room: "Main Area" name: "DAMAGE (2)" } |
@@ -136,32 +142,37 @@ doors { | |||
136 | } | 142 | } |
137 | doors { | 143 | doors { |
138 | name: "Unyielding Painting" | 144 | name: "Unyielding Painting" |
139 | type: ITEM_ONLY | 145 | type: GALLERY_PAINTING |
140 | move_paintings { room: "Main Area" name: "UNYIELDING" } | 146 | #move_paintings { room: "Main Area" name: "UNYIELDING" } |
147 | receivers: "Components/Paintings/Clue Maps/unyielding/teleportListener" | ||
141 | rooms { map: "the_unyielding" name: "Digital Entrance" } | 148 | rooms { map: "the_unyielding" name: "Digital Entrance" } |
142 | } | 149 | } |
143 | doors { | 150 | doors { |
144 | name: "Graveyard Painting" | 151 | name: "Graveyard Painting" |
145 | type: ITEM_ONLY | 152 | type: GALLERY_PAINTING |
146 | move_paintings { room: "Main Area" name: "GRAVEYARD" } | 153 | #move_paintings { room: "Main Area" name: "GRAVEYARD" } |
154 | receivers: "Components/Paintings/Endings/grave/teleportListener" | ||
147 | rooms { map: "the_graveyard" name: "Outside" } | 155 | rooms { map: "the_graveyard" name: "Outside" } |
148 | } | 156 | } |
149 | doors { | 157 | doors { |
150 | name: "Control Center Painting" | 158 | name: "Control Center Painting" |
151 | type: ITEM_ONLY | 159 | type: GALLERY_PAINTING |
152 | move_paintings { room: "Main Area" name: "CC" } | 160 | #move_paintings { room: "Main Area" name: "CC" } |
161 | receivers: "Components/Paintings/Endings/desert/teleportListener" | ||
153 | rooms { map: "the_impressive" name: "M2 Room" } | 162 | rooms { map: "the_impressive" name: "M2 Room" } |
154 | } | 163 | } |
155 | doors { | 164 | doors { |
156 | name: "Tower Painting" | 165 | name: "Tower Painting" |
157 | type: ITEM_ONLY | 166 | type: GALLERY_PAINTING |
158 | move_paintings { room: "Main Area" name: "TOWER" } | 167 | #move_paintings { room: "Main Area" name: "TOWER" } |
168 | receivers: "Components/Paintings/Endings/red/teleportListener" | ||
159 | rooms { map: "the_tower" name: "First Floor" } | 169 | rooms { map: "the_tower" name: "First Floor" } |
160 | } | 170 | } |
161 | doors { | 171 | doors { |
162 | name: "Wondrous Painting" | 172 | name: "Wondrous Painting" |
163 | type: ITEM_ONLY | 173 | type: GALLERY_PAINTING |
164 | move_paintings { room: "Main Area" name: "WONDROUS" } | 174 | #move_paintings { room: "Main Area" name: "WONDROUS" } |
175 | receivers: "Components/Paintings/Endings/window/teleportListener" | ||
165 | panels { map: "the_wondrous" room: "Entry" name: "WONDER" } | 176 | panels { map: "the_wondrous" room: "Entry" name: "WONDER" } |
166 | panels { map: "the_wondrous" room: "Regular" name: "SHRINK" } | 177 | panels { map: "the_wondrous" room: "Regular" name: "SHRINK" } |
167 | panels { map: "the_wondrous" room: "Huge" name: "SHRINK" } | 178 | panels { map: "the_wondrous" room: "Huge" name: "SHRINK" } |
@@ -176,38 +187,44 @@ doors { | |||
176 | } | 187 | } |
177 | doors { | 188 | doors { |
178 | name: "Rainbow Painting" | 189 | name: "Rainbow Painting" |
179 | type: ITEM_ONLY | 190 | type: GALLERY_PAINTING |
180 | move_paintings { room: "Main Area" name: "RAINBOW" } | 191 | #move_paintings { room: "Main Area" name: "RAINBOW" } |
192 | receivers: "Components/Paintings/Endings/rainbow/teleportListener" | ||
181 | rooms { map: "daedalus" name: "Rainbow Start" } | 193 | rooms { map: "daedalus" name: "Rainbow Start" } |
182 | } | 194 | } |
183 | doors { | 195 | doors { |
184 | name: "Words Painting" | 196 | name: "Words Painting" |
185 | type: ITEM_ONLY | 197 | type: GALLERY_PAINTING |
186 | move_paintings { room: "Main Area" name: "WORDS" } | 198 | #move_paintings { room: "Main Area" name: "WORDS" } |
199 | receivers: "Components/Paintings/Endings/words/teleportListener" | ||
187 | rooms { map: "the_words" name: "Main Area" } | 200 | rooms { map: "the_words" name: "Main Area" } |
188 | } | 201 | } |
189 | doors { | 202 | doors { |
190 | name: "Colorful Painting" | 203 | name: "Colorful Painting" |
191 | type: ITEM_ONLY | 204 | type: GALLERY_PAINTING |
192 | move_paintings { room: "Main Area" name: "COLORFUL" } | 205 | #move_paintings { room: "Main Area" name: "COLORFUL" } |
206 | receivers: "Components/Paintings/Endings/colorful/teleportListener" | ||
193 | rooms { map: "the_colorful" name: "White Room" } | 207 | rooms { map: "the_colorful" name: "White Room" } |
194 | } | 208 | } |
195 | doors { | 209 | doors { |
196 | name: "Castle Painting" | 210 | name: "Castle Painting" |
197 | type: ITEM_ONLY | 211 | type: GALLERY_PAINTING |
198 | move_paintings { room: "Main Area" name: "CASTLE" } | 212 | #move_paintings { room: "Main Area" name: "CASTLE" } |
213 | receivers: "Components/Paintings/Endings/castle/teleportListener" | ||
199 | rooms { map: "daedalus" name: "Castle" } | 214 | rooms { map: "daedalus" name: "Castle" } |
200 | } | 215 | } |
201 | doors { | 216 | doors { |
202 | name: "Sun Temple Painting" | 217 | name: "Sun Temple Painting" |
203 | type: ITEM_ONLY | 218 | type: GALLERY_PAINTING |
204 | move_paintings { room: "Main Area" name: "SUNTEMPLE" } | 219 | #move_paintings { room: "Main Area" name: "SUNTEMPLE" } |
220 | receivers: "Components/Paintings/Endings/temple/teleportListener" | ||
205 | rooms { map: "the_sun_temple" name: "Entrance" } | 221 | rooms { map: "the_sun_temple" name: "Entrance" } |
206 | } | 222 | } |
207 | doors { | 223 | doors { |
208 | name: "Ancient Painting" | 224 | name: "Ancient Painting" |
209 | type: ITEM_ONLY | 225 | type: GALLERY_PAINTING |
210 | move_paintings { room: "Main Area" name: "ANCIENT" } | 226 | #move_paintings { room: "Main Area" name: "ANCIENT" } |
227 | receivers: "Components/Paintings/Endings/cubes/teleportListener" | ||
211 | rooms { map: "the_ancient" name: "Outside" } | 228 | rooms { map: "the_ancient" name: "Outside" } |
212 | } | 229 | } |
213 | doors { | 230 | doors { |
diff --git a/data/maps/the_gallery/rooms/Back Room.txtpb b/data/maps/the_gallery/rooms/Back Room.txtpb index baf7270..74d5304 100644 --- a/data/maps/the_gallery/rooms/Back Room.txtpb +++ b/data/maps/the_gallery/rooms/Back Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Back Room" | 1 | name: "Back Room" |
2 | display_name: "Back Room" | ||
3 | panels { | 2 | panels { |
4 | name: "UNYIELDING" | 3 | name: "UNYIELDING" |
5 | path: "Panels/entry_2" | 4 | path: "Panels/entry_2" |
diff --git a/data/maps/the_gallery/rooms/Daedalus Extension.txtpb b/data/maps/the_gallery/rooms/Daedalus Extension.txtpb index e525a2c..51d2be5 100644 --- a/data/maps/the_gallery/rooms/Daedalus Extension.txtpb +++ b/data/maps/the_gallery/rooms/Daedalus Extension.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Daedalus Extension" | 1 | name: "Daedalus Extension" |
2 | display_name: "Daedalus Extension" | ||
3 | panels { | 2 | panels { |
4 | name: "WHERE" | 3 | name: "WHERE" |
5 | path: "Panels/entry_1" | 4 | path: "Panels/entry_1" |
diff --git a/data/maps/the_gallery/rooms/Ending.txtpb b/data/maps/the_gallery/rooms/Ending.txtpb index 72c8e72..f713acc 100644 --- a/data/maps/the_gallery/rooms/Ending.txtpb +++ b/data/maps/the_gallery/rooms/Ending.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Ending" | 1 | name: "Ending" |
2 | display_name: "Back Room" | ||
3 | endings { | 2 | endings { |
4 | name: "YELLOW" | 3 | name: "YELLOW" |
5 | path: "Components/Endings/yellow_ending" | 4 | path: "Components/Endings/yellow_ending" |
diff --git a/data/maps/the_gallery/rooms/Main Area.txtpb b/data/maps/the_gallery/rooms/Main Area.txtpb index a8fb3c6..e88dc48 100644 --- a/data/maps/the_gallery/rooms/Main Area.txtpb +++ b/data/maps/the_gallery/rooms/Main Area.txtpb | |||
@@ -1,8 +1,8 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | ||
3 | keyholders { | 2 | keyholders { |
4 | name: "P" | 3 | name: "P" |
5 | path: "Components/KeyHolders/keyHolderP" | 4 | path: "Components/KeyHolders/keyHolderP" |
5 | key: "p" | ||
6 | } | 6 | } |
7 | paintings { | 7 | paintings { |
8 | name: "OWL" | 8 | name: "OWL" |
@@ -162,6 +162,8 @@ paintings { | |||
162 | } | 162 | } |
163 | ports { | 163 | ports { |
164 | name: "ENTRY" | 164 | name: "ENTRY" |
165 | display_name: "Entrance" | ||
165 | path: "Components/Warps/worldport" | 166 | path: "Components/Warps/worldport" |
166 | orientation: "west" | 167 | destination { x: -3.5 y: 0 z: 16 } |
168 | rotation: 270 | ||
167 | } | 169 | } |
diff --git a/data/maps/the_gold/rooms/The Whole Thing.txtpb b/data/maps/the_gold/rooms/The Whole Thing.txtpb index 026e709..4848c1f 100644 --- a/data/maps/the_gold/rooms/The Whole Thing.txtpb +++ b/data/maps/the_gold/rooms/The Whole Thing.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "The Whole Thing" | 1 | name: "The Whole Thing" |
2 | display_name: "The Whole Thing" | ||
3 | panels { | 2 | panels { |
4 | name: "PANEL" | 3 | name: "PANEL" |
5 | path: "Panels/Room_1/panel_1" | 4 | path: "Panels/Room_1/panel_1" |
diff --git a/data/maps/the_graveyard/doors.txtpb b/data/maps/the_graveyard/doors.txtpb index f06d40d..a10d8f6 100644 --- a/data/maps/the_graveyard/doors.txtpb +++ b/data/maps/the_graveyard/doors.txtpb | |||
@@ -19,6 +19,7 @@ doors { | |||
19 | doors { | 19 | doors { |
20 | name: "Double Letters" | 20 | name: "Double Letters" |
21 | type: EVENT | 21 | type: EVENT |
22 | switches: "double_letters" | 22 | receivers: "Panels/panel_3/teleportListener" |
23 | # TODO: once again, not sure whether this is how it should work | 23 | receivers: "Components/Paintings/omrt/teleportListener" |
24 | double_letters: true | ||
24 | } | 25 | } |
diff --git a/data/maps/the_graveyard/rooms/Inside.txtpb b/data/maps/the_graveyard/rooms/Inside.txtpb index fd2fc9d..1f58d3f 100644 --- a/data/maps/the_graveyard/rooms/Inside.txtpb +++ b/data/maps/the_graveyard/rooms/Inside.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Inside" | 1 | name: "Inside" |
2 | display_name: "Inside" | ||
3 | panels { | 2 | panels { |
4 | name: "REMEMBER" | 3 | name: "REMEMBER" |
5 | path: "Panels/panel_3" | 4 | path: "Panels/panel_3" |
diff --git a/data/maps/the_graveyard/rooms/Outside.txtpb b/data/maps/the_graveyard/rooms/Outside.txtpb index b0e5ee9..db9de1b 100644 --- a/data/maps/the_graveyard/rooms/Outside.txtpb +++ b/data/maps/the_graveyard/rooms/Outside.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Outside" | 1 | name: "Outside" |
2 | display_name: "Outside" | ||
3 | panels { | 2 | panels { |
4 | name: "FOOT" | 3 | name: "FOOT" |
5 | path: "Panels/panel_1" | 4 | path: "Panels/panel_1" |
diff --git a/data/maps/the_great/connections.txtpb b/data/maps/the_great/connections.txtpb index f1a7e25..171e809 100644 --- a/data/maps/the_great/connections.txtpb +++ b/data/maps/the_great/connections.txtpb | |||
@@ -256,3 +256,7 @@ connections { | |||
256 | to_room: "Zero Room" | 256 | to_room: "Zero Room" |
257 | door { name: "Lavender Cube" } | 257 | door { name: "Lavender Cube" } |
258 | } | 258 | } |
259 | connections { | ||
260 | from_room: "Back Area" | ||
261 | to_room: "The Landscapes" | ||
262 | } | ||
diff --git a/data/maps/the_great/doors.txtpb b/data/maps/the_great/doors.txtpb index 463eaba..bf28421 100644 --- a/data/maps/the_great/doors.txtpb +++ b/data/maps/the_great/doors.txtpb | |||
@@ -49,6 +49,7 @@ doors { | |||
49 | type: LOCATION_ONLY | 49 | type: LOCATION_ONLY |
50 | panels { room: "West Side" name: "ERASE" } | 50 | panels { room: "West Side" name: "ERASE" } |
51 | location_room: "West Side" | 51 | location_room: "West Side" |
52 | location_name: "ERASE" | ||
52 | } | 53 | } |
53 | doors { | 54 | doors { |
54 | name: "Control Center Purple Door" | 55 | name: "Control Center Purple Door" |
@@ -59,13 +60,13 @@ doors { | |||
59 | doors { | 60 | doors { |
60 | name: "Control Center Gray Door" | 61 | name: "Control Center Gray Door" |
61 | type: CONTROL_CENTER_COLOR | 62 | type: CONTROL_CENTER_COLOR |
62 | receivers: "Components/Doors/Gates/Gate" | 63 | receivers: "Components/Doors/Gates/Gate/animationListener" |
63 | control_center_color: "gray" | 64 | control_center_color: "gray" |
64 | } | 65 | } |
65 | doors { | 66 | doors { |
66 | name: "Control Center Red Door" | 67 | name: "Control Center Red Door" |
67 | type: CONTROL_CENTER_COLOR | 68 | type: CONTROL_CENTER_COLOR |
68 | receivers: "Components/Doors/Gates/Gate" | 69 | receivers: "Components/Doors/entry_18" |
69 | control_center_color: "red" | 70 | control_center_color: "red" |
70 | } | 71 | } |
71 | doors { | 72 | doors { |
@@ -98,7 +99,8 @@ doors { | |||
98 | doors { | 99 | doors { |
99 | name: "Savory Painting" | 100 | name: "Savory Painting" |
100 | type: STANDARD | 101 | type: STANDARD |
101 | move_paintings { room: "West Side" name: "EXTRAVAGANT" } | 102 | #move_paintings { room: "West Side" name: "EXTRAVAGANT" } |
103 | receivers: "Components/Paintings/unless/teleportListener" | ||
102 | panels { room: "West Side" name: "SAVORY" } | 104 | panels { room: "West Side" name: "SAVORY" } |
103 | panels { room: "West Side" name: "FLAVORS" } | 105 | panels { room: "West Side" name: "FLAVORS" } |
104 | location_room: "West Side" | 106 | location_room: "West Side" |
@@ -122,6 +124,7 @@ doors { | |||
122 | panels { room: "Magnet Room" name: "SAW" } | 124 | panels { room: "Magnet Room" name: "SAW" } |
123 | panels { room: "Magnet Room" name: "BLENDER" } | 125 | panels { room: "Magnet Room" name: "BLENDER" } |
124 | location_room: "Magnet Room" | 126 | location_room: "Magnet Room" |
127 | location_name: "Gravestone" | ||
125 | } | 128 | } |
126 | doors { | 129 | doors { |
127 | name: "Hive Entrance" | 130 | name: "Hive Entrance" |
@@ -141,6 +144,7 @@ doors { | |||
141 | panels { room: "Pillar Room" name: "CAUGHT" } | 144 | panels { room: "Pillar Room" name: "CAUGHT" } |
142 | panels { room: "Pillar Room" name: "TEN" } | 145 | panels { room: "Pillar Room" name: "TEN" } |
143 | location_room: "Pillar Room" | 146 | location_room: "Pillar Room" |
147 | location_name: "Puzzles" | ||
144 | } | 148 | } |
145 | doors { | 149 | doors { |
146 | name: "North Landscape Entrance" | 150 | name: "North Landscape Entrance" |
@@ -202,29 +206,31 @@ doors { | |||
202 | panels { room: "Jail Part 2" name: "GRIMACE" } | 206 | panels { room: "Jail Part 2" name: "GRIMACE" } |
203 | panels { room: "Jail Part 2" name: "COMMENCE" } | 207 | panels { room: "Jail Part 2" name: "COMMENCE" } |
204 | location_room: "Jail Part 2" | 208 | location_room: "Jail Part 2" |
209 | location_name: "Gravestone" | ||
205 | } | 210 | } |
206 | doors { | 211 | doors { |
207 | name: "The Landscapes Gravestone" | 212 | name: "The Landscapes Gravestone" |
208 | type: GRAVESTONE | 213 | type: GRAVESTONE |
209 | panels { room: "Back Area" name: "Top Landscape Top" } | 214 | panels { room: "The Landscapes" name: "Top Landscape Top" } |
210 | panels { room: "Back Area" name: "Top Landscape Right" } | 215 | panels { room: "The Landscapes" name: "Top Landscape Right" } |
211 | panels { room: "Back Area" name: "Top Landscape Bottom" } | 216 | panels { room: "The Landscapes" name: "Top Landscape Bottom" } |
212 | panels { room: "Back Area" name: "Top Landscape Left" } | 217 | panels { room: "The Landscapes" name: "Top Landscape Left" } |
213 | panels { room: "Back Area" name: "Left Landscape Top" } | 218 | panels { room: "The Landscapes" name: "Left Landscape Top" } |
214 | panels { room: "Back Area" name: "Left Landscape Right" } | 219 | panels { room: "The Landscapes" name: "Left Landscape Right" } |
215 | panels { room: "Back Area" name: "Left Landscape Bottom" } | 220 | panels { room: "The Landscapes" name: "Left Landscape Bottom" } |
216 | panels { room: "Back Area" name: "Left Landscape Left" } | 221 | panels { room: "The Landscapes" name: "Left Landscape Left" } |
217 | panels { room: "Back Area" name: "Right Landscape Top" } | 222 | panels { room: "The Landscapes" name: "Right Landscape Top" } |
218 | panels { room: "Back Area" name: "Right Landscape Right" } | 223 | panels { room: "The Landscapes" name: "Right Landscape Right" } |
219 | panels { room: "Back Area" name: "Right Landscape Bottom" } | 224 | panels { room: "The Landscapes" name: "Right Landscape Bottom" } |
220 | panels { room: "Back Area" name: "Right Landscape Left" } | 225 | panels { room: "The Landscapes" name: "Right Landscape Left" } |
221 | location_room: "Back Area" | 226 | location_room: "The Landscapes" |
227 | location_name: "Gravestone" | ||
222 | } | 228 | } |
223 | doors { | 229 | doors { |
224 | name: "Tower Entrance" | 230 | name: "Tower Entrance" |
225 | type: ITEM_ONLY | 231 | type: ITEM_ONLY |
226 | receivers: "Components/Doors/entry_25" | 232 | receivers: "Components/Doors/entry_25" |
227 | switches: "double_letters" | 233 | double_letters: true |
228 | } | 234 | } |
229 | doors { | 235 | doors { |
230 | name: "Maze Out/South Door" | 236 | name: "Maze Out/South Door" |
@@ -315,6 +321,7 @@ doors { | |||
315 | panels { room: "Maze Up Area" name: "UP" } | 321 | panels { room: "Maze Up Area" name: "UP" } |
316 | panels { room: "Maze Wreck Area" name: "WRECK" } | 322 | panels { room: "Maze Wreck Area" name: "WRECK" } |
317 | location_room: "Maze Slice Area" | 323 | location_room: "Maze Slice Area" |
324 | location_name: "Gravestone" | ||
318 | } | 325 | } |
319 | doors { | 326 | doors { |
320 | name: "Courtyard Side Door" | 327 | name: "Courtyard Side Door" |
@@ -390,11 +397,13 @@ doors { | |||
390 | name: "Big Y" | 397 | name: "Big Y" |
391 | type: STANDARD | 398 | type: STANDARD |
392 | receivers: "Components/Doors/question_3" | 399 | receivers: "Components/Doors/question_3" |
400 | receivers: "Components/Doors/question_12" | ||
393 | panels { room: "Question Room What" name: "QUESTION" answer: "why" } | 401 | panels { room: "Question Room What" name: "QUESTION" answer: "why" } |
394 | panels { room: "Question Room How" name: "QUESTION" answer: "why" } | 402 | panels { room: "Question Room How" name: "QUESTION" answer: "why" } |
395 | panels { room: "Question Room When" name: "QUESTION" answer: "why" } | 403 | panels { room: "Question Room When" name: "QUESTION" answer: "why" } |
396 | panels { room: "Question Room Who" name: "QUESTION" answer: "why" } | 404 | panels { room: "Question Room Who" name: "QUESTION" answer: "why" } |
397 | location_room: "Question Room Who" | 405 | location_room: "Question Room Who" |
406 | location_name: "Whys" | ||
398 | } | 407 | } |
399 | doors { | 408 | doors { |
400 | name: "Talented Entrance" | 409 | name: "Talented Entrance" |
@@ -414,9 +423,10 @@ doors { | |||
414 | name: "Invisible Entrance" | 423 | name: "Invisible Entrance" |
415 | type: STANDARD | 424 | type: STANDARD |
416 | receivers: "Components/Doors/entry_36" | 425 | receivers: "Components/Doors/entry_36" |
417 | panels { room: "Back Area" name: "Right Landscape Top" answer: "tell" } | 426 | panels { room: "The Landscapes" name: "Right Landscape Top" answer: "tell" } |
418 | panels { room: "Back Area" name: "Right Landscape Left" answer: "eyes" } | 427 | panels { room: "The Landscapes" name: "Right Landscape Left" answer: "eyes" } |
419 | location_room: "Back Area" | 428 | location_room: "The Landscapes" |
429 | location_name: "Alternate Answers" | ||
420 | } | 430 | } |
421 | doors { | 431 | doors { |
422 | name: "Nature Room Door" | 432 | name: "Nature Room Door" |
@@ -462,12 +472,17 @@ doors { | |||
462 | panels { room: "Whole Room" name: "CHIPS" } | 472 | panels { room: "Whole Room" name: "CHIPS" } |
463 | panels { room: "Whole Room" name: "TOWER" } | 473 | panels { room: "Whole Room" name: "TOWER" } |
464 | location_room: "Whole Room" | 474 | location_room: "Whole Room" |
475 | location_name: "Gravestone" | ||
465 | } | 476 | } |
466 | doors { | 477 | doors { |
467 | name: "Lavender Cube" | 478 | name: "Lavender Cube" |
468 | type: ITEM_ONLY | 479 | type: EVENT |
469 | receivers: "Components/Doors/entry_28" | 480 | receivers: "Components/Doors/entry_28" |
470 | switches: "lavender_cubes" | 481 | panels { |
482 | map: "the_ancient" | ||
483 | room: "Inside" | ||
484 | name: "COLOR" | ||
485 | } | ||
471 | } | 486 | } |
472 | doors { | 487 | doors { |
473 | name: "Zero Entrance" | 488 | name: "Zero Entrance" |
@@ -484,6 +499,7 @@ doors { | |||
484 | panels { room: "Zero Room" name: "MANY" } | 499 | panels { room: "Zero Room" name: "MANY" } |
485 | panels { room: "Zero Room" name: "REMAINING" } | 500 | panels { room: "Zero Room" name: "REMAINING" } |
486 | location_room: "Zero Room" | 501 | location_room: "Zero Room" |
502 | location_name: "Panels" | ||
487 | } | 503 | } |
488 | doors { | 504 | doors { |
489 | name: "Spiral Painting" | 505 | name: "Spiral Painting" |
@@ -492,3 +508,14 @@ doors { | |||
492 | panels { room: "Back Area" name: "PAINTING" } | 508 | panels { room: "Back Area" name: "PAINTING" } |
493 | location_room: "Back Area" | 509 | location_room: "Back Area" |
494 | } | 510 | } |
511 | doors { | ||
512 | name: "Cyan Doors" | ||
513 | type: EVENT | ||
514 | receivers: "Panels/General/entry_7/teleportListener" | ||
515 | double_letters: true | ||
516 | } | ||
517 | doors { | ||
518 | name: "Partial Entrance" | ||
519 | type: EVENT | ||
520 | panels { room: "West Side" name: "CLUE" } | ||
521 | } | ||
diff --git a/data/maps/the_great/rooms/Back Area.txtpb b/data/maps/the_great/rooms/Back Area.txtpb index 3701249..33da394 100644 --- a/data/maps/the_great/rooms/Back Area.txtpb +++ b/data/maps/the_great/rooms/Back Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Back Area" | 1 | name: "Back Area" |
2 | display_name: "Back Area" | 2 | panel_display_name: "Back Area" |
3 | panels { | 3 | panels { |
4 | name: "PLANT" | 4 | name: "PLANT" |
5 | path: "Panels/General/entry_14" | 5 | path: "Panels/General/entry_14" |
@@ -28,92 +28,6 @@ panels { | |||
28 | answer: "tower" | 28 | answer: "tower" |
29 | symbols: SPARKLES | 29 | symbols: SPARKLES |
30 | } | 30 | } |
31 | panels { | ||
32 | name: "Top Landscape Top" | ||
33 | path: "Panels/Kiwi Room/kiwi_1" | ||
34 | clue: "" | ||
35 | answer: "one" | ||
36 | symbols: QUESTION | ||
37 | } | ||
38 | panels { | ||
39 | name: "Top Landscape Right" | ||
40 | path: "Panels/Kiwi Room/kiwi_2" | ||
41 | clue: "" | ||
42 | answer: "road" | ||
43 | symbols: QUESTION | ||
44 | } | ||
45 | panels { | ||
46 | name: "Top Landscape Bottom" | ||
47 | path: "Panels/Kiwi Room/kiwi_3" | ||
48 | clue: "" | ||
49 | answer: "many" | ||
50 | symbols: QUESTION | ||
51 | } | ||
52 | panels { | ||
53 | name: "Top Landscape Left" | ||
54 | path: "Panels/Kiwi Room/kiwi_4" | ||
55 | clue: "" | ||
56 | answer: "turns" | ||
57 | symbols: QUESTION | ||
58 | } | ||
59 | panels { | ||
60 | name: "Left Landscape Top" | ||
61 | path: "Panels/Kiwi Room/kiwi_5" | ||
62 | clue: "" | ||
63 | answer: "find" | ||
64 | symbols: QUESTION | ||
65 | } | ||
66 | panels { | ||
67 | name: "Left Landscape Right" | ||
68 | path: "Panels/Kiwi Room/kiwi_6" | ||
69 | clue: "" | ||
70 | answer: "keys" | ||
71 | symbols: QUESTION | ||
72 | } | ||
73 | panels { | ||
74 | name: "Left Landscape Bottom" | ||
75 | path: "Panels/Kiwi Room/kiwi_7" | ||
76 | clue: "" | ||
77 | answer: "write" | ||
78 | symbols: QUESTION | ||
79 | } | ||
80 | panels { | ||
81 | name: "Left Landscape Left" | ||
82 | path: "Panels/Kiwi Room/kiwi_8" | ||
83 | clue: "" | ||
84 | answer: "words" | ||
85 | symbols: QUESTION | ||
86 | } | ||
87 | panels { | ||
88 | name: "Right Landscape Top" | ||
89 | path: "Panels/Kiwi Room/kiwi_9" | ||
90 | clue: "" | ||
91 | answer: "hear" | ||
92 | symbols: QUESTION | ||
93 | proxies { answer: "tell" path: "Panels/Kiwi Proxies/kiwi_9_proxy_1" } | ||
94 | } | ||
95 | panels { | ||
96 | name: "Right Landscape Right" | ||
97 | path: "Panels/Kiwi Room/kiwi_10" | ||
98 | clue: "" | ||
99 | answer: "lies" | ||
100 | symbols: QUESTION | ||
101 | } | ||
102 | panels { | ||
103 | name: "Right Landscape Bottom" | ||
104 | path: "Panels/Kiwi Room/kiwi_11" | ||
105 | clue: "" | ||
106 | answer: "the" | ||
107 | symbols: QUESTION | ||
108 | } | ||
109 | panels { | ||
110 | name: "Right Landscape Left" | ||
111 | path: "Panels/Kiwi Room/kiwi_12" | ||
112 | clue: "" | ||
113 | answer: "ears" | ||
114 | symbols: QUESTION | ||
115 | proxies { answer: "eyes" path: "Panels/Kiwi Proxies/kiwi_12_proxy_1" } | ||
116 | } | ||
117 | paintings { | 31 | paintings { |
118 | name: "SPIRAL" | 32 | name: "SPIRAL" |
119 | path: "Components/Paintings/spiral" | 33 | path: "Components/Paintings/spiral" |
@@ -124,23 +38,31 @@ paintings { | |||
124 | } | 38 | } |
125 | ports { | 39 | ports { |
126 | name: "UNKEMPT" | 40 | name: "UNKEMPT" |
41 | display_name: "Unkempt Entrance" | ||
127 | path: "Meshes/Blocks/Warps/worldport5" | 42 | path: "Meshes/Blocks/Warps/worldport5" |
128 | orientation: "north" | 43 | destination { x: 72 y: 0 z: 10.5 } |
44 | rotation: 180 | ||
129 | } | 45 | } |
130 | ports { | 46 | ports { |
131 | name: "THREEDOORS" | 47 | name: "THREEDOORS" |
48 | display_name: "Three Doors Entrance" | ||
132 | path: "Meshes/Blocks/Warps/worldport16" | 49 | path: "Meshes/Blocks/Warps/worldport16" |
133 | orientation: "south" | 50 | destination { x: 77 y: 0 z: 33.5 } |
51 | rotation: 0 | ||
134 | } | 52 | } |
135 | ports { | 53 | ports { |
136 | name: "TOWER" | 54 | name: "TOWER" |
55 | display_name: "Tower Entrance" | ||
137 | path: "Meshes/Blocks/Warps/worldport10" | 56 | path: "Meshes/Blocks/Warps/worldport10" |
138 | orientation: "south" | 57 | destination { x: 0 y: 0 z: 52 } |
58 | rotation: 0 | ||
139 | required_door { name: "Tower Entrance" } | 59 | required_door { name: "Tower Entrance" } |
140 | # The reverse warp bypasses the door, so there needs to be two oneway connections. | 60 | # The reverse warp bypasses the door, so there needs to be two oneway connections. |
141 | } | 61 | } |
142 | ports { | 62 | ports { |
143 | name: "TREE" | 63 | name: "TREE" |
64 | display_name: "Tree Entrance" | ||
144 | path: "Meshes/Blocks/Warps/worldport17" | 65 | path: "Meshes/Blocks/Warps/worldport17" |
145 | orientation: "north" | 66 | destination { x: 26 y: 0 z: 58 } |
67 | rotation: 180 | ||
146 | } | 68 | } |
diff --git a/data/maps/the_great/rooms/Behind Question Area.txtpb b/data/maps/the_great/rooms/Behind Question Area.txtpb index 88f800f..744d4c4 100644 --- a/data/maps/the_great/rooms/Behind Question Area.txtpb +++ b/data/maps/the_great/rooms/Behind Question Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Behind Question Area" | 1 | name: "Behind Question Area" |
2 | display_name: "Main Area" | 2 | panel_display_name: "Question Room" |
3 | panels { | 3 | panels { |
4 | name: "DEW" | 4 | name: "DEW" |
5 | path: "Panels/General/uc_4" | 5 | path: "Panels/General/uc_4" |
diff --git a/data/maps/the_great/rooms/Colorful Entrance.txtpb b/data/maps/the_great/rooms/Colorful Entrance.txtpb index 5d7c9b2..5464698 100644 --- a/data/maps/the_great/rooms/Colorful Entrance.txtpb +++ b/data/maps/the_great/rooms/Colorful Entrance.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Colorful Entrance" | 1 | name: "Colorful Entrance" |
2 | display_name: "Pillar Room" | 2 | panel_display_name: "Pillar Room" |
3 | ports { | 3 | ports { |
4 | name: "COLORFUL" | 4 | name: "COLORFUL" |
5 | display_name: "Pillar Room Worldport" | ||
5 | path: "Meshes/Blocks/Warps/worldport13" | 6 | path: "Meshes/Blocks/Warps/worldport13" |
6 | orientation: "west" | 7 | destination { x: -37.5 y: 0 z: 74 } |
8 | rotation: 270 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_great/rooms/Daedalus Entrance.txtpb b/data/maps/the_great/rooms/Daedalus Entrance.txtpb index 7e1d477..abfab99 100644 --- a/data/maps/the_great/rooms/Daedalus Entrance.txtpb +++ b/data/maps/the_great/rooms/Daedalus Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Daedalus Entrance" | 1 | name: "Daedalus Entrance" |
2 | display_name: "Main Area" | 2 | panel_display_name: "Main Area" |
3 | panels { | 3 | panels { |
4 | name: "MISSING" | 4 | name: "MISSING" |
5 | path: "Panels/General/entry_2" | 5 | path: "Panels/General/entry_2" |
@@ -9,8 +9,10 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "DAEDALUS" | 11 | name: "DAEDALUS" |
12 | display_name: "Daedalus Entrance" | ||
12 | path: "Meshes/Blocks/Warps/worldport8" | 13 | path: "Meshes/Blocks/Warps/worldport8" |
13 | orientation: "south" | 14 | destination { x: 98 y: 2 z: 27.5 } |
15 | rotation: 0 | ||
14 | required_door { name: "Daedalus Entrance" } | 16 | required_door { name: "Daedalus Entrance" } |
15 | # The reverse warp bypasses the door, so there needs to be two oneway connections. | 17 | # The reverse warp bypasses the door, so there needs to be two oneway connections. |
16 | } | 18 | } |
diff --git a/data/maps/the_great/rooms/East Landscape.txtpb b/data/maps/the_great/rooms/East Landscape.txtpb index 84fc182..44ed2c5 100644 --- a/data/maps/the_great/rooms/East Landscape.txtpb +++ b/data/maps/the_great/rooms/East Landscape.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "East Landscape" | 1 | name: "East Landscape" |
2 | display_name: "East Landscape" | 2 | panel_display_name: "East Landscape" |
3 | panels { | 3 | panels { |
4 | name: "COLOR" | 4 | name: "COLOR" |
5 | path: "Panels/General/entry_10" | 5 | path: "Panels/General/entry_10" |
diff --git a/data/maps/the_great/rooms/G Room.txtpb b/data/maps/the_great/rooms/G Room.txtpb index 218a9c1..f93c899 100644 --- a/data/maps/the_great/rooms/G Room.txtpb +++ b/data/maps/the_great/rooms/G Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "G Room" | 1 | name: "G Room" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | letters { | 3 | letters { |
4 | key: "g" | 4 | key: "g" |
5 | path: "Components/Collectables/g" | 5 | path: "Components/Collectables/g" |
diff --git a/data/maps/the_great/rooms/Hive Entrance.txtpb b/data/maps/the_great/rooms/Hive Entrance.txtpb index ba886b1..56acc22 100644 --- a/data/maps/the_great/rooms/Hive Entrance.txtpb +++ b/data/maps/the_great/rooms/Hive Entrance.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Hive Entrance" | 1 | name: "Hive Entrance" |
2 | display_name: "West Side" | 2 | panel_display_name: "West Side" |
3 | panels { | 3 | panels { |
4 | name: "LOST" | 4 | name: "LOST" |
5 | path: "Panels/Hive Room/hive_1" | 5 | path: "Panels/Hive Room/hive_1" |
@@ -9,6 +9,8 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "HIVE" | 11 | name: "HIVE" |
12 | display_name: "Hive Entrance" | ||
12 | path: "Meshes/Blocks/Warps/worldport19" | 13 | path: "Meshes/Blocks/Warps/worldport19" |
13 | orientation: "east" | 14 | destination { x: -91.5 y: 0 z: 37 } |
15 | rotation: 90 | ||
14 | } | 16 | } |
diff --git a/data/maps/the_great/rooms/Jail Part 1.txtpb b/data/maps/the_great/rooms/Jail Part 1.txtpb index bd468bd..452841b 100644 --- a/data/maps/the_great/rooms/Jail Part 1.txtpb +++ b/data/maps/the_great/rooms/Jail Part 1.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Jail Part 1" | 1 | name: "Jail Part 1" |
2 | display_name: "Jail" | 2 | panel_display_name: "Jail" |
3 | panels { | 3 | panels { |
4 | name: "FLAP" | 4 | name: "FLAP" |
5 | path: "Panels/Throat/throat_1" | 5 | path: "Panels/Throat/throat_1" |
diff --git a/data/maps/the_great/rooms/Jail Part 2.txtpb b/data/maps/the_great/rooms/Jail Part 2.txtpb index 1f54dd5..1a0c975 100644 --- a/data/maps/the_great/rooms/Jail Part 2.txtpb +++ b/data/maps/the_great/rooms/Jail Part 2.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Jail Part 2" | 1 | name: "Jail Part 2" |
2 | display_name: "Jail" | 2 | panel_display_name: "Jail" |
3 | panels { | 3 | panels { |
4 | name: "DIGEST" | 4 | name: "DIGEST" |
5 | path: "Panels/Bowels3/bowels_1" | 5 | path: "Panels/Bowels3/bowels_1" |
diff --git a/data/maps/the_great/rooms/Jubilant Entrance.txtpb b/data/maps/the_great/rooms/Jubilant Entrance.txtpb index eaf9811..b254cc0 100644 --- a/data/maps/the_great/rooms/Jubilant Entrance.txtpb +++ b/data/maps/the_great/rooms/Jubilant Entrance.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Jubilant Entrance" | 1 | name: "Jubilant Entrance" |
2 | display_name: "West Side" | 2 | panel_display_name: "West Side" |
3 | ports { | 3 | ports { |
4 | name: "JUBILANT" | 4 | name: "JUBILANT" |
5 | display_name: "Jubilant Entrance" | ||
5 | path: "Meshes/Blocks/Warps/worldport12" | 6 | path: "Meshes/Blocks/Warps/worldport12" |
6 | orientation: "east" | 7 | destination { x: -62 y: 0 z: -19 } |
8 | rotation: 90 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_great/rooms/Magnet Room.txtpb b/data/maps/the_great/rooms/Magnet Room.txtpb index 4cf6433..2d122a4 100644 --- a/data/maps/the_great/rooms/Magnet Room.txtpb +++ b/data/maps/the_great/rooms/Magnet Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Magnet Room" | 1 | name: "Magnet Room" |
2 | display_name: "Magnet Room" | 2 | panel_display_name: "Magnet Room" |
3 | panels { | 3 | panels { |
4 | name: "AIRPLANE" | 4 | name: "AIRPLANE" |
5 | path: "Panels/Magnet Room/magnet_2" | 5 | path: "Panels/Magnet Room/magnet_2" |
diff --git a/data/maps/the_great/rooms/Main Area.txtpb b/data/maps/the_great/rooms/Main Area.txtpb index 40c7fbb..a5ed9f3 100644 --- a/data/maps/the_great/rooms/Main Area.txtpb +++ b/data/maps/the_great/rooms/Main Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | 2 | panel_display_name: "Main Area" |
3 | panels { | 3 | panels { |
4 | name: "INTRO" | 4 | name: "INTRO" |
5 | path: "Panels/General/entry_8" | 5 | path: "Panels/General/entry_8" |
@@ -111,6 +111,7 @@ panels { | |||
111 | answer: "high" | 111 | answer: "high" |
112 | symbols: SUN | 112 | symbols: SUN |
113 | symbols: ZERO | 113 | symbols: ZERO |
114 | required_door { name: "Cyan Doors" } | ||
114 | } | 115 | } |
115 | panels { | 116 | panels { |
116 | name: "CURT" | 117 | name: "CURT" |
@@ -121,27 +122,37 @@ panels { | |||
121 | } | 122 | } |
122 | ports { | 123 | ports { |
123 | name: "ENTRY" | 124 | name: "ENTRY" |
125 | display_name: "Entry Building" | ||
124 | path: "Meshes/Blocks/Warps/worldport" | 126 | path: "Meshes/Blocks/Warps/worldport" |
125 | orientation: "south" | 127 | destination { x: 33 y: 0 z: 15 } |
128 | rotation: 0 | ||
126 | } | 129 | } |
127 | ports { | 130 | ports { |
128 | name: "KEEN" | 131 | name: "KEEN" |
132 | display_name: "Keen Building Front" | ||
129 | path: "Meshes/Blocks/Warps/worldport6" | 133 | path: "Meshes/Blocks/Warps/worldport6" |
130 | orientation: "north" | 134 | destination { x: 33 y: 0 z: -21 } |
135 | rotation: 180 | ||
131 | } | 136 | } |
132 | ports { | 137 | ports { |
133 | name: "ORB" | 138 | name: "ORB" |
139 | display_name: "Orb Building" | ||
134 | path: "Meshes/Blocks/Warps/worldport3" | 140 | path: "Meshes/Blocks/Warps/worldport3" |
135 | orientation: "north" | 141 | destination { x: 62 y: 0 z: -13 } |
142 | rotation: 180 | ||
136 | } | 143 | } |
137 | ports { | 144 | ports { |
138 | name: "LINEAR" | 145 | name: "LINEAR" |
146 | display_name: "Keen Building Back" | ||
139 | path: "Meshes/Blocks/Warps/worldport15" | 147 | path: "Meshes/Blocks/Warps/worldport15" |
140 | orientation: "south" | 148 | destination { x: 33 y: 0 z: -42.5 } |
149 | rotation: 0 | ||
141 | } | 150 | } |
142 | ports { | 151 | ports { |
143 | name: "DIGITAL" | 152 | name: "DIGITAL" |
153 | display_name: "Digital Hole" | ||
144 | path: "Meshes/Blocks/Warps/worldport4" | 154 | path: "Meshes/Blocks/Warps/worldport4" |
145 | orientation: "down" | 155 | destination { x: -6.5 y: 0 z: 7.5 } |
156 | rotation: 0 | ||
146 | required_door { name: "Digital Entrance" } | 157 | required_door { name: "Digital Entrance" } |
147 | } | 158 | } |
diff --git a/data/maps/the_great/rooms/Maze Center.txtpb b/data/maps/the_great/rooms/Maze Center.txtpb index f557eaa..97ff146 100644 --- a/data/maps/the_great/rooms/Maze Center.txtpb +++ b/data/maps/the_great/rooms/Maze Center.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Center" | 1 | name: "Maze Center" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "POOR" | 4 | name: "POOR" |
5 | path: "Panels/Maze/maze_7" | 5 | path: "Panels/Maze/maze_7" |
diff --git a/data/maps/the_great/rooms/Maze Cold Area.txtpb b/data/maps/the_great/rooms/Maze Cold Area.txtpb index 5886ca8..70b311e 100644 --- a/data/maps/the_great/rooms/Maze Cold Area.txtpb +++ b/data/maps/the_great/rooms/Maze Cold Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Cold Area" | 1 | name: "Maze Cold Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "COLD" | 4 | name: "COLD" |
5 | path: "Panels/Maze/maze_11" | 5 | path: "Panels/Maze/maze_11" |
diff --git a/data/maps/the_great/rooms/Maze Empty Vestibule.txtpb b/data/maps/the_great/rooms/Maze Empty Vestibule.txtpb index d6f265f..1540ee2 100644 --- a/data/maps/the_great/rooms/Maze Empty Vestibule.txtpb +++ b/data/maps/the_great/rooms/Maze Empty Vestibule.txtpb | |||
@@ -1,2 +1,2 @@ | |||
1 | name: "Maze Empty Vestibule" | 1 | name: "Maze Empty Vestibule" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
diff --git a/data/maps/the_great/rooms/Maze In Area.txtpb b/data/maps/the_great/rooms/Maze In Area.txtpb index 13597a0..8c556aa 100644 --- a/data/maps/the_great/rooms/Maze In Area.txtpb +++ b/data/maps/the_great/rooms/Maze In Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze In Area" | 1 | name: "Maze In Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "IN" | 4 | name: "IN" |
5 | path: "Panels/Maze/maze_3" | 5 | path: "Panels/Maze/maze_3" |
diff --git a/data/maps/the_great/rooms/Maze Moon Area.txtpb b/data/maps/the_great/rooms/Maze Moon Area.txtpb index b515224..10af4a1 100644 --- a/data/maps/the_great/rooms/Maze Moon Area.txtpb +++ b/data/maps/the_great/rooms/Maze Moon Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Moon Area" | 1 | name: "Maze Moon Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "MOON" | 4 | name: "MOON" |
5 | path: "Panels/Maze/maze_9" | 5 | path: "Panels/Maze/maze_9" |
diff --git a/data/maps/the_great/rooms/Maze Off Area.txtpb b/data/maps/the_great/rooms/Maze Off Area.txtpb index 2fe7bed..c577129 100644 --- a/data/maps/the_great/rooms/Maze Off Area.txtpb +++ b/data/maps/the_great/rooms/Maze Off Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Off Area" | 1 | name: "Maze Off Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "OFF" | 4 | name: "OFF" |
5 | path: "Panels/Maze/maze_14" | 5 | path: "Panels/Maze/maze_14" |
diff --git a/data/maps/the_great/rooms/Maze Slice Area.txtpb b/data/maps/the_great/rooms/Maze Slice Area.txtpb index d720501..f59d6e5 100644 --- a/data/maps/the_great/rooms/Maze Slice Area.txtpb +++ b/data/maps/the_great/rooms/Maze Slice Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Slice Area" | 1 | name: "Maze Slice Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "SLICE" | 4 | name: "SLICE" |
5 | path: "Panels/Maze/maze_4" | 5 | path: "Panels/Maze/maze_4" |
diff --git a/data/maps/the_great/rooms/Maze Smooth Area.txtpb b/data/maps/the_great/rooms/Maze Smooth Area.txtpb index 8145357..156e885 100644 --- a/data/maps/the_great/rooms/Maze Smooth Area.txtpb +++ b/data/maps/the_great/rooms/Maze Smooth Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Smooth Area" | 1 | name: "Maze Smooth Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "SMOOTH" | 4 | name: "SMOOTH" |
5 | path: "Panels/Maze/maze_5" | 5 | path: "Panels/Maze/maze_5" |
diff --git a/data/maps/the_great/rooms/Maze South Area.txtpb b/data/maps/the_great/rooms/Maze South Area.txtpb index b3708db..e65778d 100644 --- a/data/maps/the_great/rooms/Maze South Area.txtpb +++ b/data/maps/the_great/rooms/Maze South Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze South Area" | 1 | name: "Maze South Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "SOUTH" | 4 | name: "SOUTH" |
5 | path: "Panels/Maze/maze_2" | 5 | path: "Panels/Maze/maze_2" |
diff --git a/data/maps/the_great/rooms/Maze Start.txtpb b/data/maps/the_great/rooms/Maze Start.txtpb index 1e89cbe..16a57f5 100644 --- a/data/maps/the_great/rooms/Maze Start.txtpb +++ b/data/maps/the_great/rooms/Maze Start.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Start" | 1 | name: "Maze Start" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "OUT" | 4 | name: "OUT" |
5 | path: "Panels/Maze/maze_1" | 5 | path: "Panels/Maze/maze_1" |
diff --git a/data/maps/the_great/rooms/Maze Tower.txtpb b/data/maps/the_great/rooms/Maze Tower.txtpb index 6a815aa..44c30d7 100644 --- a/data/maps/the_great/rooms/Maze Tower.txtpb +++ b/data/maps/the_great/rooms/Maze Tower.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Tower" | 1 | name: "Maze Tower" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "FEEL" | 4 | name: "FEEL" |
5 | path: "Panels/Maze/maze_12" | 5 | path: "Panels/Maze/maze_12" |
diff --git a/data/maps/the_great/rooms/Maze Up Area.txtpb b/data/maps/the_great/rooms/Maze Up Area.txtpb index 29f175b..0046cef 100644 --- a/data/maps/the_great/rooms/Maze Up Area.txtpb +++ b/data/maps/the_great/rooms/Maze Up Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Up Area" | 1 | name: "Maze Up Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "UP" | 4 | name: "UP" |
5 | path: "Panels/Maze/maze_15" | 5 | path: "Panels/Maze/maze_15" |
diff --git a/data/maps/the_great/rooms/Maze Wreck Area.txtpb b/data/maps/the_great/rooms/Maze Wreck Area.txtpb index 6808fc2..5710df5 100644 --- a/data/maps/the_great/rooms/Maze Wreck Area.txtpb +++ b/data/maps/the_great/rooms/Maze Wreck Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Maze Wreck Area" | 1 | name: "Maze Wreck Area" |
2 | display_name: "Courtyard" | 2 | panel_display_name: "Courtyard" |
3 | panels { | 3 | panels { |
4 | name: "WRECK" | 4 | name: "WRECK" |
5 | path: "Panels/Maze/maze_8" | 5 | path: "Panels/Maze/maze_8" |
diff --git a/data/maps/the_great/rooms/Nature Room.txtpb b/data/maps/the_great/rooms/Nature Room.txtpb index 9f798f3..464d3a2 100644 --- a/data/maps/the_great/rooms/Nature Room.txtpb +++ b/data/maps/the_great/rooms/Nature Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Nature Room" | 1 | name: "Nature Room" |
2 | display_name: "North Landscape" | 2 | panel_display_name: "North Landscape" |
3 | panels { | 3 | panels { |
4 | name: "SEVERE" | 4 | name: "SEVERE" |
5 | path: "Panels/General/nature_2" | 5 | path: "Panels/General/nature_2" |
diff --git a/data/maps/the_great/rooms/North Landscape.txtpb b/data/maps/the_great/rooms/North Landscape.txtpb index 959f351..f738ed3 100644 --- a/data/maps/the_great/rooms/North Landscape.txtpb +++ b/data/maps/the_great/rooms/North Landscape.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "North Landscape" | 1 | name: "North Landscape" |
2 | display_name: "North Landscape" | 2 | panel_display_name: "North Landscape" |
3 | panels { | 3 | panels { |
4 | name: "WEATHER" | 4 | name: "WEATHER" |
5 | path: "Panels/General/platforms_1" | 5 | path: "Panels/General/platforms_1" |
@@ -52,11 +52,13 @@ panels { | |||
52 | keyholders { | 52 | keyholders { |
53 | name: "X" | 53 | name: "X" |
54 | path: "Components/KeyHolders/keyHolderX" | 54 | path: "Components/KeyHolders/keyHolderX" |
55 | key: "x" | ||
55 | } | 56 | } |
56 | ports { | 57 | ports { |
57 | name: "INVISIBLE" | 58 | name: "INVISIBLE" |
59 | display_name: "Eye Worldport" | ||
58 | path: "Meshes/Blocks/Warps/worldport20" | 60 | path: "Meshes/Blocks/Warps/worldport20" |
59 | orientation: "north" | 61 | destination { x: 33 y: 0 z: -66.5 } |
60 | # Note that this can be easily entered from the other side. | 62 | rotation: 0 |
61 | required_door { name: "Invisible Entrance" } | 63 | required_door { name: "Invisible Entrance" } |
62 | } | 64 | } |
diff --git a/data/maps/the_great/rooms/Outside Jail.txtpb b/data/maps/the_great/rooms/Outside Jail.txtpb index ab30761..d6dfa71 100644 --- a/data/maps/the_great/rooms/Outside Jail.txtpb +++ b/data/maps/the_great/rooms/Outside Jail.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Outside Jail" | 1 | name: "Outside Jail" |
2 | display_name: "Jail" | 2 | panel_display_name: "Jail" |
3 | panels { | 3 | panels { |
4 | name: "GUT" | 4 | name: "GUT" |
5 | path: "Panels/Head/head_1" | 5 | path: "Panels/Head/head_1" |
diff --git a/data/maps/the_great/rooms/Pillar Room.txtpb b/data/maps/the_great/rooms/Pillar Room.txtpb index 01ff309..648b7b4 100644 --- a/data/maps/the_great/rooms/Pillar Room.txtpb +++ b/data/maps/the_great/rooms/Pillar Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Pillar Room" | 1 | name: "Pillar Room" |
2 | display_name: "Pillar Room" | 2 | panel_display_name: "Pillar Room" |
3 | panels { | 3 | panels { |
4 | name: "EYE" | 4 | name: "EYE" |
5 | path: "Panels/Impressive/entry_2" | 5 | path: "Panels/Impressive/entry_2" |
diff --git a/data/maps/the_great/rooms/Purple Room.txtpb b/data/maps/the_great/rooms/Purple Room.txtpb index ff9bd9a..12e79e7 100644 --- a/data/maps/the_great/rooms/Purple Room.txtpb +++ b/data/maps/the_great/rooms/Purple Room.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Purple Room" | 1 | name: "Purple Room" |
2 | display_name: "Main Area" | 2 | panel_display_name: "Main Area" |
3 | ports { | 3 | ports { |
4 | name: "DAEDALUS" | 4 | name: "DAEDALUS" |
5 | display_name: "Purple Hallway" | ||
5 | path: "Meshes/Blocks/Warps/worldport18" | 6 | path: "Meshes/Blocks/Warps/worldport18" |
6 | orientation: "north" | 7 | destination { x: 158 y: 0 z: 14 } |
8 | rotation: 180 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_great/rooms/Question Room How.txtpb b/data/maps/the_great/rooms/Question Room How.txtpb index 2f759b8..8f087d0 100644 --- a/data/maps/the_great/rooms/Question Room How.txtpb +++ b/data/maps/the_great/rooms/Question Room How.txtpb | |||
@@ -1,17 +1,18 @@ | |||
1 | name: "Question Room How" | 1 | name: "Question Room How" |
2 | display_name: "Question Room" | 2 | panel_display_name: "Question Room" |
3 | panels { | 3 | panels { |
4 | name: "QUESTION" | 4 | name: "QUESTION" |
5 | path: "Panels/Questions/question_3" | 5 | path: "Panels/Questions/question_3" |
6 | clue: "question" | 6 | clue: "question" |
7 | answer: "how" | 7 | answer: "how" |
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | # "Panels/Question Proxies/question_3_proxied" <- this is just how again | 9 | proxies { answer: "how" path: "Panels/Question Proxies/question_3_proxied" } |
10 | proxies { answer: "who" path: "Panels/Question Proxies/question_3_proxied2" } | 10 | proxies { answer: "who" path: "Panels/Question Proxies/question_3_proxied2" } |
11 | proxies { answer: "why" path: "Panels/Question Proxies/question_3_proxied3" } | 11 | proxies { answer: "why" path: "Panels/Question Proxies/question_3_proxied3" } |
12 | proxies { answer: "what" path: "Panels/Question Proxies/question_3_proxied4" } | 12 | proxies { answer: "what" path: "Panels/Question Proxies/question_3_proxied4" } |
13 | proxies { answer: "when" path: "Panels/Question Proxies/question_3_proxied5" } | 13 | proxies { answer: "when" path: "Panels/Question Proxies/question_3_proxied5" } |
14 | proxies { answer: "where" path: "Panels/Question Proxies/question_3_proxied6" } | 14 | proxies { answer: "where" path: "Panels/Question Proxies/question_3_proxied6" } |
15 | display_name: "QUESTION (How)" | ||
15 | } | 16 | } |
16 | paintings { | 17 | paintings { |
17 | name: "WHY" | 18 | name: "WHY" |
diff --git a/data/maps/the_great/rooms/Question Room What.txtpb b/data/maps/the_great/rooms/Question Room What.txtpb index 9cfd667..a61ccef 100644 --- a/data/maps/the_great/rooms/Question Room What.txtpb +++ b/data/maps/the_great/rooms/Question Room What.txtpb | |||
@@ -1,15 +1,16 @@ | |||
1 | name: "Question Room What" | 1 | name: "Question Room What" |
2 | display_name: "Question Room" | 2 | panel_display_name: "Question Room" |
3 | panels { | 3 | panels { |
4 | name: "QUESTION" | 4 | name: "QUESTION" |
5 | path: "Panels/Questions/question_4" | 5 | path: "Panels/Questions/question_4" |
6 | clue: "question" | 6 | clue: "question" |
7 | answer: "what" | 7 | answer: "what" |
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | proxies { answer: "why" path: "Panels/Question Proxies/question_4_proxied" } | 9 | proxies { answer: "what" path: "Panels/Question Proxies/question_4_proxied" } |
10 | proxies { answer: "who" path: "Panels/Question Proxies/question_4_proxied2" } | 10 | proxies { answer: "why" path: "Panels/Question Proxies/question_4_proxied2" } |
11 | proxies { answer: "where" path: "Panels/Question Proxies/question_4_proxied3" } | 11 | proxies { answer: "when" path: "Panels/Question Proxies/question_4_proxied3" } |
12 | proxies { answer: "how" path: "Panels/Question Proxies/question_4_proxied4" } | 12 | proxies { answer: "how" path: "Panels/Question Proxies/question_4_proxied4" } |
13 | # "Panels/Question Proxies/question_4_proxied5" <- this is just what again | 13 | proxies { answer: "who" path: "Panels/Question Proxies/question_4_proxied5" } |
14 | proxies { answer: "when" path: "Panels/Question Proxies/question_4_proxied6" } | 14 | proxies { answer: "where" path: "Panels/Question Proxies/question_4_proxied6" } |
15 | display_name: "QUESTION (What)" | ||
15 | } | 16 | } |
diff --git a/data/maps/the_great/rooms/Question Room When.txtpb b/data/maps/the_great/rooms/Question Room When.txtpb index e046edd..b3ee2db 100644 --- a/data/maps/the_great/rooms/Question Room When.txtpb +++ b/data/maps/the_great/rooms/Question Room When.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Question Room When" | 1 | name: "Question Room When" |
2 | display_name: "Question Room" | 2 | panel_display_name: "Question Room" |
3 | panels { | 3 | panels { |
4 | name: "QUESTION" | 4 | name: "QUESTION" |
5 | path: "Panels/Questions/question_1" | 5 | path: "Panels/Questions/question_1" |
@@ -8,10 +8,11 @@ panels { | |||
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | proxies { answer: "when" path: "Panels/Question Proxies/question_1_proxied" } | 9 | proxies { answer: "when" path: "Panels/Question Proxies/question_1_proxied" } |
10 | proxies { answer: "why" path: "Panels/Question Proxies/question_1_proxied2" } | 10 | proxies { answer: "why" path: "Panels/Question Proxies/question_1_proxied2" } |
11 | # "Panels/Question Proxies/question_1_proxied3" <- this is just what again | 11 | proxies { answer: "what" path: "Panels/Question Proxies/question_1_proxied3" } |
12 | proxies { answer: "who" path: "Panels/Question Proxies/question_1_proxied4" } | 12 | proxies { answer: "who" path: "Panels/Question Proxies/question_1_proxied4" } |
13 | proxies { answer: "how" path: "Panels/Question Proxies/question_1_proxied5" } | 13 | proxies { answer: "how" path: "Panels/Question Proxies/question_1_proxied5" } |
14 | proxies { answer: "where" path: "Panels/Question Proxies/question_1_proxied6" } | 14 | proxies { answer: "where" path: "Panels/Question Proxies/question_1_proxied6" } |
15 | display_name: "QUESTION (When)" | ||
15 | } | 16 | } |
16 | paintings { | 17 | paintings { |
17 | name: "WHY" | 18 | name: "WHY" |
diff --git a/data/maps/the_great/rooms/Question Room Who.txtpb b/data/maps/the_great/rooms/Question Room Who.txtpb index cbaba4b..eb80882 100644 --- a/data/maps/the_great/rooms/Question Room Who.txtpb +++ b/data/maps/the_great/rooms/Question Room Who.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Question Room Who" | 1 | name: "Question Room Who" |
2 | display_name: "Question Room" | 2 | panel_display_name: "Question Room" |
3 | panels { | 3 | panels { |
4 | name: "QUESTION" | 4 | name: "QUESTION" |
5 | path: "Panels/Questions/question_2" | 5 | path: "Panels/Questions/question_2" |
@@ -7,9 +7,10 @@ panels { | |||
7 | answer: "who" | 7 | answer: "who" |
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | proxies { answer: "why" path: "Panels/Question Proxies/question_2_proxied" } | 9 | proxies { answer: "why" path: "Panels/Question Proxies/question_2_proxied" } |
10 | # "Panels/Question Proxies/question_2_proxied2" <- this is just who again | 10 | proxies { answer: "who" path: "Panels/Question Proxies/question_2_proxied2" } |
11 | proxies { answer: "where" path: "Panels/Question Proxies/question_2_proxied3" } | 11 | proxies { answer: "where" path: "Panels/Question Proxies/question_2_proxied3" } |
12 | proxies { answer: "how" path: "Panels/Question Proxies/question_2_proxied4" } | 12 | proxies { answer: "how" path: "Panels/Question Proxies/question_2_proxied4" } |
13 | proxies { answer: "what" path: "Panels/Question Proxies/question_2_proxied5" } | 13 | proxies { answer: "what" path: "Panels/Question Proxies/question_2_proxied5" } |
14 | proxies { answer: "when" path: "Panels/Question Proxies/question_2_proxied6" } | 14 | proxies { answer: "when" path: "Panels/Question Proxies/question_2_proxied6" } |
15 | display_name: "QUESTION (Who)" | ||
15 | } | 16 | } |
diff --git a/data/maps/the_great/rooms/Salmon Room.txtpb b/data/maps/the_great/rooms/Salmon Room.txtpb index 96efd1a..8458829 100644 --- a/data/maps/the_great/rooms/Salmon Room.txtpb +++ b/data/maps/the_great/rooms/Salmon Room.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Salmon Room" | 1 | name: "Salmon Room" |
2 | display_name: "Main Area" | 2 | panel_display_name: "Main Area" |
3 | ports { | 3 | ports { |
4 | name: "BETWEEN" | 4 | name: "BETWEEN" |
5 | display_name: "Salmon Hallway" | ||
5 | path: "Meshes/Blocks/Warps/worldport11" | 6 | path: "Meshes/Blocks/Warps/worldport11" |
6 | orientation: "east" | 7 | destination { x: 83 y: 0 z: -21 } |
8 | rotation: 90 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_great/rooms/Talented Entrance.txtpb b/data/maps/the_great/rooms/Talented Entrance.txtpb index 038c7e7..53c27dc 100644 --- a/data/maps/the_great/rooms/Talented Entrance.txtpb +++ b/data/maps/the_great/rooms/Talented Entrance.txtpb | |||
@@ -1,7 +1,9 @@ | |||
1 | name: "Talented Entrance" | 1 | name: "Talented Entrance" |
2 | display_name: "Question Room" | 2 | panel_display_name: "Question Room" |
3 | ports { | 3 | ports { |
4 | name: "TALENTED" | 4 | name: "TALENTED" |
5 | display_name: "Under Question Room Worldport" | ||
5 | path: "Meshes/Blocks/Warps/worldport14" | 6 | path: "Meshes/Blocks/Warps/worldport14" |
6 | orientation: "south" | 7 | destination { x: 109 y: -6 z: -26.5 } |
8 | rotation: 0 | ||
7 | } | 9 | } |
diff --git a/data/maps/the_great/rooms/The Landscapes.txtpb b/data/maps/the_great/rooms/The Landscapes.txtpb new file mode 100644 index 0000000..2912843 --- /dev/null +++ b/data/maps/the_great/rooms/The Landscapes.txtpb | |||
@@ -0,0 +1,88 @@ | |||
1 | name: "The Landscapes" | ||
2 | panel_display_name: "The Landscapes" | ||
3 | panels { | ||
4 | name: "Top Landscape Top" | ||
5 | path: "Panels/Kiwi Room/kiwi_1" | ||
6 | clue: "" | ||
7 | answer: "one" | ||
8 | symbols: QUESTION | ||
9 | } | ||
10 | panels { | ||
11 | name: "Top Landscape Right" | ||
12 | path: "Panels/Kiwi Room/kiwi_2" | ||
13 | clue: "" | ||
14 | answer: "road" | ||
15 | symbols: QUESTION | ||
16 | } | ||
17 | panels { | ||
18 | name: "Top Landscape Bottom" | ||
19 | path: "Panels/Kiwi Room/kiwi_3" | ||
20 | clue: "" | ||
21 | answer: "many" | ||
22 | symbols: QUESTION | ||
23 | } | ||
24 | panels { | ||
25 | name: "Top Landscape Left" | ||
26 | path: "Panels/Kiwi Room/kiwi_4" | ||
27 | clue: "" | ||
28 | answer: "turns" | ||
29 | symbols: QUESTION | ||
30 | } | ||
31 | panels { | ||
32 | name: "Left Landscape Top" | ||
33 | path: "Panels/Kiwi Room/kiwi_5" | ||
34 | clue: "" | ||
35 | answer: "find" | ||
36 | symbols: QUESTION | ||
37 | } | ||
38 | panels { | ||
39 | name: "Left Landscape Right" | ||
40 | path: "Panels/Kiwi Room/kiwi_6" | ||
41 | clue: "" | ||
42 | answer: "keys" | ||
43 | symbols: QUESTION | ||
44 | } | ||
45 | panels { | ||
46 | name: "Left Landscape Bottom" | ||
47 | path: "Panels/Kiwi Room/kiwi_7" | ||
48 | clue: "" | ||
49 | answer: "write" | ||
50 | symbols: QUESTION | ||
51 | } | ||
52 | panels { | ||
53 | name: "Left Landscape Left" | ||
54 | path: "Panels/Kiwi Room/kiwi_8" | ||
55 | clue: "" | ||
56 | answer: "words" | ||
57 | symbols: QUESTION | ||
58 | } | ||
59 | panels { | ||
60 | name: "Right Landscape Top" | ||
61 | path: "Panels/Kiwi Room/kiwi_9" | ||
62 | clue: "" | ||
63 | answer: "hear" | ||
64 | symbols: QUESTION | ||
65 | proxies { answer: "tell" path: "Panels/Kiwi Proxies/kiwi_9_proxy_1" } | ||
66 | } | ||
67 | panels { | ||
68 | name: "Right Landscape Right" | ||
69 | path: "Panels/Kiwi Room/kiwi_10" | ||
70 | clue: "" | ||
71 | answer: "lies" | ||
72 | symbols: QUESTION | ||
73 | } | ||
74 | panels { | ||
75 | name: "Right Landscape Bottom" | ||
76 | path: "Panels/Kiwi Room/kiwi_11" | ||
77 | clue: "" | ||
78 | answer: "the" | ||
79 | symbols: QUESTION | ||
80 | } | ||
81 | panels { | ||
82 | name: "Right Landscape Left" | ||
83 | path: "Panels/Kiwi Room/kiwi_12" | ||
84 | clue: "" | ||
85 | answer: "ears" | ||
86 | symbols: QUESTION | ||
87 | proxies { answer: "eyes" path: "Panels/Kiwi Proxies/kiwi_12_proxy_1" } | ||
88 | } | ||
diff --git a/data/maps/the_great/rooms/Under Question Room.txtpb b/data/maps/the_great/rooms/Under Question Room.txtpb index 249c0b4..db751bb 100644 --- a/data/maps/the_great/rooms/Under Question Room.txtpb +++ b/data/maps/the_great/rooms/Under Question Room.txtpb | |||
@@ -1,10 +1,12 @@ | |||
1 | name: "Under Question Room" | 1 | name: "Under Question Room" |
2 | display_name: "Question Room" | 2 | panel_display_name: "Question Room" |
3 | panels { | 3 | panels { |
4 | name: "QUESTION" | 4 | name: "QUESTION" |
5 | path: "Panels/General/question_1" | 5 | path: "Panels/General/question_1" |
6 | clue: "question" | 6 | clue: "question" |
7 | answer: "which" | 7 | answer: "which" |
8 | symbols: EXAMPLE | 8 | symbols: EXAMPLE |
9 | proxies { answer: "which" path: "Panels/General/question_1_proxy_1" } | ||
9 | proxies { answer: "where" path: "Panels/General/question_1_proxy_2" } | 10 | proxies { answer: "where" path: "Panels/General/question_1_proxy_2" } |
11 | display_name: "QUESTION (Where)" | ||
10 | } | 12 | } |
diff --git a/data/maps/the_great/rooms/West Side.txtpb b/data/maps/the_great/rooms/West Side.txtpb index 4723213..9f098ee 100644 --- a/data/maps/the_great/rooms/West Side.txtpb +++ b/data/maps/the_great/rooms/West Side.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "West Side" | 1 | name: "West Side" |
2 | display_name: "West Side" | 2 | panel_display_name: "West Side" |
3 | panels { | 3 | panels { |
4 | name: "ERASE" | 4 | name: "ERASE" |
5 | path: "Panels/General/entry_9" | 5 | path: "Panels/General/entry_9" |
@@ -63,17 +63,24 @@ paintings { | |||
63 | } | 63 | } |
64 | ports { | 64 | ports { |
65 | name: "IMPRESSIVE" | 65 | name: "IMPRESSIVE" |
66 | display_name: "Impressive Entrance" | ||
66 | path: "Meshes/Blocks/Warps/worldport2" | 67 | path: "Meshes/Blocks/Warps/worldport2" |
67 | orientation: "south" | 68 | destination { x: -34 y: 0 z: 22.5 } |
69 | rotation: 0 | ||
68 | } | 70 | } |
69 | ports { | 71 | ports { |
70 | name: "CC" | 72 | name: "CC" |
73 | display_name: "Control Center" | ||
71 | path: "Meshes/Blocks/Warps/worldport9" | 74 | path: "Meshes/Blocks/Warps/worldport9" |
72 | orientation: "north" | 75 | destination { x: -59 y: 0 z: -50.5 } |
76 | rotation: 180 | ||
73 | } | 77 | } |
74 | ports { | 78 | ports { |
75 | name: "PARTIAL" | 79 | name: "PARTIAL" |
80 | display_name: "Red Hallway" | ||
76 | path: "Meshes/Blocks/Warps/worldport7" | 81 | path: "Meshes/Blocks/Warps/worldport7" |
77 | orientation: "east" | 82 | destination { x: -62 y: 0 z: 11 } |
83 | rotation: 90 | ||
78 | # ER with this is weird; make sure to place on the surface | 84 | # ER with this is weird; make sure to place on the surface |
85 | required_door { name: "Partial Entrance" } | ||
79 | } | 86 | } |
diff --git a/data/maps/the_great/rooms/Whole Room.txtpb b/data/maps/the_great/rooms/Whole Room.txtpb index 2f5c855..989241a 100644 --- a/data/maps/the_great/rooms/Whole Room.txtpb +++ b/data/maps/the_great/rooms/Whole Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Whole Room" | 1 | name: "Whole Room" |
2 | display_name: "North Landscape" | 2 | panel_display_name: "Building Building" |
3 | panels { | 3 | panels { |
4 | name: "VAULT" | 4 | name: "VAULT" |
5 | path: "Panels/Whole Room/whole_1" | 5 | path: "Panels/Whole Room/whole_1" |
diff --git a/data/maps/the_great/rooms/Y Room.txtpb b/data/maps/the_great/rooms/Y Room.txtpb index b20420c..46c83ea 100644 --- a/data/maps/the_great/rooms/Y Room.txtpb +++ b/data/maps/the_great/rooms/Y Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Y Room" | 1 | name: "Y Room" |
2 | display_name: "Question Room" | 2 | panel_display_name: "Question Room" |
3 | letters { | 3 | letters { |
4 | key: "y" | 4 | key: "y" |
5 | path: "Components/Collectables/y" | 5 | path: "Components/Collectables/y" |
diff --git a/data/maps/the_great/rooms/Zero Room.txtpb b/data/maps/the_great/rooms/Zero Room.txtpb index dcbe067..54675bf 100644 --- a/data/maps/the_great/rooms/Zero Room.txtpb +++ b/data/maps/the_great/rooms/Zero Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Zero Room" | 1 | name: "Zero Room" |
2 | display_name: "Zero Room" | 2 | panel_display_name: "Zero Room" |
3 | panels { | 3 | panels { |
4 | name: "HERO" | 4 | name: "HERO" |
5 | path: "Panels/General/zero_1" | 5 | path: "Panels/General/zero_1" |
diff --git a/data/maps/the_hinterlands/rooms/Main Area.txtpb b/data/maps/the_hinterlands/rooms/Main Area.txtpb index ad44b38..5cd626b 100644 --- a/data/maps/the_hinterlands/rooms/Main Area.txtpb +++ b/data/maps/the_hinterlands/rooms/Main Area.txtpb | |||
@@ -1,13 +1,16 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Main Area" | ||
3 | # I'm probably not going to include any of the panels in here. | 2 | # I'm probably not going to include any of the panels in here. |
4 | ports { | 3 | ports { |
5 | name: "RIGHT" | 4 | name: "RIGHT" |
5 | display_name: "South Worldport" | ||
6 | path: "Components/Warps/worldport" | 6 | path: "Components/Warps/worldport" |
7 | orientation: "east" | 7 | destination { x: 30 y: 0 z: 19 } |
8 | rotation: 270 | ||
8 | } | 9 | } |
9 | ports { | 10 | ports { |
10 | name: "LEFT" | 11 | name: "LEFT" |
12 | display_name: "North Worldport" | ||
11 | path: "Components/Warps/worldport2" | 13 | path: "Components/Warps/worldport2" |
12 | orientation: "east" | 14 | destination { x: 30 y: 0 z: -76 } |
15 | rotation: 270 | ||
13 | } | 16 | } |
diff --git a/data/maps/the_hive/doors.txtpb b/data/maps/the_hive/doors.txtpb index 4d86e13..48dc892 100644 --- a/data/maps/the_hive/doors.txtpb +++ b/data/maps/the_hive/doors.txtpb | |||
@@ -1,6 +1,7 @@ | |||
1 | doors { | 1 | doors { |
2 | name: "Room 8 Door" | 2 | name: "Room 8 Door" |
3 | type: LOCATION_ONLY | 3 | type: STANDARD |
4 | receivers: "Components/Doors/entry_10" | ||
4 | panels { room: "Main Area" name: "STEM" } | 5 | panels { room: "Main Area" name: "STEM" } |
5 | panels { room: "Main Area" name: "PETAL" } | 6 | panels { room: "Main Area" name: "PETAL" } |
6 | panels { room: "Main Area" name: "SOIL" } | 7 | panels { room: "Main Area" name: "SOIL" } |
diff --git a/data/maps/the_hive/rooms/Main Area.txtpb b/data/maps/the_hive/rooms/Main Area.txtpb index de7bdec..aaf8e2a 100644 --- a/data/maps/the_hive/rooms/Main Area.txtpb +++ b/data/maps/the_hive/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Hive" | ||
3 | panels { | 2 | panels { |
4 | name: "ASP" | 3 | name: "ASP" |
5 | path: "Panels/Room 1/panel_1" | 4 | path: "Panels/Room 1/panel_1" |
@@ -269,24 +268,33 @@ panels { | |||
269 | keyholders { | 268 | keyholders { |
270 | name: "B" | 269 | name: "B" |
271 | path: "Components/KeyHolders/keyHolderB" | 270 | path: "Components/KeyHolders/keyHolderB" |
271 | key: "b" | ||
272 | } | 272 | } |
273 | ports { | 273 | ports { |
274 | name: "DAED1" | 274 | name: "DAED1" |
275 | display_name: "Blue Area Worldport" | ||
275 | path: "Components/Warps/worldport" | 276 | path: "Components/Warps/worldport" |
276 | orientation: "west" | 277 | destination { x: -1.5 y: 0 z: 24 } |
278 | rotation: 270 | ||
277 | } | 279 | } |
278 | ports { | 280 | ports { |
279 | name: "DAED2" | 281 | name: "DAED2" |
282 | display_name: "Pink Area South Worldport" | ||
280 | path: "Components/Warps/worldport2" | 283 | path: "Components/Warps/worldport2" |
281 | orientation: "west" | 284 | destination { x: -26.5 y: 0 z: -22 } |
285 | rotation: 270 | ||
282 | } | 286 | } |
283 | ports { | 287 | ports { |
284 | name: "DAED3" | 288 | name: "DAED3" |
289 | display_name: "Lime Area Worldport" | ||
285 | path: "Components/Warps/worldport3" | 290 | path: "Components/Warps/worldport3" |
286 | orientation: "east" | 291 | destination { x: -44.5 y: 0 z: -13 } |
292 | rotation: 90 | ||
287 | } | 293 | } |
288 | ports { | 294 | ports { |
289 | name: "GREAT" | 295 | name: "GREAT" |
296 | display_name: "Pink Area North Worldport" | ||
290 | path: "Components/Warps/worldport4" | 297 | path: "Components/Warps/worldport4" |
291 | orientation: "west" | 298 | destination { x: -29.5 y: 0 z: -62 } |
299 | rotation: 270 | ||
292 | } | 300 | } |
diff --git a/data/maps/the_hive/rooms/Mastery Room.txtpb b/data/maps/the_hive/rooms/Mastery Room.txtpb index 1884cfd..5e3326c 100644 --- a/data/maps/the_hive/rooms/Mastery Room.txtpb +++ b/data/maps/the_hive/rooms/Mastery Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Mastery Room" | 1 | name: "Mastery Room" |
2 | display_name: "Hive" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/smiley" | 4 | path: "Components/Collectables/smiley" |
diff --git a/data/maps/the_hive/rooms/Room 8.txtpb b/data/maps/the_hive/rooms/Room 8.txtpb index e8cbb60..c96440c 100644 --- a/data/maps/the_hive/rooms/Room 8.txtpb +++ b/data/maps/the_hive/rooms/Room 8.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Room 8" | 1 | name: "Room 8" |
2 | display_name: "Hive" | ||
3 | panels { | 2 | panels { |
4 | name: "BUMBLE" | 3 | name: "BUMBLE" |
5 | path: "Panels/Room 8/panel_1" | 4 | path: "Panels/Room 8/panel_1" |
diff --git a/data/maps/the_impressive/rooms/Green Eye.txtpb b/data/maps/the_impressive/rooms/Green Eye.txtpb index 195099d..aa31b07 100644 --- a/data/maps/the_impressive/rooms/Green Eye.txtpb +++ b/data/maps/the_impressive/rooms/Green Eye.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Green Eye" | 1 | name: "Green Eye" |
2 | display_name: "Impressive" | 2 | panel_display_name: "Outside" |
3 | panels { | 3 | panels { |
4 | name: "RETURN" | 4 | name: "RETURN" |
5 | path: "Panels/entry_5" | 5 | path: "Panels/entry_5" |
@@ -22,6 +22,8 @@ panels { | |||
22 | } | 22 | } |
23 | ports { | 23 | ports { |
24 | name: "PLAZA" | 24 | name: "PLAZA" |
25 | display_name: "Green Hallway" | ||
25 | path: "Components/Warps/worldport3" | 26 | path: "Components/Warps/worldport3" |
26 | orientation: "east" | 27 | destination { x: -33 y: 0 z: 1 } |
28 | rotation: 90 | ||
27 | } | 29 | } |
diff --git a/data/maps/the_impressive/rooms/Lobby.txtpb b/data/maps/the_impressive/rooms/Lobby.txtpb index 5492d67..577a051 100644 --- a/data/maps/the_impressive/rooms/Lobby.txtpb +++ b/data/maps/the_impressive/rooms/Lobby.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Lobby" | 1 | name: "Lobby" |
2 | display_name: "Impressive" | 2 | panel_display_name: "Outside" |
3 | panels { | 3 | panels { |
4 | name: "RIGHT" | 4 | name: "RIGHT" |
5 | path: "Panels/entry_1" | 5 | path: "Panels/entry_1" |
@@ -9,6 +9,8 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "GREAT" | 11 | name: "GREAT" |
12 | display_name: "Main Entrance" | ||
12 | path: "Components/Warps/worldport" | 13 | path: "Components/Warps/worldport" |
13 | orientation: "south" | 14 | destination { x: 0 y: 0 z: 11.5 } |
15 | rotation: 0 | ||
14 | } | 16 | } |
diff --git a/data/maps/the_impressive/rooms/M Room.txtpb b/data/maps/the_impressive/rooms/M Room.txtpb index 1796bb3..2cc71be 100644 --- a/data/maps/the_impressive/rooms/M Room.txtpb +++ b/data/maps/the_impressive/rooms/M Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "M Room" | 1 | name: "M Room" |
2 | display_name: "Impressive" | 2 | panel_display_name: "Inside" |
3 | letters { | 3 | letters { |
4 | key: "m" | 4 | key: "m" |
5 | path: "Components/Collectables/collectable" | 5 | path: "Components/Collectables/collectable" |
diff --git a/data/maps/the_impressive/rooms/M2 Room.txtpb b/data/maps/the_impressive/rooms/M2 Room.txtpb index d229cbc..3684441 100644 --- a/data/maps/the_impressive/rooms/M2 Room.txtpb +++ b/data/maps/the_impressive/rooms/M2 Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "M2 Room" | 1 | name: "M2 Room" |
2 | display_name: "Impressive" | 2 | panel_display_name: "Inside" |
3 | letters { | 3 | letters { |
4 | key: "m" | 4 | key: "m" |
5 | level2: true | 5 | level2: true |
diff --git a/data/maps/the_impressive/rooms/Side Area.txtpb b/data/maps/the_impressive/rooms/Side Area.txtpb index 7c3dbd8..d1b28a3 100644 --- a/data/maps/the_impressive/rooms/Side Area.txtpb +++ b/data/maps/the_impressive/rooms/Side Area.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "Side Area" | 1 | name: "Side Area" |
2 | display_name: "Impressive" | 2 | panel_display_name: "Outside" |
3 | panels { | 3 | panels { |
4 | name: "COLOR" | 4 | name: "COLOR" |
5 | path: "Panels/entry_4" | 5 | path: "Panels/entry_4" |
@@ -9,6 +9,8 @@ panels { | |||
9 | } | 9 | } |
10 | ports { | 10 | ports { |
11 | name: "FOURROOMS" | 11 | name: "FOURROOMS" |
12 | display_name: "Four Rooms Entrance" | ||
12 | path: "Components/Warps/worldport2" | 13 | path: "Components/Warps/worldport2" |
13 | orientation: "south" | 14 | destination { x: -27 y: 0 z: 25.5 } |
15 | rotation: 0 | ||
14 | } | 16 | } |
diff --git a/data/maps/the_impressive/rooms/W Room.txtpb b/data/maps/the_impressive/rooms/W Room.txtpb index c0616f9..21f1eab 100644 --- a/data/maps/the_impressive/rooms/W Room.txtpb +++ b/data/maps/the_impressive/rooms/W Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "W Room" | 1 | name: "W Room" |
2 | display_name: "Impressive" | 2 | panel_display_name: "Inside" |
3 | letters { | 3 | letters { |
4 | key: "w" | 4 | key: "w" |
5 | path: "Components/Collectables/collectable2" | 5 | path: "Components/Collectables/collectable2" |
diff --git a/data/maps/the_impressive/rooms/WM Room.txtpb b/data/maps/the_impressive/rooms/WM Room.txtpb index a66f614..dce77ed 100644 --- a/data/maps/the_impressive/rooms/WM Room.txtpb +++ b/data/maps/the_impressive/rooms/WM Room.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | name: "WM Room" | 1 | name: "WM Room" |
2 | display_name: "Impressive" | 2 | panel_display_name: "Inside" |
3 | panels { | 3 | panels { |
4 | name: "LEFT" | 4 | name: "LEFT" |
5 | path: "Panels/entry_2" | 5 | path: "Panels/entry_2" |
@@ -13,4 +13,5 @@ panels { | |||
13 | clue: "right" | 13 | clue: "right" |
14 | answer: "right" | 14 | answer: "right" |
15 | proxies { answer: "left" path: "Panels/proxied_1" } | 15 | proxies { answer: "left" path: "Panels/proxied_1" } |
16 | proxies { answer: "right" path: "Panels/proxied_2" } | ||
16 | } | 17 | } |
diff --git a/data/maps/the_invisible/rooms/Entrance.txtpb b/data/maps/the_invisible/rooms/Entrance.txtpb index 7fafcb5..c74b968 100644 --- a/data/maps/the_invisible/rooms/Entrance.txtpb +++ b/data/maps/the_invisible/rooms/Entrance.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Entrance" | 1 | name: "Entrance" |
2 | display_name: "Invisible" | ||
3 | panels { | 2 | panels { |
4 | name: "VISIBLE" | 3 | name: "VISIBLE" |
5 | path: "Panels/Room_1/panel_1" | 4 | path: "Panels/Room_1/panel_1" |
@@ -9,6 +8,8 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "ENTRY" | 10 | name: "ENTRY" |
11 | display_name: "Entrance" | ||
12 | path: "Components/Warps/worldport2" | 12 | path: "Components/Warps/worldport2" |
13 | orientation: "north" | 13 | destination { x: 0 y: 0 z: -57 } |
14 | rotation: 180 | ||
14 | } | 15 | } |
diff --git a/data/maps/the_invisible/rooms/Maze.txtpb b/data/maps/the_invisible/rooms/Maze.txtpb index 4461f08..46f3fbc 100644 --- a/data/maps/the_invisible/rooms/Maze.txtpb +++ b/data/maps/the_invisible/rooms/Maze.txtpb | |||
@@ -1,11 +1,13 @@ | |||
1 | name: "Maze" | 1 | name: "Maze" |
2 | display_name: "Invisible" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/smiley" | 4 | path: "Components/Collectables/smiley" |
6 | } | 5 | } |
7 | ports { | 6 | ports { |
8 | name: "ENTRY" | 7 | name: "ENTRY" |
8 | display_name: "Exit" | ||
9 | path: "Components/Warps/worldport" | 9 | path: "Components/Warps/worldport" |
10 | orientation: "south" | 10 | # Should this be shuffleable? It skips the maze lol. |
11 | destination { x: 0 y: 0 z: 9.5 } | ||
12 | rotation: 0 | ||
11 | } | 13 | } |
diff --git a/data/maps/the_jubilant/rooms/J Room.txtpb b/data/maps/the_jubilant/rooms/J Room.txtpb index 35abc54..19425f1 100644 --- a/data/maps/the_jubilant/rooms/J Room.txtpb +++ b/data/maps/the_jubilant/rooms/J Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "J Room" | 1 | name: "J Room" |
2 | display_name: "Jubilant" | ||
3 | letters { | 2 | letters { |
4 | key: "j" | 3 | key: "j" |
5 | path: "Components/Collectables/q" # yeah lol | 4 | path: "Components/Collectables/q" # yeah lol |
diff --git a/data/maps/the_jubilant/rooms/Main Area.txtpb b/data/maps/the_jubilant/rooms/Main Area.txtpb index 3d7d31f..b38fafd 100644 --- a/data/maps/the_jubilant/rooms/Main Area.txtpb +++ b/data/maps/the_jubilant/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Jubilant" | ||
3 | panels { | 2 | panels { |
4 | name: "GEMSTONE" | 3 | name: "GEMSTONE" |
5 | path: "Panels/Main/panel_1" | 4 | path: "Panels/Main/panel_1" |
@@ -98,6 +97,8 @@ panels { | |||
98 | } | 97 | } |
99 | ports { | 98 | ports { |
100 | name: "GREAT" | 99 | name: "GREAT" |
100 | display_name: "Entrance" | ||
101 | path: "Components/Warps/worldport" | 101 | path: "Components/Warps/worldport" |
102 | orientation: "west" | 102 | destination { x: -3 y: 0 z: 9 } |
103 | rotation: 270 | ||
103 | } | 104 | } |
diff --git a/data/maps/the_jubilant/rooms/Side Area.txtpb b/data/maps/the_jubilant/rooms/Side Area.txtpb index 0e904aa..807f044 100644 --- a/data/maps/the_jubilant/rooms/Side Area.txtpb +++ b/data/maps/the_jubilant/rooms/Side Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Side Area" | 1 | name: "Side Area" |
2 | display_name: "Jubilant" | ||
3 | panels { | 2 | panels { |
4 | name: "CALLBACK" | 3 | name: "CALLBACK" |
5 | path: "Panels/Back Helpers/back_1" | 4 | path: "Panels/Back Helpers/back_1" |
@@ -39,4 +38,5 @@ panels { | |||
39 | keyholders { | 38 | keyholders { |
40 | name: "J" | 39 | name: "J" |
41 | path: "Components/KeyHolders/keyHolderJ" | 40 | path: "Components/KeyHolders/keyHolderJ" |
41 | key: "j" | ||
42 | } | 42 | } |
diff --git a/data/maps/the_keen/rooms/K Room.txtpb b/data/maps/the_keen/rooms/K Room.txtpb index 3485856..d8108f5 100644 --- a/data/maps/the_keen/rooms/K Room.txtpb +++ b/data/maps/the_keen/rooms/K Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "K Room" | 1 | name: "K Room" |
2 | display_name: "Keen" | ||
3 | letters { | 2 | letters { |
4 | key: "k" | 3 | key: "k" |
5 | path: "Components/Collectables/collectable" | 4 | path: "Components/Collectables/collectable" |
diff --git a/data/maps/the_keen/rooms/Main Area.txtpb b/data/maps/the_keen/rooms/Main Area.txtpb index 616e7e7..32d399a 100644 --- a/data/maps/the_keen/rooms/Main Area.txtpb +++ b/data/maps/the_keen/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Keen" | ||
3 | panels { | 2 | panels { |
4 | name: "TIN (1)" | 3 | name: "TIN (1)" |
5 | path: "Panels/entry_3" | 4 | path: "Panels/entry_3" |
@@ -70,6 +69,8 @@ panels { | |||
70 | } | 69 | } |
71 | ports { | 70 | ports { |
72 | name: "GREAT" | 71 | name: "GREAT" |
72 | display_name: "Entrance" | ||
73 | path: "Components/Warps/worldport" | 73 | path: "Components/Warps/worldport" |
74 | orientation: "south" | 74 | destination { x: 0 y: 0 z: 7.5 } |
75 | rotation: 0 | ||
75 | } | 76 | } |
diff --git a/data/maps/the_liberated/doors.txtpb b/data/maps/the_liberated/doors.txtpb index becddf9..a7d3c24 100644 --- a/data/maps/the_liberated/doors.txtpb +++ b/data/maps/the_liberated/doors.txtpb | |||
@@ -11,4 +11,5 @@ doors { | |||
11 | panels { room: "Puzzle Room" name: "WOLF" } | 11 | panels { room: "Puzzle Room" name: "WOLF" } |
12 | panels { room: "Puzzle Room" name: "FOOT" } | 12 | panels { room: "Puzzle Room" name: "FOOT" } |
13 | location_room: "Puzzle Room" | 13 | location_room: "Puzzle Room" |
14 | location_name: "Puzzles" | ||
14 | } | 15 | } |
diff --git a/data/maps/the_liberated/rooms/Painting Room.txtpb b/data/maps/the_liberated/rooms/Painting Room.txtpb index 025281a..f22929c 100644 --- a/data/maps/the_liberated/rooms/Painting Room.txtpb +++ b/data/maps/the_liberated/rooms/Painting Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Painting Room" | 1 | name: "Painting Room" |
2 | display_name: "Liberated" | ||
3 | paintings { | 2 | paintings { |
4 | name: "PYRAMID" | 3 | name: "PYRAMID" |
5 | path: "Components/triangle" | 4 | path: "Components/triangle" |
diff --git a/data/maps/the_liberated/rooms/Puzzle Room.txtpb b/data/maps/the_liberated/rooms/Puzzle Room.txtpb index dcb29c4..2103bfa 100644 --- a/data/maps/the_liberated/rooms/Puzzle Room.txtpb +++ b/data/maps/the_liberated/rooms/Puzzle Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Puzzle Room" | 1 | name: "Puzzle Room" |
2 | display_name: "Liberated" | ||
3 | panels { | 2 | panels { |
4 | name: "CORPSE" | 3 | name: "CORPSE" |
5 | path: "Panels/entry_1" | 4 | path: "Panels/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "ENTRY" | 59 | name: "ENTRY" |
60 | display_name: "Entrance" | ||
61 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | orientation: "south" | 62 | destination { x: 0 y: 0 z: 7.5 } |
63 | rotation: 0 | ||
63 | } | 64 | } |
diff --git a/data/maps/the_linear/doors.txtpb b/data/maps/the_linear/doors.txtpb index 63d8ae8..9a57158 100644 --- a/data/maps/the_linear/doors.txtpb +++ b/data/maps/the_linear/doors.txtpb | |||
@@ -10,4 +10,5 @@ doors { | |||
10 | panels { room: "Room" name: "INTO" } | 10 | panels { room: "Room" name: "INTO" } |
11 | panels { room: "Room" name: "NOR" } | 11 | panels { room: "Room" name: "NOR" } |
12 | location_room: "Room" | 12 | location_room: "Room" |
13 | location_name: "Gravestone" | ||
13 | } | 14 | } |
diff --git a/data/maps/the_linear/rooms/Room.txtpb b/data/maps/the_linear/rooms/Room.txtpb index abb89c8..ac03fd9 100644 --- a/data/maps/the_linear/rooms/Room.txtpb +++ b/data/maps/the_linear/rooms/Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Room" | 1 | name: "Room" |
2 | display_name: "Room" | ||
3 | panels { | 2 | panels { |
4 | name: "HORN" | 3 | name: "HORN" |
5 | path: "Panels/entry_1" | 4 | path: "Panels/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "GREAT" | 59 | name: "GREAT" |
60 | display_name: "Entrance" | ||
61 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | orientation: "south" | 62 | destination { x: 0 y: 0 z: 7.5 } |
63 | rotation: 0 | ||
63 | } | 64 | } |
diff --git a/data/maps/the_lionized/rooms/E2 Room.txtpb b/data/maps/the_lionized/rooms/E2 Room.txtpb index b07d820..e8f81c1 100644 --- a/data/maps/the_lionized/rooms/E2 Room.txtpb +++ b/data/maps/the_lionized/rooms/E2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "E2 Room" | 1 | name: "E2 Room" |
2 | display_name: "Lionized" | ||
3 | letters { | 2 | letters { |
4 | key: "e" | 3 | key: "e" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_lionized/rooms/Puzzle Room.txtpb b/data/maps/the_lionized/rooms/Puzzle Room.txtpb index 5754c71..3a5e267 100644 --- a/data/maps/the_lionized/rooms/Puzzle Room.txtpb +++ b/data/maps/the_lionized/rooms/Puzzle Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Puzzle Room" | 1 | name: "Puzzle Room" |
2 | display_name: "Lionized" | ||
3 | panels { | 2 | panels { |
4 | name: "CHILD" | 3 | name: "CHILD" |
5 | path: "Panels/entry_1" | 4 | path: "Panels/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "ENTRY" | 59 | name: "ENTRY" |
60 | display_name: "Entrance" | ||
61 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | orientation: "south" | 62 | destination { x: 0 y: 0 z: 6.5 } |
63 | rotation: 0 | ||
63 | } | 64 | } |
diff --git a/data/maps/the_literate/doors.txtpb b/data/maps/the_literate/doors.txtpb index 480f54d..d17d02b 100644 --- a/data/maps/the_literate/doors.txtpb +++ b/data/maps/the_literate/doors.txtpb | |||
@@ -11,4 +11,5 @@ doors { | |||
11 | panels { room: "Puzzle Room" name: "STICK" } | 11 | panels { room: "Puzzle Room" name: "STICK" } |
12 | panels { room: "Puzzle Room" name: "BREAD" } | 12 | panels { room: "Puzzle Room" name: "BREAD" } |
13 | location_room: "Puzzle Room" | 13 | location_room: "Puzzle Room" |
14 | location_name: "Puzzles" | ||
14 | } | 15 | } |
diff --git a/data/maps/the_literate/rooms/Painting Room.txtpb b/data/maps/the_literate/rooms/Painting Room.txtpb index 254e174..f22929c 100644 --- a/data/maps/the_literate/rooms/Painting Room.txtpb +++ b/data/maps/the_literate/rooms/Painting Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Painting Room" | 1 | name: "Painting Room" |
2 | display_name: "Literate" | ||
3 | paintings { | 2 | paintings { |
4 | name: "PYRAMID" | 3 | name: "PYRAMID" |
5 | path: "Components/triangle" | 4 | path: "Components/triangle" |
diff --git a/data/maps/the_literate/rooms/Puzzle Room.txtpb b/data/maps/the_literate/rooms/Puzzle Room.txtpb index 610a87a..c65d408 100644 --- a/data/maps/the_literate/rooms/Puzzle Room.txtpb +++ b/data/maps/the_literate/rooms/Puzzle Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Puzzle Room" | 1 | name: "Puzzle Room" |
2 | display_name: "Literate" | ||
3 | panels { | 2 | panels { |
4 | name: "WATER" | 3 | name: "WATER" |
5 | path: "Panels/entry_1" | 4 | path: "Panels/entry_1" |
@@ -58,6 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "ENTRY" | 59 | name: "ENTRY" |
60 | display_name: "Entrance" | ||
61 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | orientation: "south" | 62 | destination { x: 0 y: 0 z: 7.5 } |
63 | rotation: 0 | ||
63 | } | 64 | } |
diff --git a/data/maps/the_lively/rooms/L2 Room.txtpb b/data/maps/the_lively/rooms/L2 Room.txtpb index 094ab10..cd75bbd 100644 --- a/data/maps/the_lively/rooms/L2 Room.txtpb +++ b/data/maps/the_lively/rooms/L2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "L2 Room" | 1 | name: "L2 Room" |
2 | display_name: "Lively" | ||
3 | letters { | 2 | letters { |
4 | key: "l" | 3 | key: "l" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_lively/rooms/Puzzle Room.txtpb b/data/maps/the_lively/rooms/Puzzle Room.txtpb index f202453..4918476 100644 --- a/data/maps/the_lively/rooms/Puzzle Room.txtpb +++ b/data/maps/the_lively/rooms/Puzzle Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Puzzle Room" | 1 | name: "Puzzle Room" |
2 | display_name: "Lively" | ||
3 | panels { | 2 | panels { |
4 | name: "LIONESS" | 3 | name: "LIONESS" |
5 | path: "Panels/entry_1" | 4 | path: "Panels/entry_1" |
@@ -58,5 +57,8 @@ panels { | |||
58 | } | 57 | } |
59 | ports { | 58 | ports { |
60 | name: "BETWEEN" | 59 | name: "BETWEEN" |
60 | display_name: "Entrance" | ||
61 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | destination { x: 0 y: 0 z: 6.5 } | ||
63 | rotation: 0 | ||
62 | } | 64 | } |
diff --git a/data/maps/the_nuanced/connections.txtpb b/data/maps/the_nuanced/connections.txtpb index 6c4b0f6..a530472 100644 --- a/data/maps/the_nuanced/connections.txtpb +++ b/data/maps/the_nuanced/connections.txtpb | |||
@@ -1,7 +1,7 @@ | |||
1 | connections { | 1 | connections { |
2 | from_room: "Main Room" | 2 | from_room: "Main Room" |
3 | to_room: "Back Room" | 3 | to_room: "Back Room" |
4 | door { name: "Main Room Puzzles" } | 4 | door { name: "Main Room Door" } |
5 | } | 5 | } |
6 | connections { | 6 | connections { |
7 | from_room: "Back Room" | 7 | from_room: "Back Room" |
diff --git a/data/maps/the_nuanced/doors.txtpb b/data/maps/the_nuanced/doors.txtpb index 0c66799..cd29766 100644 --- a/data/maps/the_nuanced/doors.txtpb +++ b/data/maps/the_nuanced/doors.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | doors { | 1 | doors { |
2 | name: "Left Room Puzzles" | 2 | name: "Blue Side Puzzles" |
3 | type: LOCATION_ONLY | 3 | type: LOCATION_ONLY |
4 | panels { room: "Main Room" name: "HOARSE" } | 4 | panels { room: "Main Room" name: "HOARSE" } |
5 | panels { room: "Main Room" name: "NAY" } | 5 | panels { room: "Main Room" name: "NAY" } |
@@ -11,7 +11,7 @@ doors { | |||
11 | location_room: "Main Room" | 11 | location_room: "Main Room" |
12 | } | 12 | } |
13 | doors { | 13 | doors { |
14 | name: "Right Room Puzzles" | 14 | name: "Green Side Puzzles" |
15 | type: LOCATION_ONLY | 15 | type: LOCATION_ONLY |
16 | panels { room: "Main Room" name: "HOSE" } | 16 | panels { room: "Main Room" name: "HOSE" } |
17 | panels { room: "Main Room" name: "NIGH" } | 17 | panels { room: "Main Room" name: "NIGH" } |
@@ -23,7 +23,7 @@ doors { | |||
23 | location_room: "Main Room" | 23 | location_room: "Main Room" |
24 | } | 24 | } |
25 | doors { | 25 | doors { |
26 | name: "Main Room Puzzles" | 26 | name: "Main Room Door" |
27 | type: ITEM_ONLY | 27 | type: ITEM_ONLY |
28 | receivers: "Components/Doors/entry_1" | 28 | receivers: "Components/Doors/entry_1" |
29 | panels { room: "Main Room" name: "HOARSE" } | 29 | panels { room: "Main Room" name: "HOARSE" } |
diff --git a/data/maps/the_nuanced/rooms/Back Room.txtpb b/data/maps/the_nuanced/rooms/Back Room.txtpb index 37a1c7a..b61e18b 100644 --- a/data/maps/the_nuanced/rooms/Back Room.txtpb +++ b/data/maps/the_nuanced/rooms/Back Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Back Room" | 1 | name: "Back Room" |
2 | display_name: "Nuanced" | ||
3 | panels { | 2 | panels { |
4 | name: "COURSE" | 3 | name: "COURSE" |
5 | path: "Panels/Rhymes/panel_1" | 4 | path: "Panels/Rhymes/panel_1" |
diff --git a/data/maps/the_nuanced/rooms/Main Room.txtpb b/data/maps/the_nuanced/rooms/Main Room.txtpb index 8523b38..ce4310e 100644 --- a/data/maps/the_nuanced/rooms/Main Room.txtpb +++ b/data/maps/the_nuanced/rooms/Main Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Room" | 1 | name: "Main Room" |
2 | display_name: "Nuanced" | ||
3 | panels { | 2 | panels { |
4 | name: "HOARSE" | 3 | name: "HOARSE" |
5 | path: "Panels/Eyes/panel_1" | 4 | path: "Panels/Eyes/panel_1" |
@@ -107,10 +106,13 @@ panels { | |||
107 | } | 106 | } |
108 | ports { | 107 | ports { |
109 | name: "UNYIELDING" | 108 | name: "UNYIELDING" |
109 | display_name: "Entrance" | ||
110 | path: "Components/Warps/worldport" | 110 | path: "Components/Warps/worldport" |
111 | orientation: "west" | 111 | destination { x: -3.5 y: 0 z: 21 } |
112 | rotation: 270 | ||
112 | } | 113 | } |
113 | keyholders { | 114 | keyholders { |
114 | name: "S" | 115 | name: "S" |
115 | path: "Components/KeyHolders/keyHolderS" | 116 | path: "Components/KeyHolders/keyHolderS" |
117 | key: "s" | ||
116 | } | 118 | } |
diff --git a/data/maps/the_nuanced/rooms/N2 Room.txtpb b/data/maps/the_nuanced/rooms/N2 Room.txtpb index 492d4a3..eb9f67c 100644 --- a/data/maps/the_nuanced/rooms/N2 Room.txtpb +++ b/data/maps/the_nuanced/rooms/N2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "N2 Room" | 1 | name: "N2 Room" |
2 | display_name: "Nuanced" | ||
3 | letters { | 2 | letters { |
4 | key: "n" | 3 | key: "n" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_orb/connections.txtpb b/data/maps/the_orb/connections.txtpb index 62a7643..b902711 100644 --- a/data/maps/the_orb/connections.txtpb +++ b/data/maps/the_orb/connections.txtpb | |||
@@ -10,10 +10,20 @@ connections { | |||
10 | } | 10 | } |
11 | connections { | 11 | connections { |
12 | from_room: "Main Area" | 12 | from_room: "Main Area" |
13 | to_room: "B Room" | 13 | to_room: "Middle Room" |
14 | door { name: "B Puzzles" } | 14 | door { name: "B Puzzles" } |
15 | } | 15 | } |
16 | connections { | 16 | connections { |
17 | from_room: "Middle Room" | ||
18 | to_room: "B Room" | ||
19 | oneway: true | ||
20 | } | ||
21 | connections { | ||
22 | from_room: "Middle Room" | ||
23 | to_room: "Main Area" | ||
24 | oneway: true | ||
25 | } | ||
26 | connections { | ||
17 | from_room: "B Room" | 27 | from_room: "B Room" |
18 | to_room: "Main Area" | 28 | to_room: "Main Area" |
19 | oneway: true | 29 | oneway: true |
diff --git a/data/maps/the_orb/rooms/B Room.txtpb b/data/maps/the_orb/rooms/B Room.txtpb index 833c659..633232f 100644 --- a/data/maps/the_orb/rooms/B Room.txtpb +++ b/data/maps/the_orb/rooms/B Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "B Room" | 1 | name: "B Room" |
2 | display_name: "Orb" | ||
3 | letters { | 2 | letters { |
4 | key: "b" | 3 | key: "b" |
5 | path: "Components/Collectables/b" | 4 | path: "Components/Collectables/b" |
@@ -10,19 +9,10 @@ paintings { | |||
10 | # TODO: This is too high up to enter. It's also a hint painting. | 9 | # TODO: This is too high up to enter. It's also a hint painting. |
11 | exit_only: true | 10 | exit_only: true |
12 | } | 11 | } |
13 | # TODO: Should these two be independent for shuffling purposes, or always tied | ||
14 | # to the Main Area's port? | ||
15 | ports { | ||
16 | name: "MID" | ||
17 | path: "Components/Warps/worldport4" | ||
18 | orientation: "south" | ||
19 | # This port is in the room immediately after solving the B puzzles, which | ||
20 | # means it seems like it would be inaccessible if you enter the map from the | ||
21 | # painting or from the final port, but entering the O or R areas brings you | ||
22 | # back to the beginning. | ||
23 | } | ||
24 | ports { | 12 | ports { |
25 | name: "FINAL" | 13 | name: "FINAL" |
14 | display_name: "Final Worldport" | ||
26 | path: "Components/Warps/worldport5" | 15 | path: "Components/Warps/worldport5" |
27 | orientation: "south" | 16 | destination { x: -69 y: 0 z: 87 } |
17 | rotation: 90 | ||
28 | } | 18 | } |
diff --git a/data/maps/the_orb/rooms/Main Area.txtpb b/data/maps/the_orb/rooms/Main Area.txtpb index 8d7b7b1..976c489 100644 --- a/data/maps/the_orb/rooms/Main Area.txtpb +++ b/data/maps/the_orb/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Orb" | ||
3 | panels { | 2 | panels { |
4 | name: "STRIKE" | 3 | name: "STRIKE" |
5 | path: "Panels/O/entry_1" | 4 | path: "Panels/O/entry_1" |
@@ -86,6 +85,8 @@ panels { | |||
86 | } | 85 | } |
87 | ports { | 86 | ports { |
88 | name: "GREAT" | 87 | name: "GREAT" |
88 | display_name: "Main Entrance" | ||
89 | path: "Components/Warps/worldport" | 89 | path: "Components/Warps/worldport" |
90 | orientation: "south" | 90 | destination { x: 38 y: 0 z: 39 } |
91 | rotation: 90 | ||
91 | } | 92 | } |
diff --git a/data/maps/the_orb/rooms/Middle Room.txtpb b/data/maps/the_orb/rooms/Middle Room.txtpb new file mode 100644 index 0000000..ed1a00c --- /dev/null +++ b/data/maps/the_orb/rooms/Middle Room.txtpb | |||
@@ -0,0 +1,12 @@ | |||
1 | name: "Middle Room" | ||
2 | # This is the room after solving the B puzzles but before getting to B1 itself. | ||
3 | # It has to be a separate region because if you are shuffling worldports and you | ||
4 | # warp to the B1 room port, you can't access this port if you're not able to | ||
5 | # solve the B puzzles. | ||
6 | ports { | ||
7 | name: "MID" | ||
8 | display_name: "Middle Worldport" | ||
9 | path: "Components/Warps/worldport4" | ||
10 | destination { x: -69 y: 0 z: 43 } | ||
11 | rotation: 90 | ||
12 | } | ||
diff --git a/data/maps/the_orb/rooms/O Room.txtpb b/data/maps/the_orb/rooms/O Room.txtpb index f997780..cc254a4 100644 --- a/data/maps/the_orb/rooms/O Room.txtpb +++ b/data/maps/the_orb/rooms/O Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "O Room" | 1 | name: "O Room" |
2 | display_name: "Orb" | ||
3 | letters { | 2 | letters { |
4 | key: "o" | 3 | key: "o" |
5 | path: "Components/Collectables/o" | 4 | path: "Components/Collectables/o" |
diff --git a/data/maps/the_orb/rooms/R Room.txtpb b/data/maps/the_orb/rooms/R Room.txtpb index c53b7eb..a01726a 100644 --- a/data/maps/the_orb/rooms/R Room.txtpb +++ b/data/maps/the_orb/rooms/R Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "R Room" | 1 | name: "R Room" |
2 | display_name: "Orb" | ||
3 | letters { | 2 | letters { |
4 | key: "r" | 3 | key: "r" |
5 | path: "Components/Collectables/r" | 4 | path: "Components/Collectables/r" |
diff --git a/data/maps/the_owl/connections.txtpb b/data/maps/the_owl/connections.txtpb index 87c98b3..cb4bee3 100644 --- a/data/maps/the_owl/connections.txtpb +++ b/data/maps/the_owl/connections.txtpb | |||
@@ -10,12 +10,27 @@ connections { | |||
10 | } | 10 | } |
11 | connections { | 11 | connections { |
12 | from_room: "R2C2 Bottom" | 12 | from_room: "R2C2 Bottom" |
13 | to_room: "R2C2.5 Bottom" | 13 | to_room: "R2C2 Top" |
14 | door { name: "Sky Owl" } | ||
15 | } | ||
16 | connections { | ||
17 | from_room: "R2C2 Bottom" | ||
18 | to_room: "Connected Area" | ||
14 | door { name: "Gray Owl" } | 19 | door { name: "Gray Owl" } |
15 | } | 20 | } |
16 | connections { | 21 | connections { |
17 | from_room: "R2C2 Bottom" | 22 | from_room: "R2C2 Bottom" |
18 | to_room: "R2C2.5 Bottom" | 23 | to_room: "Connected Area" |
24 | door { name: "Sky Owl" } | ||
25 | } | ||
26 | connections { | ||
27 | from_room: "R2C3 Bottom" | ||
28 | to_room: "Connected Area" | ||
29 | oneway: true | ||
30 | } | ||
31 | connections { | ||
32 | from_room: "R2C2 Bottom" | ||
33 | to_room: "Connected Area" | ||
19 | door { name: "First Room Shortcut" } | 34 | door { name: "First Room Shortcut" } |
20 | } | 35 | } |
21 | connections { | 36 | connections { |
@@ -30,18 +45,18 @@ connections { | |||
30 | } | 45 | } |
31 | connections { | 46 | connections { |
32 | from_room: "R2C2 Top" | 47 | from_room: "R2C2 Top" |
33 | to_room: "R2C2.5 Bottom" | 48 | to_room: "R2C3 Bottom" |
34 | door { name: "Gray Bottom Door" } | 49 | door { name: "Gray Bottom Door" } |
35 | } | 50 | } |
36 | connections { | 51 | connections { |
37 | from_room: "R2C2 Top" | 52 | from_room: "Connected Area" |
38 | to_room: "R2C2.5 Bottom" | 53 | to_room: "R2C3 Bottom" |
39 | door { name: "Gray Owl" } | 54 | door { name: "Gray Owl" } |
40 | } | 55 | } |
41 | connections { | 56 | connections { |
42 | from_room: "Connected Area" | 57 | from_room: "Connected Area" |
43 | to_room: "R2C2.5 Bottom" | 58 | to_room: "R2C3 Bottom" |
44 | door { name: "Gray Owl" } | 59 | door { name: "Sky Owl" } |
45 | } | 60 | } |
46 | connections { | 61 | connections { |
47 | from_room: "Connected Area" | 62 | from_room: "Connected Area" |
@@ -70,6 +85,11 @@ connections { | |||
70 | } | 85 | } |
71 | connections { | 86 | connections { |
72 | from_room: "Connected Area" | 87 | from_room: "Connected Area" |
88 | to_room: "R1C4 Left" | ||
89 | door { name: "Sky Owl" } | ||
90 | } | ||
91 | connections { | ||
92 | from_room: "Connected Area" | ||
73 | to_room: "R2C1 Left" | 93 | to_room: "R2C1 Left" |
74 | door { name: "Sky Top Doors" } | 94 | door { name: "Sky Top Doors" } |
75 | } | 95 | } |
@@ -84,6 +104,11 @@ connections { | |||
84 | door { name: "Gray Owl" } | 104 | door { name: "Gray Owl" } |
85 | } | 105 | } |
86 | connections { | 106 | connections { |
107 | from_room: "Connected Area" | ||
108 | to_room: "R2C1 Left" | ||
109 | door { name: "Sky Owl" } | ||
110 | } | ||
111 | connections { | ||
87 | from { | 112 | from { |
88 | painting { | 113 | painting { |
89 | room: "Connected Area" | 114 | room: "Connected Area" |
diff --git a/data/maps/the_owl/doors.txtpb b/data/maps/the_owl/doors.txtpb index 2c7f449..9254c2a 100644 --- a/data/maps/the_owl/doors.txtpb +++ b/data/maps/the_owl/doors.txtpb | |||
@@ -25,8 +25,8 @@ doors { | |||
25 | name: "First Room Shortcut" | 25 | name: "First Room Shortcut" |
26 | type: STANDARD | 26 | type: STANDARD |
27 | receivers: "Components/Doors/entry_6" | 27 | receivers: "Components/Doors/entry_6" |
28 | panels { room: "R2C2.5 Bottom" name: "FIZZLE" } | 28 | panels { room: "Connected Area" name: "FIZZLE" } |
29 | location_room: "R2C2.5 Bottom" | 29 | location_room: "Connected Area" |
30 | } | 30 | } |
31 | doors { | 31 | doors { |
32 | name: "First Door" | 32 | name: "First Door" |
@@ -171,8 +171,8 @@ doors { | |||
171 | receivers: "Components/Owl/Room 10/WG" | 171 | receivers: "Components/Owl/Room 10/WG" |
172 | receivers: "Components/Owl/Room 11/W" | 172 | receivers: "Components/Owl/Room 11/W" |
173 | receivers: "Components/Owl/Room 11/WG" | 173 | receivers: "Components/Owl/Room 11/WG" |
174 | panels { room: "R2C2.5 Bottom" name: "BLACK" } | 174 | panels { room: "R2C3 Bottom" name: "BLACK" } |
175 | location_room: "R2C2.5 Bottom" | 175 | location_room: "R2C3 Bottom" |
176 | } | 176 | } |
177 | doors { | 177 | doors { |
178 | name: "Black Owl" | 178 | name: "Black Owl" |
@@ -233,19 +233,20 @@ doors { | |||
233 | doors { | 233 | doors { |
234 | name: "Gray Panel" | 234 | name: "Gray Panel" |
235 | type: EVENT | 235 | type: EVENT |
236 | # TODO: Is it okay to have an event with an in-game effect? | 236 | #receivers: "Panels/Colors/owl_2/animationListener2" |
237 | receivers: "Panels/Colors/owl_2/animationListener2" | 237 | panels { room: "Connected Area" name: "RANGE" } |
238 | doors { name: "Orange Owl" } | 238 | panels { room: "Connected Area" name: "WHITE" } |
239 | doors { name: "Black Owl" } | 239 | panels { room: "Blue Room" name: "SKY" } |
240 | doors { name: "Blue Owl" } | ||
241 | } | 240 | } |
242 | doors { | 241 | doors { |
243 | name: "Owl Painting" | 242 | name: "Owl Painting" |
244 | type: EVENT | 243 | type: EVENT |
245 | move_paintings { room: "Connected Area" name: "OWL" } | 244 | #move_paintings { room: "Connected Area" name: "OWL" } |
246 | doors { name: "Orange Owl" } | 245 | #receivers: "Components/Paintings/owl/teleportListener" |
247 | doors { name: "Black Owl" } | 246 | panels { room: "R2C1 Left" name: "DUSKY" } |
248 | doors { name: "Blue Owl" } | 247 | panels { room: "R2C2 Top" name: "RAY" } |
249 | doors { name: "White Owl" } | 248 | panels { room: "Connected Area" name: "RANGE" } |
250 | doors { name: "Sky Owl" } | 249 | panels { room: "R2C3 Bottom" name: "BLACK" } |
250 | panels { room: "Connected Area" name: "WHITE" } | ||
251 | panels { room: "Blue Room" name: "SKY" } | ||
251 | } | 252 | } |
diff --git a/data/maps/the_owl/rooms/Blue Room.txtpb b/data/maps/the_owl/rooms/Blue Room.txtpb index 7c2d69a..a7298cd 100644 --- a/data/maps/the_owl/rooms/Blue Room.txtpb +++ b/data/maps/the_owl/rooms/Blue Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Blue Room" | 1 | name: "Blue Room" |
2 | display_name: "Owl" | ||
3 | panels { | 2 | panels { |
4 | name: "SKY" | 3 | name: "SKY" |
5 | path: "Panels/Colors/owl_7" | 4 | path: "Panels/Colors/owl_7" |
diff --git a/data/maps/the_owl/rooms/Connected Area.txtpb b/data/maps/the_owl/rooms/Connected Area.txtpb index 18388be..432d6b2 100644 --- a/data/maps/the_owl/rooms/Connected Area.txtpb +++ b/data/maps/the_owl/rooms/Connected Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Connected Area" | 1 | name: "Connected Area" |
2 | display_name: "Owl" | ||
3 | panels { | 2 | panels { |
4 | name: "MODE" | 3 | name: "MODE" |
5 | path: "Panels/Noncritical/owl_12" | 4 | path: "Panels/Noncritical/owl_12" |
@@ -133,6 +132,13 @@ panels { | |||
133 | answer: "orange" | 132 | answer: "orange" |
134 | symbols: SPARKLES | 133 | symbols: SPARKLES |
135 | } | 134 | } |
135 | panels { | ||
136 | name: "FIZZLE" | ||
137 | path: "Panels/Bottom Mid/owl_10" | ||
138 | clue: "fizzle" | ||
139 | answer: "chisel" | ||
140 | symbols: ZERO | ||
141 | } | ||
136 | paintings { | 142 | paintings { |
137 | name: "OWL" | 143 | name: "OWL" |
138 | path: "Components/Paintings/owl" | 144 | path: "Components/Paintings/owl" |
@@ -143,7 +149,9 @@ paintings { | |||
143 | } | 149 | } |
144 | ports { | 150 | ports { |
145 | name: "FOURROOMS" | 151 | name: "FOURROOMS" |
152 | display_name: "Four Rooms Entrance" | ||
146 | path: "Components/Warps/worldport2" | 153 | path: "Components/Warps/worldport2" |
147 | orientation: "east" | 154 | destination { x: 71.5 y: 0 z: -9 } |
155 | rotation: 90 | ||
148 | # Note that this is behind teal walls. | 156 | # Note that this is behind teal walls. |
149 | } | 157 | } |
diff --git a/data/maps/the_owl/rooms/Magenta Hallway.txtpb b/data/maps/the_owl/rooms/Magenta Hallway.txtpb index 58a4a5d..14d6f0d 100644 --- a/data/maps/the_owl/rooms/Magenta Hallway.txtpb +++ b/data/maps/the_owl/rooms/Magenta Hallway.txtpb | |||
@@ -1,7 +1,8 @@ | |||
1 | name: "Magenta Hallway" | 1 | name: "Magenta Hallway" |
2 | display_name: "Owl" | ||
3 | ports { | 2 | ports { |
4 | name: "STURDY" | 3 | name: "STURDY" |
4 | display_name: "Magenta Hallway" | ||
5 | path: "Components/Warps/worldport3" | 5 | path: "Components/Warps/worldport3" |
6 | orientation: "west" | 6 | destination { x: 17 y: 0 z: -46 } |
7 | rotation: 270 | ||
7 | } | 8 | } |
diff --git a/data/maps/the_owl/rooms/R1C4 Left.txtpb b/data/maps/the_owl/rooms/R1C4 Left.txtpb index 73c1520..3714842 100644 --- a/data/maps/the_owl/rooms/R1C4 Left.txtpb +++ b/data/maps/the_owl/rooms/R1C4 Left.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "R1C4 Left" | 1 | name: "R1C4 Left" |
2 | display_name: "Owl" | ||
3 | panels { | 2 | panels { |
4 | name: "WALK" | 3 | name: "WALK" |
5 | path: "Panels/Noncritical/owl_5" | 4 | path: "Panels/Noncritical/owl_5" |
diff --git a/data/maps/the_owl/rooms/R2C1 Left.txtpb b/data/maps/the_owl/rooms/R2C1 Left.txtpb index 0f9a2b5..72e7331 100644 --- a/data/maps/the_owl/rooms/R2C1 Left.txtpb +++ b/data/maps/the_owl/rooms/R2C1 Left.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "R2C1 Left" | 1 | name: "R2C1 Left" |
2 | display_name: "Owl" | ||
3 | panels { | 2 | panels { |
4 | name: "VERB" | 3 | name: "VERB" |
5 | path: "Panels/Bottom Left/owl_8" | 4 | path: "Panels/Bottom Left/owl_8" |
diff --git a/data/maps/the_owl/rooms/R2C2 Bottom.txtpb b/data/maps/the_owl/rooms/R2C2 Bottom.txtpb index e7eb9e4..2cfd340 100644 --- a/data/maps/the_owl/rooms/R2C2 Bottom.txtpb +++ b/data/maps/the_owl/rooms/R2C2 Bottom.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "R2C2 Bottom" | 1 | name: "R2C2 Bottom" |
2 | display_name: "Owl" | ||
3 | panels { | 2 | panels { |
4 | name: "FOUL" | 3 | name: "FOUL" |
5 | path: "Panels/Bottom Mid/owl_11" | 4 | path: "Panels/Bottom Mid/owl_11" |
@@ -9,7 +8,10 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "GALLERY" | 10 | name: "GALLERY" |
11 | display_name: "Gallery Worldport" | ||
12 | path: "Components/Warps/worldport" | 12 | path: "Components/Warps/worldport" |
13 | orientation: "south" | 13 | destination { x: 0 y: 0 z: 9 } |
14 | # Note that this port is accessible from the other side in the Z1 room. Hmm. | 14 | rotation: 0 |
15 | # TODO: Note that this port is accessible from the other side in the Z1 | ||
16 | # room. Hmm. | ||
15 | } | 17 | } |
diff --git a/data/maps/the_owl/rooms/R2C2 Top.txtpb b/data/maps/the_owl/rooms/R2C2 Top.txtpb index 87b7705..78ce270 100644 --- a/data/maps/the_owl/rooms/R2C2 Top.txtpb +++ b/data/maps/the_owl/rooms/R2C2 Top.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "R2C2 Top" | 1 | name: "R2C2 Top" |
2 | display_name: "Owl" | ||
3 | panels { | 2 | panels { |
4 | name: "CRUSH" | 3 | name: "CRUSH" |
5 | path: "Panels/Bottom Mid/owl_1" | 4 | path: "Panels/Bottom Mid/owl_1" |
diff --git a/data/maps/the_owl/rooms/R2C2.5 Bottom.txtpb b/data/maps/the_owl/rooms/R2C3 Bottom.txtpb index 41b6265..2b49e26 100644 --- a/data/maps/the_owl/rooms/R2C2.5 Bottom.txtpb +++ b/data/maps/the_owl/rooms/R2C3 Bottom.txtpb | |||
@@ -1,12 +1,4 @@ | |||
1 | name: "R2C2.5 Bottom" | 1 | name: "R2C3 Bottom" |
2 | display_name: "Owl" | ||
3 | panels { | ||
4 | name: "FIZZLE" | ||
5 | path: "Panels/Bottom Mid/owl_10" | ||
6 | clue: "fizzle" | ||
7 | answer: "chisel" | ||
8 | symbols: ZERO | ||
9 | } | ||
10 | panels { | 2 | panels { |
11 | name: "FIGMENT" | 3 | name: "FIGMENT" |
12 | path: "Panels/Noncritical/owl_14" | 4 | path: "Panels/Noncritical/owl_14" |
diff --git a/data/maps/the_owl/rooms/Z Room.txtpb b/data/maps/the_owl/rooms/Z Room.txtpb index 035d0b4..ab28655 100644 --- a/data/maps/the_owl/rooms/Z Room.txtpb +++ b/data/maps/the_owl/rooms/Z Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Z Room" | 1 | name: "Z Room" |
2 | display_name: "Owl" | ||
3 | panels { | 2 | panels { |
4 | name: "MAZE" | 3 | name: "MAZE" |
5 | path: "Panels/Noncritical/owl_10" | 4 | path: "Panels/Noncritical/owl_10" |
diff --git a/data/maps/the_parthenon/connections.txtpb b/data/maps/the_parthenon/connections.txtpb index a07d858..331ac66 100644 --- a/data/maps/the_parthenon/connections.txtpb +++ b/data/maps/the_parthenon/connections.txtpb | |||
@@ -7,6 +7,7 @@ connections { | |||
7 | from_room: "Main Area" | 7 | from_room: "Main Area" |
8 | to_room: "Ending" | 8 | to_room: "Ending" |
9 | door { name: "Ending Door" } | 9 | door { name: "Ending Door" } |
10 | cyan_ending: true | ||
10 | } | 11 | } |
11 | connections { | 12 | connections { |
12 | from_room: "Main Area" | 13 | from_room: "Main Area" |
diff --git a/data/maps/the_parthenon/doors.txtpb b/data/maps/the_parthenon/doors.txtpb index 82a2748..1161917 100644 --- a/data/maps/the_parthenon/doors.txtpb +++ b/data/maps/the_parthenon/doors.txtpb | |||
@@ -1,12 +1,24 @@ | |||
1 | doors { | 1 | doors { |
2 | name: "Double Letters" | 2 | name: "Double Letters" |
3 | type: EVENT | 3 | type: EVENT |
4 | switches: "double_letters" | 4 | receivers: "Components/Doors/entry_11" |
5 | receivers: "Components/Doors/entry_5" | ||
6 | receivers: "Components/Doors/entry_6" | ||
7 | receivers: "Components/Doors/entry_7" | ||
8 | receivers: "Components/Doors/entry_8" | ||
9 | receivers: "Components/Doors/entry_9" | ||
10 | receivers: "Components/Doors/entry_10" | ||
11 | double_letters: true | ||
5 | } | 12 | } |
6 | doors { | 13 | doors { |
7 | name: "Lavender Cubes" | 14 | name: "Lavender Cubes" |
8 | type: EVENT | 15 | type: EVENT |
9 | switches: "lavender_cubes" | 16 | receivers: "Components/Doors/entry_3" |
17 | panels { | ||
18 | map: "the_ancient" | ||
19 | room: "Inside" | ||
20 | name: "COLOR" | ||
21 | } | ||
10 | } | 22 | } |
11 | doors { | 23 | doors { |
12 | name: "K2 Door" | 24 | name: "K2 Door" |
@@ -19,6 +31,7 @@ doors { | |||
19 | panels { room: "Main Area" name: "ALEXANDER" answer: "greece" } | 31 | panels { room: "Main Area" name: "ALEXANDER" answer: "greece" } |
20 | panels { room: "Main Area" name: "CAESAR" answer: "rome" } | 32 | panels { room: "Main Area" name: "CAESAR" answer: "rome" } |
21 | location_room: "Main Area" | 33 | location_room: "Main Area" |
34 | location_name: "Empires" | ||
22 | } | 35 | } |
23 | doors { | 36 | doors { |
24 | name: "Ending Door" | 37 | name: "Ending Door" |
diff --git a/data/maps/the_parthenon/rooms/Ending.txtpb b/data/maps/the_parthenon/rooms/Ending.txtpb index 8fa805f..789e906 100644 --- a/data/maps/the_parthenon/rooms/Ending.txtpb +++ b/data/maps/the_parthenon/rooms/Ending.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Ending" | 1 | name: "Ending" |
2 | display_name: "Parthenon" | ||
3 | endings { | 2 | endings { |
4 | name: "CYAN" | 3 | name: "CYAN" |
5 | path: "Components/cyan_end" | 4 | path: "Components/cyan_end" |
diff --git a/data/maps/the_parthenon/rooms/K2 Room.txtpb b/data/maps/the_parthenon/rooms/K2 Room.txtpb index 1c95ad5..596b489 100644 --- a/data/maps/the_parthenon/rooms/K2 Room.txtpb +++ b/data/maps/the_parthenon/rooms/K2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "K2 Room" | 1 | name: "K2 Room" |
2 | display_name: "Parthenon" | ||
3 | letters { | 2 | letters { |
4 | key: "k" | 3 | key: "k" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_parthenon/rooms/Lavender Area.txtpb b/data/maps/the_parthenon/rooms/Lavender Area.txtpb index 6f67214..9e62498 100644 --- a/data/maps/the_parthenon/rooms/Lavender Area.txtpb +++ b/data/maps/the_parthenon/rooms/Lavender Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Lavender Area" | 1 | name: "Lavender Area" |
2 | display_name: "Parthenon" | ||
3 | panels { | 2 | panels { |
4 | name: "ME" | 3 | name: "ME" |
5 | path: "Panels/Lavender/panel_7" | 4 | path: "Panels/Lavender/panel_7" |
diff --git a/data/maps/the_parthenon/rooms/Main Area.txtpb b/data/maps/the_parthenon/rooms/Main Area.txtpb index db62c2c..2d989f8 100644 --- a/data/maps/the_parthenon/rooms/Main Area.txtpb +++ b/data/maps/the_parthenon/rooms/Main Area.txtpb | |||
@@ -1,12 +1,11 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Parthenon" | ||
3 | panels { | 2 | panels { |
4 | name: "XERXES" | 3 | name: "XERXES" |
5 | path: "Panels/Main/panel_1" | 4 | path: "Panels/Main/panel_1" |
6 | clue: "xerxes" | 5 | clue: "xerxes" |
7 | answer: "xerxes" | 6 | answer: "xerxes" |
8 | proxies { answer: "persia" path: "Panels/Empires/panel_7" } | 7 | proxies { answer: "persia" path: "Panels/Empires/panel_7" } |
9 | #proxies { answer: "xerxes" path: "Panels/Rulers/panel_13" } | 8 | proxies { answer: "xerxes" path: "Panels/Rulers/panel_13" } |
10 | required_door { name: "Double Letters" } | 9 | required_door { name: "Double Letters" } |
11 | } | 10 | } |
12 | panels { | 11 | panels { |
@@ -15,7 +14,7 @@ panels { | |||
15 | clue: "arthur" | 14 | clue: "arthur" |
16 | answer: "arthur" | 15 | answer: "arthur" |
17 | proxies { answer: "england" path: "Panels/Empires/panel_8" } | 16 | proxies { answer: "england" path: "Panels/Empires/panel_8" } |
18 | #proxies { answer: "arthur" path: "Panels/Rulers/panel_14" } | 17 | proxies { answer: "arthur" path: "Panels/Rulers/panel_14" } |
19 | required_door { name: "Double Letters" } | 18 | required_door { name: "Double Letters" } |
20 | } | 19 | } |
21 | panels { | 20 | panels { |
@@ -24,7 +23,7 @@ panels { | |||
24 | clue: "cleopatra" | 23 | clue: "cleopatra" |
25 | answer: "cleopatra" | 24 | answer: "cleopatra" |
26 | proxies { answer: "egypt" path: "Panels/Empires/panel_9" } | 25 | proxies { answer: "egypt" path: "Panels/Empires/panel_9" } |
27 | #proxies { answer: "cleopatra" path: "Panels/Rulers/panel_15" } | 26 | proxies { answer: "cleopatra" path: "Panels/Rulers/panel_15" } |
28 | required_door { name: "Double Letters" } | 27 | required_door { name: "Double Letters" } |
29 | } | 28 | } |
30 | panels { | 29 | panels { |
@@ -33,7 +32,7 @@ panels { | |||
33 | clue: "napoleon" | 32 | clue: "napoleon" |
34 | answer: "napoleon" | 33 | answer: "napoleon" |
35 | proxies { answer: "france" path: "Panels/Empires/panel_10" } | 34 | proxies { answer: "france" path: "Panels/Empires/panel_10" } |
36 | #proxies { answer: "napoleon" path: "Panels/Rulers/panel_16" } | 35 | proxies { answer: "napoleon" path: "Panels/Rulers/panel_16" } |
37 | required_door { name: "Double Letters" } | 36 | required_door { name: "Double Letters" } |
38 | } | 37 | } |
39 | panels { | 38 | panels { |
@@ -42,7 +41,7 @@ panels { | |||
42 | clue: "alexander" | 41 | clue: "alexander" |
43 | answer: "alexander" | 42 | answer: "alexander" |
44 | proxies { answer: "greece" path: "Panels/Empires/panel_11" } | 43 | proxies { answer: "greece" path: "Panels/Empires/panel_11" } |
45 | #proxies { answer: "alexander" path: "Panels/Rulers/panel_17" } | 44 | proxies { answer: "alexander" path: "Panels/Rulers/panel_17" } |
46 | required_door { name: "Double Letters" } | 45 | required_door { name: "Double Letters" } |
47 | } | 46 | } |
48 | panels { | 47 | panels { |
@@ -51,21 +50,27 @@ panels { | |||
51 | clue: "caesar" | 50 | clue: "caesar" |
52 | answer: "caesar" | 51 | answer: "caesar" |
53 | proxies { answer: "rome" path: "Panels/Empires/panel_12" } | 52 | proxies { answer: "rome" path: "Panels/Empires/panel_12" } |
54 | #proxies { answer: "caesar" path: "Panels/Rulers/panel_18" } | 53 | proxies { answer: "caesar" path: "Panels/Rulers/panel_18" } |
55 | required_door { name: "Double Letters" } | 54 | required_door { name: "Double Letters" } |
56 | } | 55 | } |
57 | ports { | 56 | ports { |
58 | name: "GALLERY" | 57 | name: "GALLERY" |
58 | display_name: "Columns Worldport" | ||
59 | path: "Components/Warps/worldport" | 59 | path: "Components/Warps/worldport" |
60 | orientation: "south" | 60 | destination { x: 0 y: 0 z: 0 } |
61 | rotation: 0 | ||
61 | } | 62 | } |
62 | ports { | 63 | ports { |
63 | name: "ENTRY" | 64 | name: "ENTRY" |
65 | display_name: "Building Worldport" | ||
64 | path: "Components/Warps/worldport2" | 66 | path: "Components/Warps/worldport2" |
65 | orientation: "south" | 67 | destination { x: 0 y: 0 z: -21 } |
68 | rotation: 0 | ||
66 | } | 69 | } |
67 | ports { | 70 | ports { |
68 | name: "REVITALIZED" | 71 | name: "REVITALIZED" |
72 | display_name: "Plum Hallway" | ||
69 | path: "Components/Warps/worldport3" | 73 | path: "Components/Warps/worldport3" |
70 | orientation: "north" | 74 | destination { x: -24 y: 0 z: -39 } |
75 | rotation: 180 | ||
71 | } | 76 | } |
diff --git a/data/maps/the_parthenon/rooms/U Keyholder.txtpb b/data/maps/the_parthenon/rooms/U Keyholder.txtpb index d3107b4..0a5c31b 100644 --- a/data/maps/the_parthenon/rooms/U Keyholder.txtpb +++ b/data/maps/the_parthenon/rooms/U Keyholder.txtpb | |||
@@ -1,6 +1,6 @@ | |||
1 | name: "U Keyholder" | 1 | name: "U Keyholder" |
2 | display_name: "Parthenon" | ||
3 | keyholders { | 2 | keyholders { |
4 | name: "U" | 3 | name: "U" |
5 | path: "Components/KeyHolders/keyHolderU" | 4 | path: "Components/KeyHolders/keyHolderU" |
5 | key: "u" | ||
6 | } | 6 | } |
diff --git a/data/maps/the_partial/doors.txtpb b/data/maps/the_partial/doors.txtpb index 2b233db..c51062a 100644 --- a/data/maps/the_partial/doors.txtpb +++ b/data/maps/the_partial/doors.txtpb | |||
@@ -22,6 +22,7 @@ doors { | |||
22 | panels { room: "Obverse Side" name: "CUT" } | 22 | panels { room: "Obverse Side" name: "CUT" } |
23 | panels { room: "Obverse Side" name: "FUN" } | 23 | panels { room: "Obverse Side" name: "FUN" } |
24 | location_room: "Obverse Side" | 24 | location_room: "Obverse Side" |
25 | location_name: "Obverse Side Room" | ||
25 | } | 26 | } |
26 | doors { | 27 | doors { |
27 | name: "Giant P" | 28 | name: "Giant P" |
diff --git a/data/maps/the_partial/rooms/Control Center Entrance.txtpb b/data/maps/the_partial/rooms/Control Center Entrance.txtpb index 8d7e228..02f3e69 100644 --- a/data/maps/the_partial/rooms/Control Center Entrance.txtpb +++ b/data/maps/the_partial/rooms/Control Center Entrance.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Control Center Entrance" | 1 | name: "Control Center Entrance" |
2 | display_name: "Partial" | ||
3 | panels { | 2 | panels { |
4 | name: "RETURN" | 3 | name: "RETURN" |
5 | path: "Panels/Control/panel_10" | 4 | path: "Panels/Control/panel_10" |
@@ -9,6 +8,10 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "CC" | 10 | name: "CC" |
11 | display_name: "Control Center Connector" | ||
12 | path: "Components/Warps/worldport2" | 12 | path: "Components/Warps/worldport2" |
13 | orientation: "north" | 13 | destination { x: -19 y: 0 z: 8 } |
14 | rotation: 180 | ||
15 | # TODO: shuffle entrances with dependent keyholders | ||
16 | no_shuffle: true | ||
14 | } | 17 | } |
diff --git a/data/maps/the_partial/rooms/F Room.txtpb b/data/maps/the_partial/rooms/F Room.txtpb index 358c936..d41d039 100644 --- a/data/maps/the_partial/rooms/F Room.txtpb +++ b/data/maps/the_partial/rooms/F Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "F Room" | 1 | name: "F Room" |
2 | display_name: "Partial" | ||
3 | letters { | 2 | letters { |
4 | key: "f" | 3 | key: "f" |
5 | path: "Components/Collectables/collectable2" | 4 | path: "Components/Collectables/collectable2" |
diff --git a/data/maps/the_partial/rooms/Obverse Side.txtpb b/data/maps/the_partial/rooms/Obverse Side.txtpb index 0d83c34..462888c 100644 --- a/data/maps/the_partial/rooms/Obverse Side.txtpb +++ b/data/maps/the_partial/rooms/Obverse Side.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Obverse Side" | 1 | name: "Obverse Side" |
2 | display_name: "Partial" | ||
3 | panels { | 2 | panels { |
4 | name: "PUN" | 3 | name: "PUN" |
5 | path: "Panels/Main/panel_1" | 4 | path: "Panels/Main/panel_1" |
@@ -100,13 +99,16 @@ panels { | |||
100 | } | 99 | } |
101 | ports { | 100 | ports { |
102 | name: "GREAT" | 101 | name: "GREAT" |
102 | display_name: "Main Entrance" | ||
103 | path: "Components/Warps/worldport" | 103 | path: "Components/Warps/worldport" |
104 | orientation: "west" | 104 | destination { x: -3 y: 0 z: 20 } |
105 | rotation: 270 | ||
105 | } | 106 | } |
106 | keyholders { | 107 | keyholders { |
107 | # This is one of the ones that's misnamed within the game. | 108 | # This is one of the ones that's misnamed within the game. |
108 | name: "L" | 109 | name: "L" |
109 | path: "Components/KeyHolders/keyHolderI" | 110 | path: "Components/KeyHolders/keyHolderI" |
111 | key: "l" | ||
110 | } | 112 | } |
111 | paintings { | 113 | paintings { |
112 | name: "F" | 114 | name: "F" |
diff --git a/data/maps/the_partial/rooms/P Room.txtpb b/data/maps/the_partial/rooms/P Room.txtpb index e7a7a60..618ebd9 100644 --- a/data/maps/the_partial/rooms/P Room.txtpb +++ b/data/maps/the_partial/rooms/P Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "P Room" | 1 | name: "P Room" |
2 | display_name: "Partial" | ||
3 | letters { | 2 | letters { |
4 | key: "p" | 3 | key: "p" |
5 | path: "Components/Collectables/collectable" | 4 | path: "Components/Collectables/collectable" |
diff --git a/data/maps/the_partial/rooms/Reverse Side.txtpb b/data/maps/the_partial/rooms/Reverse Side.txtpb index a286737..01858d6 100644 --- a/data/maps/the_partial/rooms/Reverse Side.txtpb +++ b/data/maps/the_partial/rooms/Reverse Side.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Reverse Side" | 1 | name: "Reverse Side" |
2 | display_name: "Partial" | ||
3 | panels { | 2 | panels { |
4 | name: "BRO" | 3 | name: "BRO" |
5 | path: "Panels/Side 2/panel_2" | 4 | path: "Panels/Side 2/panel_2" |
diff --git a/data/maps/the_perceptive/rooms/Main Area.txtpb b/data/maps/the_perceptive/rooms/Main Area.txtpb index 75a0343..90bfb41 100644 --- a/data/maps/the_perceptive/rooms/Main Area.txtpb +++ b/data/maps/the_perceptive/rooms/Main Area.txtpb | |||
@@ -1,7 +1,10 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Perceptive" | ||
3 | ports { | 2 | ports { |
4 | name: "CC" | 3 | name: "CC" |
4 | display_name: "Entrance" | ||
5 | path: "Components/Warps/worldport" | 5 | path: "Components/Warps/worldport" |
6 | orientation: "east" | 6 | destination { x: 3 y: 0 z: 13 } |
7 | rotation: 90 | ||
8 | # TODO: shuffle entrances with dependent keyholders | ||
9 | no_shuffle: true | ||
7 | } | 10 | } |
diff --git a/data/maps/the_plaza/connections.txtpb b/data/maps/the_plaza/connections.txtpb index 44586be..6da201c 100644 --- a/data/maps/the_plaza/connections.txtpb +++ b/data/maps/the_plaza/connections.txtpb | |||
@@ -21,22 +21,22 @@ connections { | |||
21 | connections { | 21 | connections { |
22 | from_room: "Center Room" | 22 | from_room: "Center Room" |
23 | to_room: "Top Left Room" | 23 | to_room: "Top Left Room" |
24 | door { name: "Top Left Door" } | 24 | door { name: "Northwest Door" } |
25 | } | 25 | } |
26 | connections { | 26 | connections { |
27 | from_room: "Center Room" | 27 | from_room: "Center Room" |
28 | to_room: "Top Right Room" | 28 | to_room: "Top Right Room" |
29 | door { name: "Top Right Door" } | 29 | door { name: "Northeast Door" } |
30 | } | 30 | } |
31 | connections { | 31 | connections { |
32 | from_room: "Center Room" | 32 | from_room: "Center Room" |
33 | to_room: "Bottom Left Room" | 33 | to_room: "Bottom Left Room" |
34 | door { name: "Bottom Left Door" } | 34 | door { name: "Southwest Door" } |
35 | } | 35 | } |
36 | connections { | 36 | connections { |
37 | from_room: "Center Room" | 37 | from_room: "Center Room" |
38 | to_room: "Bottom Right Room" | 38 | to_room: "Bottom Right Room" |
39 | door { name: "Bottom Right Door" } | 39 | door { name: "Southeast Door" } |
40 | } | 40 | } |
41 | connections { | 41 | connections { |
42 | from_room: "Center Room" | 42 | from_room: "Center Room" |
diff --git a/data/maps/the_plaza/doors.txtpb b/data/maps/the_plaza/doors.txtpb index be491ed..d95273c 100644 --- a/data/maps/the_plaza/doors.txtpb +++ b/data/maps/the_plaza/doors.txtpb | |||
@@ -31,7 +31,7 @@ doors { | |||
31 | location_room: "Main Area" | 31 | location_room: "Main Area" |
32 | } | 32 | } |
33 | doors { | 33 | doors { |
34 | name: "Top Left Door" | 34 | name: "Northwest Door" |
35 | type: STANDARD | 35 | type: STANDARD |
36 | receivers: "Components/Doors/entry_6" | 36 | receivers: "Components/Doors/entry_6" |
37 | panels { room: "Center Room" name: "REPORTER" } | 37 | panels { room: "Center Room" name: "REPORTER" } |
@@ -41,9 +41,10 @@ doors { | |||
41 | panels { room: "Center Room" name: "DENTIST" } | 41 | panels { room: "Center Room" name: "DENTIST" } |
42 | panels { room: "Center Room" name: "SQUIRREL" } | 42 | panels { room: "Center Room" name: "SQUIRREL" } |
43 | location_room: "Center Room" | 43 | location_room: "Center Room" |
44 | location_name: "First Room" | ||
44 | } | 45 | } |
45 | doors { | 46 | doors { |
46 | name: "Top Right Door" | 47 | name: "Northeast Door" |
47 | type: ITEM_ONLY | 48 | type: ITEM_ONLY |
48 | receivers: "Components/Doors/entry_7" | 49 | receivers: "Components/Doors/entry_7" |
49 | panels { room: "Center Room" name: "REPORTER" } | 50 | panels { room: "Center Room" name: "REPORTER" } |
@@ -54,7 +55,7 @@ doors { | |||
54 | panels { room: "Center Room" name: "SQUIRREL" } | 55 | panels { room: "Center Room" name: "SQUIRREL" } |
55 | } | 56 | } |
56 | doors { | 57 | doors { |
57 | name: "Bottom Left Door" | 58 | name: "Southwest Door" |
58 | type: ITEM_ONLY | 59 | type: ITEM_ONLY |
59 | receivers: "Components/Doors/entry_5" | 60 | receivers: "Components/Doors/entry_5" |
60 | panels { room: "Center Room" name: "REPORTER" } | 61 | panels { room: "Center Room" name: "REPORTER" } |
@@ -65,7 +66,7 @@ doors { | |||
65 | panels { room: "Center Room" name: "SQUIRREL" } | 66 | panels { room: "Center Room" name: "SQUIRREL" } |
66 | } | 67 | } |
67 | doors { | 68 | doors { |
68 | name: "Bottom Right Door" | 69 | name: "Southeast Door" |
69 | type: ITEM_ONLY | 70 | type: ITEM_ONLY |
70 | receivers: "Components/Doors/entry_4" | 71 | receivers: "Components/Doors/entry_4" |
71 | panels { room: "Center Room" name: "REPORTER" } | 72 | panels { room: "Center Room" name: "REPORTER" } |
@@ -76,7 +77,7 @@ doors { | |||
76 | panels { room: "Center Room" name: "SQUIRREL" } | 77 | panels { room: "Center Room" name: "SQUIRREL" } |
77 | } | 78 | } |
78 | doors { | 79 | doors { |
79 | name: "Top Left Puzzles" | 80 | name: "Northwest Puzzles" |
80 | type: LOCATION_ONLY | 81 | type: LOCATION_ONLY |
81 | panels { room: "Top Left Room" name: "BARE SOD" } | 82 | panels { room: "Top Left Room" name: "BARE SOD" } |
82 | panels { room: "Top Left Room" name: "SOD" } | 83 | panels { room: "Top Left Room" name: "SOD" } |
@@ -103,7 +104,7 @@ doors { | |||
103 | location_room: "Top Left Room" | 104 | location_room: "Top Left Room" |
104 | } | 105 | } |
105 | doors { | 106 | doors { |
106 | name: "Top Right Puzzles" | 107 | name: "Northeast Puzzles" |
107 | type: LOCATION_ONLY | 108 | type: LOCATION_ONLY |
108 | panels { room: "Top Right Room" name: "RIGHT WING" } | 109 | panels { room: "Top Right Room" name: "RIGHT WING" } |
109 | panels { room: "Top Right Room" name: "WING" } | 110 | panels { room: "Top Right Room" name: "WING" } |
@@ -129,7 +130,7 @@ doors { | |||
129 | location_room: "Top Right Room" | 130 | location_room: "Top Right Room" |
130 | } | 131 | } |
131 | doors { | 132 | doors { |
132 | name: "Bottom Left Puzzles" | 133 | name: "Southwest Puzzles" |
133 | type: LOCATION_ONLY | 134 | type: LOCATION_ONLY |
134 | panels { room: "Bottom Left Room" name: "SHELL (1)" } | 135 | panels { room: "Bottom Left Room" name: "SHELL (1)" } |
135 | panels { room: "Bottom Left Room" name: "SHELL (2)" } | 136 | panels { room: "Bottom Left Room" name: "SHELL (2)" } |
@@ -140,7 +141,7 @@ doors { | |||
140 | location_room: "Bottom Left Room" | 141 | location_room: "Bottom Left Room" |
141 | } | 142 | } |
142 | doors { | 143 | doors { |
143 | name: "Bottom Right Puzzles" | 144 | name: "Southeast Puzzles" |
144 | type: LOCATION_ONLY | 145 | type: LOCATION_ONLY |
145 | panels { room: "Bottom Right Room" name: "FLY" } | 146 | panels { room: "Bottom Right Room" name: "FLY" } |
146 | panels { room: "Bottom Right Room" name: "DECLOG" } | 147 | panels { room: "Bottom Right Room" name: "DECLOG" } |
diff --git a/data/maps/the_plaza/rooms/Bottom Left Room.txtpb b/data/maps/the_plaza/rooms/Bottom Left Room.txtpb index 833ccce..138efc6 100644 --- a/data/maps/the_plaza/rooms/Bottom Left Room.txtpb +++ b/data/maps/the_plaza/rooms/Bottom Left Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Bottom Left Room" | 1 | name: "Bottom Left Room" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "SHELL (1)" | 3 | name: "SHELL (1)" |
5 | path: "Panels/Room 4/panel_1" | 4 | path: "Panels/Room 4/panel_1" |
diff --git a/data/maps/the_plaza/rooms/Bottom Right Room.txtpb b/data/maps/the_plaza/rooms/Bottom Right Room.txtpb index cc38e23..fcd8d37 100644 --- a/data/maps/the_plaza/rooms/Bottom Right Room.txtpb +++ b/data/maps/the_plaza/rooms/Bottom Right Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Bottom Right Room" | 1 | name: "Bottom Right Room" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "FLY" | 3 | name: "FLY" |
5 | path: "Panels/Room 3/panel_1" | 4 | path: "Panels/Room 3/panel_1" |
diff --git a/data/maps/the_plaza/rooms/Center Room.txtpb b/data/maps/the_plaza/rooms/Center Room.txtpb index 4f1c62a..dea2d06 100644 --- a/data/maps/the_plaza/rooms/Center Room.txtpb +++ b/data/maps/the_plaza/rooms/Center Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Center Room" | 1 | name: "Center Room" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "REPORTER" | 3 | name: "REPORTER" |
5 | path: "Panels/Room 2/panel_1" | 4 | path: "Panels/Room 2/panel_1" |
diff --git a/data/maps/the_plaza/rooms/Main Area.txtpb b/data/maps/the_plaza/rooms/Main Area.txtpb index cabfc94..c2fca13 100644 --- a/data/maps/the_plaza/rooms/Main Area.txtpb +++ b/data/maps/the_plaza/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "COURTYARD" | 3 | name: "COURTYARD" |
5 | path: "Panels/Entrances/panel_1" | 4 | path: "Panels/Entrances/panel_1" |
@@ -37,16 +36,22 @@ panels { | |||
37 | } | 36 | } |
38 | ports { | 37 | ports { |
39 | name: "UNYIELDING" | 38 | name: "UNYIELDING" |
39 | display_name: "Unyielding Hallway" | ||
40 | path: "Components/Warps/worldport" | 40 | path: "Components/Warps/worldport" |
41 | orientation: "west" | 41 | destination { x: 1 y: 0 z: 10 } |
42 | rotation: 270 | ||
42 | } | 43 | } |
43 | ports { | 44 | ports { |
44 | name: "IMPRESSIVE" | 45 | name: "IMPRESSIVE" |
46 | display_name: "Impressive Hallway" | ||
45 | path: "Components/Warps/worldport2" | 47 | path: "Components/Warps/worldport2" |
46 | orientation: "west" | 48 | destination { x: 11 y: 0 z: 10 } |
49 | rotation: 270 | ||
47 | } | 50 | } |
48 | ports { | 51 | ports { |
49 | name: "BETWEEN" | 52 | name: "BETWEEN" |
53 | display_name: "Between Hallway" | ||
50 | path: "Components/Warps/worldport3" | 54 | path: "Components/Warps/worldport3" |
51 | orientation: "west" | 55 | destination { x: -9 y: 0 z: 10 } |
56 | rotation: 270 | ||
52 | } | 57 | } |
diff --git a/data/maps/the_plaza/rooms/Mastery.txtpb b/data/maps/the_plaza/rooms/Mastery.txtpb index 6b8fd5b..749837e 100644 --- a/data/maps/the_plaza/rooms/Mastery.txtpb +++ b/data/maps/the_plaza/rooms/Mastery.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Mastery" | 1 | name: "Mastery" |
2 | display_name: "Plaza" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/smiley" | 4 | path: "Components/Collectables/smiley" |
diff --git a/data/maps/the_plaza/rooms/Repetitive Entrance.txtpb b/data/maps/the_plaza/rooms/Repetitive Entrance.txtpb index 1690c11..59faaa8 100644 --- a/data/maps/the_plaza/rooms/Repetitive Entrance.txtpb +++ b/data/maps/the_plaza/rooms/Repetitive Entrance.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Repetitive Entrance" | 1 | name: "Repetitive Entrance" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "TEDIOUS" | 3 | name: "TEDIOUS" |
5 | path: "Panels/Entrances/panel_6" | 4 | path: "Panels/Entrances/panel_6" |
@@ -9,6 +8,8 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "REPETITIVE" | 10 | name: "REPETITIVE" |
11 | display_name: "Repetitive Entrance" | ||
12 | path: "Components/Warps/worldport5" | 12 | path: "Components/Warps/worldport5" |
13 | orientation: "north" | 13 | destination { x: -19 y: 0 z: 16 } |
14 | rotation: 180 | ||
14 | } | 15 | } |
diff --git a/data/maps/the_plaza/rooms/Sirenic Entrance.txtpb b/data/maps/the_plaza/rooms/Sirenic Entrance.txtpb index 048359d..524de2b 100644 --- a/data/maps/the_plaza/rooms/Sirenic Entrance.txtpb +++ b/data/maps/the_plaza/rooms/Sirenic Entrance.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Sirenic Entrance" | 1 | name: "Sirenic Entrance" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "SIREN" | 3 | name: "SIREN" |
5 | path: "Panels/Entrances/panel_8" | 4 | path: "Panels/Entrances/panel_8" |
@@ -9,6 +8,8 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "SIRENIC" | 10 | name: "SIRENIC" |
11 | display_name: "Sirenic Entrance" | ||
12 | path: "Components/Warps/worldport6" | 12 | path: "Components/Warps/worldport6" |
13 | orientation: "west" | 13 | destination { x: -51 y: 0 z: -43 } |
14 | rotation: 270 | ||
14 | } | 15 | } |
diff --git a/data/maps/the_plaza/rooms/Symbolic Entrance.txtpb b/data/maps/the_plaza/rooms/Symbolic Entrance.txtpb index 36b6a9b..e2719b8 100644 --- a/data/maps/the_plaza/rooms/Symbolic Entrance.txtpb +++ b/data/maps/the_plaza/rooms/Symbolic Entrance.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Symbolic Entrance" | 1 | name: "Symbolic Entrance" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "FIGURATIVE" | 3 | name: "FIGURATIVE" |
5 | path: "Panels/Entrances/panel_5" | 4 | path: "Panels/Entrances/panel_5" |
@@ -9,6 +8,8 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "SYMBOLIC" | 10 | name: "SYMBOLIC" |
11 | display_name: "Symbolic Entrance" | ||
12 | path: "Components/Warps/worldport4" | 12 | path: "Components/Warps/worldport4" |
13 | orientation: "south" | 13 | destination { x: 28 y: 0 z: 4 } |
14 | rotation: 0 | ||
14 | } | 15 | } |
diff --git a/data/maps/the_plaza/rooms/Top Left Room.txtpb b/data/maps/the_plaza/rooms/Top Left Room.txtpb index 4f562e0..d5b7056 100644 --- a/data/maps/the_plaza/rooms/Top Left Room.txtpb +++ b/data/maps/the_plaza/rooms/Top Left Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Top Left Room" | 1 | name: "Top Left Room" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "BARE SOD" | 3 | name: "BARE SOD" |
5 | path: "Panels/Room 6/panel_1" | 4 | path: "Panels/Room 6/panel_1" |
@@ -42,6 +41,7 @@ panels { | |||
42 | clue: "knot" | 41 | clue: "knot" |
43 | answer: "not" | 42 | answer: "not" |
44 | symbols: ZERO | 43 | symbols: ZERO |
44 | display_name: "KNOT (TL)" | ||
45 | } | 45 | } |
46 | panels { | 46 | panels { |
47 | name: "SURE TEMPER" | 47 | name: "SURE TEMPER" |
@@ -129,6 +129,7 @@ panels { | |||
129 | clue: "bear" | 129 | clue: "bear" |
130 | answer: "bearer" | 130 | answer: "bearer" |
131 | symbols: SPARKLES | 131 | symbols: SPARKLES |
132 | display_name: "BEAR (TL)" | ||
132 | } | 133 | } |
133 | panels { | 134 | panels { |
134 | name: "CHILL" | 135 | name: "CHILL" |
diff --git a/data/maps/the_plaza/rooms/Top Right Room.txtpb b/data/maps/the_plaza/rooms/Top Right Room.txtpb index 2a169af..7e91cbe 100644 --- a/data/maps/the_plaza/rooms/Top Right Room.txtpb +++ b/data/maps/the_plaza/rooms/Top Right Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Top Right Room" | 1 | name: "Top Right Room" |
2 | display_name: "Plaza" | ||
3 | panels { | 2 | panels { |
4 | name: "RIGHT WING" | 3 | name: "RIGHT WING" |
5 | path: "Panels/Room 5/panel_1" | 4 | path: "Panels/Room 5/panel_1" |
@@ -34,6 +33,7 @@ panels { | |||
34 | clue: "bear" | 33 | clue: "bear" |
35 | answer: "cave" | 34 | answer: "cave" |
36 | symbols: STARS | 35 | symbols: STARS |
36 | display_name: "BEAR (TR)" | ||
37 | } | 37 | } |
38 | panels { | 38 | panels { |
39 | name: "TYPIST" | 39 | name: "TYPIST" |
@@ -125,6 +125,7 @@ panels { | |||
125 | clue: "knot" | 125 | clue: "knot" |
126 | answer: "not" | 126 | answer: "not" |
127 | symbols: ZERO | 127 | symbols: ZERO |
128 | display_name: "KNOT (TR)" | ||
128 | } | 129 | } |
129 | panels { | 130 | panels { |
130 | name: "HALVES ANNOYED SOUR GOOD" | 131 | name: "HALVES ANNOYED SOUR GOOD" |
diff --git a/data/maps/the_quiet/rooms/Keyholder Room.txtpb b/data/maps/the_quiet/rooms/Keyholder Room.txtpb index e2322a8..d3cab73 100644 --- a/data/maps/the_quiet/rooms/Keyholder Room.txtpb +++ b/data/maps/the_quiet/rooms/Keyholder Room.txtpb | |||
@@ -1,6 +1,6 @@ | |||
1 | name: "Keyholder Room" | 1 | name: "Keyholder Room" |
2 | display_name: "Quiet" | ||
3 | keyholders { | 2 | keyholders { |
4 | name: "Q" | 3 | name: "Q" |
5 | path: "Components/KeyHolders/keyHolderQ" | 4 | path: "Components/KeyHolders/keyHolderQ" |
5 | key: "q" | ||
6 | } | 6 | } |
diff --git a/data/maps/the_quiet/rooms/Main Area.txtpb b/data/maps/the_quiet/rooms/Main Area.txtpb index d9c2361..72c0a1e 100644 --- a/data/maps/the_quiet/rooms/Main Area.txtpb +++ b/data/maps/the_quiet/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Quiet" | ||
3 | panels { | 2 | panels { |
4 | name: "SOLID" | 3 | name: "SOLID" |
5 | path: "Panels/Main/panel_1" | 4 | path: "Panels/Main/panel_1" |
@@ -98,6 +97,8 @@ panels { | |||
98 | } | 97 | } |
99 | ports { | 98 | ports { |
100 | name: "DAEDALUS" | 99 | name: "DAEDALUS" |
100 | display_name: "Entrance" | ||
101 | path: "Components/Warps/worldport" | 101 | path: "Components/Warps/worldport" |
102 | orientation: "east" | 102 | destination { x: 3 y: 0 z: 8 } |
103 | rotation: 90 | ||
103 | } | 104 | } |
diff --git a/data/maps/the_quiet/rooms/Q Room.txtpb b/data/maps/the_quiet/rooms/Q Room.txtpb index 224e71b..368f366 100644 --- a/data/maps/the_quiet/rooms/Q Room.txtpb +++ b/data/maps/the_quiet/rooms/Q Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Q Room" | 1 | name: "Q Room" |
2 | display_name: "Quiet" | ||
3 | letters { | 2 | letters { |
4 | key: "q" | 3 | key: "q" |
5 | path: "Components/Collectables/q" | 4 | path: "Components/Collectables/q" |
diff --git a/data/maps/the_relentless/rooms/All.txtpb b/data/maps/the_relentless/rooms/All.txtpb index 12705ba..19238c9 100644 --- a/data/maps/the_relentless/rooms/All.txtpb +++ b/data/maps/the_relentless/rooms/All.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "All" | 1 | name: "All" |
2 | display_name: "Relentless" | ||
3 | panels { | 2 | panels { |
4 | name: "LEFT (1)" | 3 | name: "LEFT (1)" |
5 | path: "Panels/Room_1/panel_6" | 4 | path: "Panels/Room_1/panel_6" |
diff --git a/data/maps/the_relentless/rooms/Left And Turn.txtpb b/data/maps/the_relentless/rooms/Left And Turn.txtpb index 5037f20..f79bb54 100644 --- a/data/maps/the_relentless/rooms/Left And Turn.txtpb +++ b/data/maps/the_relentless/rooms/Left And Turn.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Left And Turn" | 1 | name: "Left And Turn" |
2 | display_name: "Relentless" | ||
3 | panels { | 2 | panels { |
4 | name: "HIDE (1)" | 3 | name: "HIDE (1)" |
5 | path: "Panels/Room_1/panel_2" | 4 | path: "Panels/Room_1/panel_2" |
diff --git a/data/maps/the_relentless/rooms/Left Room.txtpb b/data/maps/the_relentless/rooms/Left Room.txtpb index 52b5154..4db0075 100644 --- a/data/maps/the_relentless/rooms/Left Room.txtpb +++ b/data/maps/the_relentless/rooms/Left Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Left Room" | 1 | name: "Left Room" |
2 | display_name: "Relentless" | ||
3 | panels { | 2 | panels { |
4 | name: "HIDE" | 3 | name: "HIDE" |
5 | path: "Panels/Room_1/panel_1" | 4 | path: "Panels/Room_1/panel_1" |
diff --git a/data/maps/the_relentless/rooms/Mastery.txtpb b/data/maps/the_relentless/rooms/Mastery.txtpb index 8b12c56..749837e 100644 --- a/data/maps/the_relentless/rooms/Mastery.txtpb +++ b/data/maps/the_relentless/rooms/Mastery.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Mastery" | 1 | name: "Mastery" |
2 | display_name: "Relentless" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/smiley" | 4 | path: "Components/Collectables/smiley" |
diff --git a/data/maps/the_relentless/rooms/Shop Room.txtpb b/data/maps/the_relentless/rooms/Shop Room.txtpb index 22b7acc..be3ff7a 100644 --- a/data/maps/the_relentless/rooms/Shop Room.txtpb +++ b/data/maps/the_relentless/rooms/Shop Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Shop Room" | 1 | name: "Shop Room" |
2 | display_name: "Relentless" | ||
3 | panels { | 2 | panels { |
4 | name: "LEFT (1)" | 3 | name: "LEFT (1)" |
5 | path: "Panels/Room_3/panel_5" | 4 | path: "Panels/Room_3/panel_5" |
diff --git a/data/maps/the_relentless/rooms/Turn And Shop.txtpb b/data/maps/the_relentless/rooms/Turn And Shop.txtpb index 9e61769..b9e257c 100644 --- a/data/maps/the_relentless/rooms/Turn And Shop.txtpb +++ b/data/maps/the_relentless/rooms/Turn And Shop.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Turn And Shop" | 1 | name: "Turn And Shop" |
2 | display_name: "Relentless" | ||
3 | panels { | 2 | panels { |
4 | name: "LEFT (1)" | 3 | name: "LEFT (1)" |
5 | path: "Panels/Room_2/panel_5" | 4 | path: "Panels/Room_2/panel_5" |
diff --git a/data/maps/the_relentless/rooms/Turn Room.txtpb b/data/maps/the_relentless/rooms/Turn Room.txtpb index 3b5caef..525786c 100644 --- a/data/maps/the_relentless/rooms/Turn Room.txtpb +++ b/data/maps/the_relentless/rooms/Turn Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Turn Room" | 1 | name: "Turn Room" |
2 | display_name: "Relentless" | ||
3 | panels { | 2 | panels { |
4 | name: "HIDE (1)" | 3 | name: "HIDE (1)" |
5 | path: "Panels/Room_2/panel_2" | 4 | path: "Panels/Room_2/panel_2" |
diff --git a/data/maps/the_repetitive/connections.txtpb b/data/maps/the_repetitive/connections.txtpb index 2b115a9..f4c06f2 100644 --- a/data/maps/the_repetitive/connections.txtpb +++ b/data/maps/the_repetitive/connections.txtpb | |||
@@ -6,13 +6,13 @@ connections { | |||
6 | connections { | 6 | connections { |
7 | from_room: "Main Room" | 7 | from_room: "Main Room" |
8 | to_room: "Plaza Connector" | 8 | to_room: "Plaza Connector" |
9 | door { name: "Plaza Entrance" } | 9 | door { name: "Black Hallway" } |
10 | oneway: true | ||
11 | } | 10 | } |
12 | connections { | 11 | connections { |
13 | from_room: "Plaza Connector" | 12 | from_room: "Plaza Connector" |
14 | to_room: "Main Room" | 13 | to_room: "Main Room" |
15 | oneway: true | 14 | oneway: true |
15 | vanilla_only: true | ||
16 | } | 16 | } |
17 | connections { | 17 | connections { |
18 | from_room: "Main Room" | 18 | from_room: "Main Room" |
diff --git a/data/maps/the_repetitive/doors.txtpb b/data/maps/the_repetitive/doors.txtpb index 9e63c1d..d964928 100644 --- a/data/maps/the_repetitive/doors.txtpb +++ b/data/maps/the_repetitive/doors.txtpb | |||
@@ -6,7 +6,7 @@ doors { | |||
6 | location_room: "Main Room" | 6 | location_room: "Main Room" |
7 | } | 7 | } |
8 | doors { | 8 | doors { |
9 | name: "Plaza Entrance" | 9 | name: "Black Hallway" |
10 | type: STANDARD | 10 | type: STANDARD |
11 | receivers: "Components/Doors/Door12" | 11 | receivers: "Components/Doors/Door12" |
12 | panels { room: "Main Room" name: "I" } | 12 | panels { room: "Main Room" name: "I" } |
@@ -194,3 +194,9 @@ doors { | |||
194 | panels { room: "Yellow Room" name: "ASSESSES" } | 194 | panels { room: "Yellow Room" name: "ASSESSES" } |
195 | panels { room: "Yellow Room" name: "TINTING" } | 195 | panels { room: "Yellow Room" name: "TINTING" } |
196 | } | 196 | } |
197 | doors { | ||
198 | name: "Anti-Collectable" | ||
199 | type: LOCATION_ONLY | ||
200 | senders: "Components/Collectables/anticollectable" | ||
201 | location_room: "Anti Room" | ||
202 | } | ||
diff --git a/data/maps/the_repetitive/metadata.txtpb b/data/maps/the_repetitive/metadata.txtpb index 6f5c459..76a0f50 100644 --- a/data/maps/the_repetitive/metadata.txtpb +++ b/data/maps/the_repetitive/metadata.txtpb | |||
@@ -1,10 +1,6 @@ | |||
1 | display_name: "The Repetitive" | 1 | display_name: "The Repetitive" |
2 | # The anti-collectable doesn't fit into our system right now so let's ignore it. | ||
3 | excluded_nodes: "Components/Collectables/anticollectable" | ||
4 | # These paintings are directly above/behind panels and thus can't be entered. | 2 | # These paintings are directly above/behind panels and thus can't be entered. |
5 | excluded_nodes: "Meshes/eyeRed3" | 3 | excluded_nodes: "Meshes/eyeRed3" |
6 | excluded_nodes: "Meshes/eyeRed4" | 4 | excluded_nodes: "Meshes/eyeRed4" |
7 | # I do not know what this is. | ||
8 | excluded_nodes: "Components/Doors/Door3/Hinge/panel_i" | ||
9 | # This has something to do with the magenta room entrance proxy panel. | 5 | # This has something to do with the magenta room entrance proxy panel. |
10 | excluded_nodes: "Panels/Eval/panel_26_proxyied_fake" | 6 | excluded_nodes: "Panels/Eval/panel_26_proxyied_fake" |
diff --git a/data/maps/the_repetitive/rooms/Anti Room.txtpb b/data/maps/the_repetitive/rooms/Anti Room.txtpb index 5451977..65a99ff 100644 --- a/data/maps/the_repetitive/rooms/Anti Room.txtpb +++ b/data/maps/the_repetitive/rooms/Anti Room.txtpb | |||
@@ -1,6 +1,4 @@ | |||
1 | name: "Anti Room" | 1 | name: "Anti Room" |
2 | display_name: "Repetitive" | ||
3 | # Ignore the collectible. The mod should remove it and the back wall too. | ||
4 | panels { | 2 | panels { |
5 | name: "HA (1)" | 3 | name: "HA (1)" |
6 | path: "Panels/Entry/panel_7" | 4 | path: "Panels/Entry/panel_7" |
@@ -39,9 +37,17 @@ panels { | |||
39 | symbols: EXAMPLE | 37 | symbols: EXAMPLE |
40 | } | 38 | } |
41 | panels { | 39 | panels { |
42 | name: "EYE" | 40 | name: "EYE (1)" |
43 | path: "Panels/Entry/panel4" | 41 | path: "Panels/Entry/panel4" |
44 | clue: "eye" | 42 | clue: "eye" |
45 | answer: "iris" | 43 | answer: "iris" |
46 | symbols: BOXES | 44 | symbols: BOXES |
47 | } | 45 | } |
46 | panels { | ||
47 | # This appears after grabbing the anti-collectable. | ||
48 | name: "EYE (2)" | ||
49 | path: "Components/Doors/Door3/Hinge/panel_i" | ||
50 | clue: "eye" | ||
51 | answer: "i" | ||
52 | symbols: ZERO | ||
53 | } | ||
diff --git a/data/maps/the_repetitive/rooms/Cyan Room.txtpb b/data/maps/the_repetitive/rooms/Cyan Room.txtpb index fb56ac7..d6790f5 100644 --- a/data/maps/the_repetitive/rooms/Cyan Room.txtpb +++ b/data/maps/the_repetitive/rooms/Cyan Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Cyan Room" | 1 | name: "Cyan Room" |
2 | display_name: "Repetitive" | ||
3 | panels { | 2 | panels { |
4 | name: "ALFA" | 3 | name: "ALFA" |
5 | path: "Panels/Lingo2/panel_3" | 4 | path: "Panels/Lingo2/panel_3" |
diff --git a/data/maps/the_repetitive/rooms/Dot Area.txtpb b/data/maps/the_repetitive/rooms/Dot Area.txtpb index 202ed92..c4f4583 100644 --- a/data/maps/the_repetitive/rooms/Dot Area.txtpb +++ b/data/maps/the_repetitive/rooms/Dot Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Dot Area" | 1 | name: "Dot Area" |
2 | display_name: "Repetitive" | ||
3 | panels { | 2 | panels { |
4 | name: "TUTU (1)" | 3 | name: "TUTU (1)" |
5 | path: "Panels/Lingo2/panel" | 4 | path: "Panels/Lingo2/panel" |
@@ -96,7 +95,7 @@ panels { | |||
96 | clue: "door" | 95 | clue: "door" |
97 | answer: "door" | 96 | answer: "door" |
98 | symbols: EVAL | 97 | symbols: EVAL |
99 | #proxies { answer: "door" path: "Panels/Eval/panel_26_proxyied_1" } | 98 | proxies { answer: "door" path: "Panels/Eval/panel_26_proxyied_1" } |
100 | proxies { answer: "do" path: "Panels/Eval/panel_26_proxyied_2" } | 99 | proxies { answer: "do" path: "Panels/Eval/panel_26_proxyied_2" } |
101 | } | 100 | } |
102 | panels { | 101 | panels { |
diff --git a/data/maps/the_repetitive/rooms/Entry Connector.txtpb b/data/maps/the_repetitive/rooms/Entry Connector.txtpb index 8addc7f..16dc116 100644 --- a/data/maps/the_repetitive/rooms/Entry Connector.txtpb +++ b/data/maps/the_repetitive/rooms/Entry Connector.txtpb | |||
@@ -1,7 +1,11 @@ | |||
1 | name: "Entry Connector" | 1 | name: "Entry Connector" |
2 | display_name: "Repetitive" | ||
3 | ports { | 2 | ports { |
4 | name: "ENTRY" | 3 | name: "ENTRY" |
4 | display_name: "Northwest Worldport" | ||
5 | path: "Components/Warps/worldport2" | 5 | path: "Components/Warps/worldport2" |
6 | orientation: "south" | 6 | destination { x: -11 y: 0 z: 13 } |
7 | rotation: 0 | ||
8 | # TODO: this is part of what makes the keyholder dependent connection form CC | ||
9 | # safe in vanilla doors | ||
10 | no_shuffle: true | ||
7 | } | 11 | } |
diff --git a/data/maps/the_repetitive/rooms/Lime Room.txtpb b/data/maps/the_repetitive/rooms/Lime Room.txtpb index 71e4c2c..37d4937 100644 --- a/data/maps/the_repetitive/rooms/Lime Room.txtpb +++ b/data/maps/the_repetitive/rooms/Lime Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Lime Room" | 1 | name: "Lime Room" |
2 | display_name: "Repetitive" | ||
3 | panels { | 2 | panels { |
4 | name: "RAT" | 3 | name: "RAT" |
5 | path: "Panels/Lingo2/panel_1" | 4 | path: "Panels/Lingo2/panel_1" |
diff --git a/data/maps/the_repetitive/rooms/Magenta Room.txtpb b/data/maps/the_repetitive/rooms/Magenta Room.txtpb index 827d058..d38e485 100644 --- a/data/maps/the_repetitive/rooms/Magenta Room.txtpb +++ b/data/maps/the_repetitive/rooms/Magenta Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Magenta Room" | 1 | name: "Magenta Room" |
2 | display_name: "Repetitive" | ||
3 | panels { | 2 | panels { |
4 | name: "WRITE" | 3 | name: "WRITE" |
5 | path: "Panels/Eval/panel_9" | 4 | path: "Panels/Eval/panel_9" |
diff --git a/data/maps/the_repetitive/rooms/Main Room.txtpb b/data/maps/the_repetitive/rooms/Main Room.txtpb index 9fd36d4..3e624a7 100644 --- a/data/maps/the_repetitive/rooms/Main Room.txtpb +++ b/data/maps/the_repetitive/rooms/Main Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Room" | 1 | name: "Main Room" |
2 | display_name: "Repetitive" | ||
3 | panels { | 2 | panels { |
4 | name: "HOTS (2)" | 3 | name: "HOTS (2)" |
5 | path: "Panels/Entry/panel_3" | 4 | path: "Panels/Entry/panel_3" |
@@ -139,6 +138,10 @@ paintings { | |||
139 | } | 138 | } |
140 | ports { | 139 | ports { |
141 | name: "CC" | 140 | name: "CC" |
141 | display_name: "Southwest Worldport" | ||
142 | path: "Components/Warps/worldport3" | 142 | path: "Components/Warps/worldport3" |
143 | orientation: "east" | 143 | destination { x: -5.5 y: 0 z: 56 } |
144 | rotation: 90 | ||
145 | # TODO: shuffle entrances with dependent keyholders | ||
146 | no_shuffle: true | ||
144 | } | 147 | } |
diff --git a/data/maps/the_repetitive/rooms/Mastery Room.txtpb b/data/maps/the_repetitive/rooms/Mastery Room.txtpb index 074a825..5e3326c 100644 --- a/data/maps/the_repetitive/rooms/Mastery Room.txtpb +++ b/data/maps/the_repetitive/rooms/Mastery Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Mastery Room" | 1 | name: "Mastery Room" |
2 | display_name: "Repetitive" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/smiley" | 4 | path: "Components/Collectables/smiley" |
diff --git a/data/maps/the_repetitive/rooms/Plaza Connector.txtpb b/data/maps/the_repetitive/rooms/Plaza Connector.txtpb index 88f7fc4..b26fdb0 100644 --- a/data/maps/the_repetitive/rooms/Plaza Connector.txtpb +++ b/data/maps/the_repetitive/rooms/Plaza Connector.txtpb | |||
@@ -1,7 +1,8 @@ | |||
1 | name: "Plaza Connector" | 1 | name: "Plaza Connector" |
2 | display_name: "Repetitive" | ||
3 | ports { | 2 | ports { |
4 | name: "PLAZA" | 3 | name: "PLAZA" |
4 | display_name: "Northeast Worldport" | ||
5 | path: "Components/Warps/worldport" | 5 | path: "Components/Warps/worldport" |
6 | orientation: "north" | 6 | destination { x: 15 y: 0 z: 13 } |
7 | rotation: 0 | ||
7 | } | 8 | } |
diff --git a/data/maps/the_repetitive/rooms/Yellow Room.txtpb b/data/maps/the_repetitive/rooms/Yellow Room.txtpb index 65d665f..9b7d619 100644 --- a/data/maps/the_repetitive/rooms/Yellow Room.txtpb +++ b/data/maps/the_repetitive/rooms/Yellow Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Yellow Room" | 1 | name: "Yellow Room" |
2 | display_name: "Repetitive" | ||
3 | panels { | 2 | panels { |
4 | name: "W" | 3 | name: "W" |
5 | path: "Panels/Eval/panel_1" | 4 | path: "Panels/Eval/panel_1" |
diff --git a/data/maps/the_revitalized/rooms/Bye Room.txtpb b/data/maps/the_revitalized/rooms/Bye Room.txtpb index 60726c2..52d8c42 100644 --- a/data/maps/the_revitalized/rooms/Bye Room.txtpb +++ b/data/maps/the_revitalized/rooms/Bye Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Bye Room" | 1 | name: "Bye Room" |
2 | display_name: "Revitalized" | ||
3 | panels { | 2 | panels { |
4 | name: "BYE" | 3 | name: "BYE" |
5 | path: "Panels/panel_1" | 4 | path: "Panels/panel_1" |
@@ -9,6 +8,8 @@ panels { | |||
9 | } | 8 | } |
10 | ports { | 9 | ports { |
11 | name: "PARTHENON" | 10 | name: "PARTHENON" |
11 | display_name: "Entrance" | ||
12 | path: "Components/Warps/worldport" | 12 | path: "Components/Warps/worldport" |
13 | orientation: "south" | 13 | destination { x: 30 y: 0 z: 16 } |
14 | rotation: 0 | ||
14 | } | 15 | } |
diff --git a/data/maps/the_revitalized/rooms/Hidden Room.txtpb b/data/maps/the_revitalized/rooms/Hidden Room.txtpb index c9ec310..61f2e4d 100644 --- a/data/maps/the_revitalized/rooms/Hidden Room.txtpb +++ b/data/maps/the_revitalized/rooms/Hidden Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Hidden Room" | 1 | name: "Hidden Room" |
2 | display_name: "Revitalized" | ||
3 | panels { | 2 | panels { |
4 | name: "HIDDEN" | 3 | name: "HIDDEN" |
5 | path: "Panels/panel_3" | 4 | path: "Panels/panel_3" |
diff --git a/data/maps/the_revitalized/rooms/Hide Room.txtpb b/data/maps/the_revitalized/rooms/Hide Room.txtpb index 6660787..92b29bf 100644 --- a/data/maps/the_revitalized/rooms/Hide Room.txtpb +++ b/data/maps/the_revitalized/rooms/Hide Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Hide Room" | 1 | name: "Hide Room" |
2 | display_name: "Revitalized" | ||
3 | panels { | 2 | panels { |
4 | name: "HIDE" | 3 | name: "HIDE" |
5 | path: "Panels/panel_2" | 4 | path: "Panels/panel_2" |
diff --git a/data/maps/the_revitalized/rooms/High Room.txtpb b/data/maps/the_revitalized/rooms/High Room.txtpb index de8fdaf..e876801 100644 --- a/data/maps/the_revitalized/rooms/High Room.txtpb +++ b/data/maps/the_revitalized/rooms/High Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "High Room" | 1 | name: "High Room" |
2 | display_name: "Revitalized" | ||
3 | panels { | 2 | panels { |
4 | name: "HIGH" | 3 | name: "HIGH" |
5 | path: "Panels/panel_4" | 4 | path: "Panels/panel_4" |
diff --git a/data/maps/the_revitalized/rooms/Return Room.txtpb b/data/maps/the_revitalized/rooms/Return Room.txtpb index 1d9d094..d629c8d 100644 --- a/data/maps/the_revitalized/rooms/Return Room.txtpb +++ b/data/maps/the_revitalized/rooms/Return Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Return Room" | 1 | name: "Return Room" |
2 | display_name: "Revitalized" | ||
3 | panels { | 2 | panels { |
4 | name: "RETURN" | 3 | name: "RETURN" |
5 | path: "Components/panel_7" | 4 | path: "Components/panel_7" |
diff --git a/data/maps/the_revitalized/rooms/Too Room.txtpb b/data/maps/the_revitalized/rooms/Too Room.txtpb index a35b80f..819c3cf 100644 --- a/data/maps/the_revitalized/rooms/Too Room.txtpb +++ b/data/maps/the_revitalized/rooms/Too Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Too Room" | 1 | name: "Too Room" |
2 | display_name: "Revitalized" | ||
3 | panels { | 2 | panels { |
4 | name: "TOO" | 3 | name: "TOO" |
5 | path: "Panels/panel_6" | 4 | path: "Panels/panel_6" |
diff --git a/data/maps/the_revitalized/rooms/Won Room.txtpb b/data/maps/the_revitalized/rooms/Won Room.txtpb index 16766fb..8cedd1d 100644 --- a/data/maps/the_revitalized/rooms/Won Room.txtpb +++ b/data/maps/the_revitalized/rooms/Won Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Won Room" | 1 | name: "Won Room" |
2 | display_name: "Revitalized" | ||
3 | panels { | 2 | panels { |
4 | name: "WON" | 3 | name: "WON" |
5 | path: "Panels/panel_5" | 4 | path: "Panels/panel_5" |
diff --git a/data/maps/the_shop/rooms/Main Area.txtpb b/data/maps/the_shop/rooms/Main Area.txtpb index eb0e696..df1cb14 100644 --- a/data/maps/the_shop/rooms/Main Area.txtpb +++ b/data/maps/the_shop/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Shop" | ||
3 | panels { | 2 | panels { |
4 | name: "DUCKS" | 3 | name: "DUCKS" |
5 | path: "Panels/Books/panel_1" | 4 | path: "Panels/Books/panel_1" |
@@ -156,9 +155,13 @@ panels { | |||
156 | } | 155 | } |
157 | ports { | 156 | ports { |
158 | name: "ENTRY" | 157 | name: "ENTRY" |
158 | display_name: "Entrance" | ||
159 | path: "Components/Warps/worldport" | 159 | path: "Components/Warps/worldport" |
160 | destination { x: 4 y: 0 z: 12 } | ||
161 | rotation: 90 | ||
160 | } | 162 | } |
161 | keyholders { | 163 | keyholders { |
162 | name: "N" | 164 | name: "N" |
163 | path: "Components/KeyHolders/keyHolderN" | 165 | path: "Components/KeyHolders/keyHolderN" |
166 | key: "n" | ||
164 | } | 167 | } |
diff --git a/data/maps/the_sirenic/rooms/Mastery.txtpb b/data/maps/the_sirenic/rooms/Mastery.txtpb index 849202b..749837e 100644 --- a/data/maps/the_sirenic/rooms/Mastery.txtpb +++ b/data/maps/the_sirenic/rooms/Mastery.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Mastery" | 1 | name: "Mastery" |
2 | display_name: "Sirenic" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/smiley" | 4 | path: "Components/Collectables/smiley" |
diff --git a/data/maps/the_sirenic/rooms/Puzzles.txtpb b/data/maps/the_sirenic/rooms/Puzzles.txtpb index 6784163..0f62cbd 100644 --- a/data/maps/the_sirenic/rooms/Puzzles.txtpb +++ b/data/maps/the_sirenic/rooms/Puzzles.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Puzzles" | 1 | name: "Puzzles" |
2 | display_name: "Sirenic" | ||
3 | panels { | 2 | panels { |
4 | name: "Left Top 1" | 3 | name: "Left Top 1" |
5 | path: "Panels/Room_1/pip_1" | 4 | path: "Panels/Room_1/pip_1" |
diff --git a/data/maps/the_sirenic/rooms/Start.txtpb b/data/maps/the_sirenic/rooms/Start.txtpb index 61150d9..532d951 100644 --- a/data/maps/the_sirenic/rooms/Start.txtpb +++ b/data/maps/the_sirenic/rooms/Start.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Start" | 1 | name: "Start" |
2 | display_name: "Sirenic" | ||
3 | panels { | 2 | panels { |
4 | name: "Flipped" | 3 | name: "Flipped" |
5 | path: "Panels/Entry/entry_2" | 4 | path: "Panels/Entry/entry_2" |
@@ -16,6 +15,8 @@ panels { | |||
16 | } | 15 | } |
17 | ports { | 16 | ports { |
18 | name: "PLAZA" | 17 | name: "PLAZA" |
18 | display_name: "Entrance" | ||
19 | path: "Components/Warps/worldport" | 19 | path: "Components/Warps/worldport" |
20 | orientation: "south" | 20 | destination { x: 0 y: 0 z: 26 } |
21 | rotation: 0 | ||
21 | } | 22 | } |
diff --git a/data/maps/the_stormy/rooms/Center.txtpb b/data/maps/the_stormy/rooms/Center.txtpb index 62395ba..6a929a7 100644 --- a/data/maps/the_stormy/rooms/Center.txtpb +++ b/data/maps/the_stormy/rooms/Center.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Center" | 1 | name: "Center" |
2 | display_name: "Stormy" | ||
3 | panels { | 2 | panels { |
4 | name: "REACTOR" | 3 | name: "REACTOR" |
5 | path: "Panels/Room_1/panel_7" | 4 | path: "Panels/Room_1/panel_7" |
@@ -20,6 +19,7 @@ panels { | |||
20 | clue: "cloud" | 19 | clue: "cloud" |
21 | answer: "rain" | 20 | answer: "rain" |
22 | symbols: AGE | 21 | symbols: AGE |
22 | display_name: "CLOUD (1)" | ||
23 | } | 23 | } |
24 | panels { | 24 | panels { |
25 | name: "WIND" | 25 | name: "WIND" |
@@ -27,9 +27,12 @@ panels { | |||
27 | clue: "wind" | 27 | clue: "wind" |
28 | answer: "tornado" | 28 | answer: "tornado" |
29 | symbols: CROSS | 29 | symbols: CROSS |
30 | display_name: "WIND (1)" | ||
30 | } | 31 | } |
31 | ports { | 32 | ports { |
32 | name: "ENTRY" | 33 | name: "ENTRY" |
34 | display_name: "Worldport" | ||
33 | path: "Components/Warps/worldport" | 35 | path: "Components/Warps/worldport" |
34 | orientation: "west" | 36 | destination { x: -8.5 y: 0 z: 6 } |
37 | rotation: 270 | ||
35 | } | 38 | } |
diff --git a/data/maps/the_stormy/rooms/Nuclear Side.txtpb b/data/maps/the_stormy/rooms/Nuclear Side.txtpb index 15d393b..7704cfb 100644 --- a/data/maps/the_stormy/rooms/Nuclear Side.txtpb +++ b/data/maps/the_stormy/rooms/Nuclear Side.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Nuclear Side" | 1 | name: "Nuclear Side" |
2 | display_name: "Stormy" | ||
3 | panels { | 2 | panels { |
4 | name: "GERM" | 3 | name: "GERM" |
5 | path: "Panels/Room_1/panel_2" | 4 | path: "Panels/Room_1/panel_2" |
diff --git a/data/maps/the_stormy/rooms/Nuclear Vestibule.txtpb b/data/maps/the_stormy/rooms/Nuclear Vestibule.txtpb index 1d9c46d..34a6715 100644 --- a/data/maps/the_stormy/rooms/Nuclear Vestibule.txtpb +++ b/data/maps/the_stormy/rooms/Nuclear Vestibule.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Nuclear Vestibule" | 1 | name: "Nuclear Vestibule" |
2 | display_name: "Stormy" | ||
3 | panels { | 2 | panels { |
4 | name: "STORM" | 3 | name: "STORM" |
5 | path: "Panels/Room 2/panel_11" | 4 | path: "Panels/Room 2/panel_11" |
diff --git a/data/maps/the_stormy/rooms/Rain Side.txtpb b/data/maps/the_stormy/rooms/Rain Side.txtpb index cb59a6d..1babef2 100644 --- a/data/maps/the_stormy/rooms/Rain Side.txtpb +++ b/data/maps/the_stormy/rooms/Rain Side.txtpb | |||
@@ -1,11 +1,11 @@ | |||
1 | name: "Rain Side" | 1 | name: "Rain Side" |
2 | display_name: "Stormy" | ||
3 | panels { | 2 | panels { |
4 | name: "CLOUD" | 3 | name: "CLOUD" |
5 | path: "Panels/Room_1/panel_4" | 4 | path: "Panels/Room_1/panel_4" |
6 | clue: "cloud" | 5 | clue: "cloud" |
7 | answer: "lightning" | 6 | answer: "lightning" |
8 | symbols: CROSS | 7 | symbols: CROSS |
8 | display_name: "CLOUD (2)" | ||
9 | } | 9 | } |
10 | panels { | 10 | panels { |
11 | name: "WIND" | 11 | name: "WIND" |
@@ -13,4 +13,5 @@ panels { | |||
13 | clue: "wind" | 13 | clue: "wind" |
14 | answer: "whirlwind" | 14 | answer: "whirlwind" |
15 | symbols: PYRAMID | 15 | symbols: PYRAMID |
16 | display_name: "WIND (2)" | ||
16 | } | 17 | } |
diff --git a/data/maps/the_stormy/rooms/Tornado Side.txtpb b/data/maps/the_stormy/rooms/Tornado Side.txtpb index d91d057..1e5ca69 100644 --- a/data/maps/the_stormy/rooms/Tornado Side.txtpb +++ b/data/maps/the_stormy/rooms/Tornado Side.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Tornado Side" | 1 | name: "Tornado Side" |
2 | display_name: "Stormy" | ||
3 | panels { | 2 | panels { |
4 | name: "PUDDLE" | 3 | name: "PUDDLE" |
5 | path: "Panels/Room_1/panel_6" | 4 | path: "Panels/Room_1/panel_6" |
diff --git a/data/maps/the_stormy/rooms/Tornado Vestibule.txtpb b/data/maps/the_stormy/rooms/Tornado Vestibule.txtpb index 9a98c3e..e6c7e60 100644 --- a/data/maps/the_stormy/rooms/Tornado Vestibule.txtpb +++ b/data/maps/the_stormy/rooms/Tornado Vestibule.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Tornado Vestibule" | 1 | name: "Tornado Vestibule" |
2 | display_name: "Stormy" | ||
3 | panels { | 2 | panels { |
4 | name: "SHIP" | 3 | name: "SHIP" |
5 | path: "Panels/Room 2/panel_12" | 4 | path: "Panels/Room 2/panel_12" |
diff --git a/data/maps/the_stormy/rooms/Volcano Side.txtpb b/data/maps/the_stormy/rooms/Volcano Side.txtpb index bd823d5..73c7ae4 100644 --- a/data/maps/the_stormy/rooms/Volcano Side.txtpb +++ b/data/maps/the_stormy/rooms/Volcano Side.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Volcano Side" | 1 | name: "Volcano Side" |
2 | display_name: "Stormy" | ||
3 | panels { | 2 | panels { |
4 | name: "SNOW" | 3 | name: "SNOW" |
5 | path: "Panels/Room_1/panel_1" | 4 | path: "Panels/Room_1/panel_1" |
diff --git a/data/maps/the_stormy/rooms/X2 Room.txtpb b/data/maps/the_stormy/rooms/X2 Room.txtpb index 7d46956..3be4def 100644 --- a/data/maps/the_stormy/rooms/X2 Room.txtpb +++ b/data/maps/the_stormy/rooms/X2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "X2 Room" | 1 | name: "X2 Room" |
2 | display_name: "Stormy" | ||
3 | letters { | 2 | letters { |
4 | key: "x" | 3 | key: "x" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_sturdy/rooms/Main Area.txtpb b/data/maps/the_sturdy/rooms/Main Area.txtpb index 39a425f..8c81a1e 100644 --- a/data/maps/the_sturdy/rooms/Main Area.txtpb +++ b/data/maps/the_sturdy/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Sturdy" | ||
3 | panels { | 2 | panels { |
4 | name: "MOVE (1)" | 3 | name: "MOVE (1)" |
5 | path: "Panels/Main/panel_1" | 4 | path: "Panels/Main/panel_1" |
@@ -11,7 +10,7 @@ panels { | |||
11 | proxies { answer: "down" path: "Panels/Down/down_1" } | 10 | proxies { answer: "down" path: "Panels/Down/down_1" } |
12 | proxies { answer: "left" path: "Panels/Left/left_1" } | 11 | proxies { answer: "left" path: "Panels/Left/left_1" } |
13 | proxies { answer: "right" path: "Panels/Right/right_1" } | 12 | proxies { answer: "right" path: "Panels/Right/right_1" } |
14 | #proxies { answer: "move" path: "Panels/Secret/secret_1" } | 13 | proxies { answer: "move" path: "Panels/Secret/secret_1" } |
15 | } | 14 | } |
16 | panels { | 15 | panels { |
17 | name: "MOVE (2)" | 16 | name: "MOVE (2)" |
@@ -24,7 +23,7 @@ panels { | |||
24 | proxies { answer: "down" path: "Panels/Down/down_2" } | 23 | proxies { answer: "down" path: "Panels/Down/down_2" } |
25 | proxies { answer: "left" path: "Panels/Left/left_2" } | 24 | proxies { answer: "left" path: "Panels/Left/left_2" } |
26 | proxies { answer: "right" path: "Panels/Right/right_2" } | 25 | proxies { answer: "right" path: "Panels/Right/right_2" } |
27 | #proxies { answer: "move" path: "Panels/Secret/secret_2" } | 26 | proxies { answer: "move" path: "Panels/Secret/secret_2" } |
28 | } | 27 | } |
29 | panels { | 28 | panels { |
30 | name: "MOVE (3)" | 29 | name: "MOVE (3)" |
@@ -37,7 +36,7 @@ panels { | |||
37 | proxies { answer: "down" path: "Panels/Down/down_3" } | 36 | proxies { answer: "down" path: "Panels/Down/down_3" } |
38 | proxies { answer: "left" path: "Panels/Left/left_3" } | 37 | proxies { answer: "left" path: "Panels/Left/left_3" } |
39 | proxies { answer: "right" path: "Panels/Right/right_3" } | 38 | proxies { answer: "right" path: "Panels/Right/right_3" } |
40 | #proxies { answer: "move" path: "Panels/Secret/secret_3" } | 39 | proxies { answer: "move" path: "Panels/Secret/secret_3" } |
41 | } | 40 | } |
42 | panels { | 41 | panels { |
43 | name: "MOVE (4)" | 42 | name: "MOVE (4)" |
@@ -50,7 +49,7 @@ panels { | |||
50 | proxies { answer: "down" path: "Panels/Down/down_4" } | 49 | proxies { answer: "down" path: "Panels/Down/down_4" } |
51 | proxies { answer: "left" path: "Panels/Left/left_4" } | 50 | proxies { answer: "left" path: "Panels/Left/left_4" } |
52 | proxies { answer: "right" path: "Panels/Right/right_4" } | 51 | proxies { answer: "right" path: "Panels/Right/right_4" } |
53 | #proxies { answer: "move" path: "Panels/Secret/secret_4" } | 52 | proxies { answer: "move" path: "Panels/Secret/secret_4" } |
54 | } | 53 | } |
55 | panels { | 54 | panels { |
56 | name: "MOVE (5)" | 55 | name: "MOVE (5)" |
@@ -63,7 +62,7 @@ panels { | |||
63 | proxies { answer: "down" path: "Panels/Down/down_5" } | 62 | proxies { answer: "down" path: "Panels/Down/down_5" } |
64 | proxies { answer: "left" path: "Panels/Left/left_5" } | 63 | proxies { answer: "left" path: "Panels/Left/left_5" } |
65 | proxies { answer: "right" path: "Panels/Right/right_5" } | 64 | proxies { answer: "right" path: "Panels/Right/right_5" } |
66 | #proxies { answer: "move" path: "Panels/Secret/secret_5" } | 65 | proxies { answer: "move" path: "Panels/Secret/secret_5" } |
67 | } | 66 | } |
68 | panels { | 67 | panels { |
69 | name: "MOVE (6)" | 68 | name: "MOVE (6)" |
@@ -76,7 +75,7 @@ panels { | |||
76 | proxies { answer: "down" path: "Panels/Down/down_6" } | 75 | proxies { answer: "down" path: "Panels/Down/down_6" } |
77 | proxies { answer: "left" path: "Panels/Left/left_6" } | 76 | proxies { answer: "left" path: "Panels/Left/left_6" } |
78 | proxies { answer: "right" path: "Panels/Right/right_6" } | 77 | proxies { answer: "right" path: "Panels/Right/right_6" } |
79 | #proxies { answer: "move" path: "Panels/Secret/secret_6" } | 78 | proxies { answer: "move" path: "Panels/Secret/secret_6" } |
80 | } | 79 | } |
81 | panels { | 80 | panels { |
82 | name: "MOVE (7)" | 81 | name: "MOVE (7)" |
@@ -89,7 +88,7 @@ panels { | |||
89 | proxies { answer: "down" path: "Panels/Down/down_7" } | 88 | proxies { answer: "down" path: "Panels/Down/down_7" } |
90 | proxies { answer: "left" path: "Panels/Left/left_7" } | 89 | proxies { answer: "left" path: "Panels/Left/left_7" } |
91 | proxies { answer: "right" path: "Panels/Right/right_7" } | 90 | proxies { answer: "right" path: "Panels/Right/right_7" } |
92 | #proxies { answer: "move" path: "Panels/Secret/secret_7" } | 91 | proxies { answer: "move" path: "Panels/Secret/secret_7" } |
93 | } | 92 | } |
94 | panels { | 93 | panels { |
95 | name: "MOVE (8)" | 94 | name: "MOVE (8)" |
@@ -102,13 +101,19 @@ panels { | |||
102 | proxies { answer: "down" path: "Panels/Down/down_8" } | 101 | proxies { answer: "down" path: "Panels/Down/down_8" } |
103 | proxies { answer: "left" path: "Panels/Left/left_8" } | 102 | proxies { answer: "left" path: "Panels/Left/left_8" } |
104 | proxies { answer: "right" path: "Panels/Right/right_8" } | 103 | proxies { answer: "right" path: "Panels/Right/right_8" } |
105 | #proxies { answer: "move" path: "Panels/Secret/secret_8" } | 104 | proxies { answer: "move" path: "Panels/Secret/secret_8" } |
106 | } | 105 | } |
107 | ports { | 106 | ports { |
108 | name: "OWL" | 107 | name: "OWL" |
108 | display_name: "Magenta Hallway" | ||
109 | path: "Components/Warps/worldport" | 109 | path: "Components/Warps/worldport" |
110 | destination { x: 17 y: 0 z: 41 } | ||
111 | rotation: 90 | ||
110 | } | 112 | } |
111 | ports { | 113 | ports { |
112 | name: "COLORFUL" | 114 | name: "COLORFUL" |
115 | display_name: "Cyan Hallway" | ||
113 | path: "Components/Warps/worldport2" | 116 | path: "Components/Warps/worldport2" |
117 | destination { x: 17 y: 0 z: -33 } | ||
118 | rotation: 90 | ||
114 | } | 119 | } |
diff --git a/data/maps/the_sturdy/rooms/S2 Area.txtpb b/data/maps/the_sturdy/rooms/S2 Area.txtpb index 118b914..38fad5e 100644 --- a/data/maps/the_sturdy/rooms/S2 Area.txtpb +++ b/data/maps/the_sturdy/rooms/S2 Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "S2 Area" | 1 | name: "S2 Area" |
2 | display_name: "Sturdy" | ||
3 | panels { | 2 | panels { |
4 | name: "COLORS" | 3 | name: "COLORS" |
5 | path: "Panels/Rainbow/panel_1" | 4 | path: "Panels/Rainbow/panel_1" |
diff --git a/data/maps/the_sun_temple/connections.txtpb b/data/maps/the_sun_temple/connections.txtpb index b0b3a0a..ffe4d5d 100644 --- a/data/maps/the_sun_temple/connections.txtpb +++ b/data/maps/the_sun_temple/connections.txtpb | |||
@@ -7,6 +7,7 @@ connections { | |||
7 | from_room: "Temple" | 7 | from_room: "Temple" |
8 | to_room: "Ending" | 8 | to_room: "Ending" |
9 | door { name: "Ending" } | 9 | door { name: "Ending" } |
10 | purple_ending: true | ||
10 | } | 11 | } |
11 | connections { | 12 | connections { |
12 | from_room: "Temple" | 13 | from_room: "Temple" |
diff --git a/data/maps/the_sun_temple/rooms/Ending.txtpb b/data/maps/the_sun_temple/rooms/Ending.txtpb index a94e606..975374a 100644 --- a/data/maps/the_sun_temple/rooms/Ending.txtpb +++ b/data/maps/the_sun_temple/rooms/Ending.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Ending" | 1 | name: "Ending" |
2 | display_name: "Sun Temple" | ||
3 | endings { | 2 | endings { |
4 | name: "PURPLE" | 3 | name: "PURPLE" |
5 | path: "Components/purple_ending" | 4 | path: "Components/purple_ending" |
diff --git a/data/maps/the_sun_temple/rooms/Entrance.txtpb b/data/maps/the_sun_temple/rooms/Entrance.txtpb index 0b2a0bd..07d6e38 100644 --- a/data/maps/the_sun_temple/rooms/Entrance.txtpb +++ b/data/maps/the_sun_temple/rooms/Entrance.txtpb | |||
@@ -1,14 +1,16 @@ | |||
1 | name: "Entrance" | 1 | name: "Entrance" |
2 | display_name: "Sun Temple" | ||
3 | panels { | 2 | panels { |
4 | name: "SUN" | 3 | name: "SUN" |
5 | path: "Panels/Main/panel_1" | 4 | path: "Panels/Main/panel_1" |
6 | clue: "sun" | 5 | clue: "sun" |
7 | answer: "sun" | 6 | answer: "sun" |
8 | #proxies { answer: "sun" path: "Panels/Sun/panel_8" } | 7 | proxies { answer: "sun" path: "Panels/Sun/panel_8" } |
9 | proxies { answer: "moon" path: "Panels/Moon/panel_15" } | 8 | proxies { answer: "moon" path: "Panels/Moon/panel_15" } |
10 | } | 9 | } |
11 | ports { | 10 | ports { |
12 | name: "UNKEMPT" | 11 | name: "UNKEMPT" |
12 | display_name: "Entrance" | ||
13 | path: "Components/Warps/worldport" | 13 | path: "Components/Warps/worldport" |
14 | destination { x: 0 y: 0 z: 13 } | ||
15 | rotation: 0 | ||
14 | } | 16 | } |
diff --git a/data/maps/the_sun_temple/rooms/Mastery.txtpb b/data/maps/the_sun_temple/rooms/Mastery.txtpb index b416a9a..bbe8742 100644 --- a/data/maps/the_sun_temple/rooms/Mastery.txtpb +++ b/data/maps/the_sun_temple/rooms/Mastery.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Mastery" | 1 | name: "Mastery" |
2 | display_name: "Sun Temple" | ||
3 | masteries { | 2 | masteries { |
4 | name: "MASTERY" | 3 | name: "MASTERY" |
5 | path: "Components/Collectables/collectable" | 4 | path: "Components/Collectables/collectable" |
diff --git a/data/maps/the_sun_temple/rooms/Temple.txtpb b/data/maps/the_sun_temple/rooms/Temple.txtpb index 6281584..4f39737 100644 --- a/data/maps/the_sun_temple/rooms/Temple.txtpb +++ b/data/maps/the_sun_temple/rooms/Temple.txtpb | |||
@@ -1,12 +1,11 @@ | |||
1 | name: "Temple" | 1 | name: "Temple" |
2 | display_name: "Sun Temple" | ||
3 | panels { | 2 | panels { |
4 | name: "DELAY" | 3 | name: "DELAY" |
5 | path: "Panels/Main/panel_2" | 4 | path: "Panels/Main/panel_2" |
6 | clue: "delay" | 5 | clue: "delay" |
7 | answer: "day" | 6 | answer: "day" |
8 | symbols: SPARKLES | 7 | symbols: SPARKLES |
9 | #proxies { answer: "day" path: "Panels/Sun/panel_9" } | 8 | proxies { answer: "day" path: "Panels/Sun/panel_9" } |
10 | proxies { answer: "night" path: "Panels/Moon/panel_16" } | 9 | proxies { answer: "night" path: "Panels/Moon/panel_16" } |
11 | } | 10 | } |
12 | panels { | 11 | panels { |
@@ -15,7 +14,7 @@ panels { | |||
15 | clue: "lawn" | 14 | clue: "lawn" |
16 | answer: "dawn" | 15 | answer: "dawn" |
17 | symbols: SPARKLES | 16 | symbols: SPARKLES |
18 | #proxies { answer: "dawn" path: "Panels/Sun/panel_10" } | 17 | proxies { answer: "dawn" path: "Panels/Sun/panel_10" } |
19 | proxies { answer: "dusk" path: "Panels/Moon/panel_17" } | 18 | proxies { answer: "dusk" path: "Panels/Moon/panel_17" } |
20 | } | 19 | } |
21 | panels { | 20 | panels { |
@@ -24,7 +23,7 @@ panels { | |||
24 | clue: "jump" | 23 | clue: "jump" |
25 | answer: "spring" | 24 | answer: "spring" |
26 | symbols: SUN | 25 | symbols: SUN |
27 | #proxies { answer: "spring" path: "Panels/Sun/panel_11" } | 26 | proxies { answer: "spring" path: "Panels/Sun/panel_11" } |
28 | proxies { answer: "autumn" path: "Panels/Moon/panel_18" } | 27 | proxies { answer: "autumn" path: "Panels/Moon/panel_18" } |
29 | } | 28 | } |
30 | panels { | 29 | panels { |
@@ -33,7 +32,7 @@ panels { | |||
33 | clue: "heavy" | 32 | clue: "heavy" |
34 | answer: "light" | 33 | answer: "light" |
35 | symbols: SUN | 34 | symbols: SUN |
36 | #proxies { answer: "light" path: "Panels/Sun/panel_12" } | 35 | proxies { answer: "light" path: "Panels/Sun/panel_12" } |
37 | proxies { answer: "dark" path: "Panels/Moon/panel_19" } | 36 | proxies { answer: "dark" path: "Panels/Moon/panel_19" } |
38 | } | 37 | } |
39 | panels { | 38 | panels { |
@@ -42,7 +41,7 @@ panels { | |||
42 | clue: "knife" | 41 | clue: "knife" |
43 | answer: "life" | 42 | answer: "life" |
44 | symbols: ZERO | 43 | symbols: ZERO |
45 | #proxies { answer: "life" path: "Panels/Sun/panel_13" } | 44 | proxies { answer: "life" path: "Panels/Sun/panel_13" } |
46 | proxies { answer: "death" path: "Panels/Moon/panel_20" } | 45 | proxies { answer: "death" path: "Panels/Moon/panel_20" } |
47 | } | 46 | } |
48 | panels { | 47 | panels { |
@@ -51,7 +50,7 @@ panels { | |||
51 | clue: "arm" | 50 | clue: "arm" |
52 | answer: "warmth" | 51 | answer: "warmth" |
53 | symbols: SPARKLES | 52 | symbols: SPARKLES |
54 | #proxies { answer: "warmth" path: "Panels/Sun/panel_14" } | 53 | proxies { answer: "warmth" path: "Panels/Sun/panel_14" } |
55 | proxies { answer: "chill" path: "Panels/Moon/panel_21" } | 54 | proxies { answer: "chill" path: "Panels/Moon/panel_21" } |
56 | } | 55 | } |
57 | panels { | 56 | panels { |
@@ -60,5 +59,5 @@ panels { | |||
60 | clue: "equinox" | 59 | clue: "equinox" |
61 | answer: "equinox" | 60 | answer: "equinox" |
62 | proxies { answer: "solstice" path: "Panels/End/panel_23" } | 61 | proxies { answer: "solstice" path: "Panels/End/panel_23" } |
63 | #proxies { answer: "equinox" path: "Panels/End/panel_24" } | 62 | proxies { answer: "equinox" path: "Panels/End/panel_24" } |
64 | } | 63 | } |
diff --git a/data/maps/the_sweet/rooms/Main Area.txtpb b/data/maps/the_sweet/rooms/Main Area.txtpb index b72b6d4..a8976f7 100644 --- a/data/maps/the_sweet/rooms/Main Area.txtpb +++ b/data/maps/the_sweet/rooms/Main Area.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Main Area" | 1 | name: "Main Area" |
2 | display_name: "Sweet" | ||
3 | panels { | 2 | panels { |
4 | name: "POTATO" | 3 | name: "POTATO" |
5 | path: "Panels/Sweetening Room/panel_1" | 4 | path: "Panels/Sweetening Room/panel_1" |
@@ -201,9 +200,15 @@ panels { | |||
201 | } | 200 | } |
202 | ports { | 201 | ports { |
203 | name: "EXIT1" | 202 | name: "EXIT1" |
203 | display_name: "South Worldport" | ||
204 | path: "Components/Warps/worldport" | 204 | path: "Components/Warps/worldport" |
205 | destination { x: 0 y: 0 z: -11.5 } | ||
206 | rotation: 180 | ||
205 | } | 207 | } |
206 | ports { | 208 | ports { |
207 | name: "EXIT2" | 209 | name: "EXIT2" |
210 | display_name: "North Worldport" | ||
208 | path: "Components/Warps/worldport2" | 211 | path: "Components/Warps/worldport2" |
212 | destination { x: 0 y: 0 z: -17.5 } | ||
213 | rotation: 0 | ||
209 | } | 214 | } |
diff --git a/data/maps/the_sweet/rooms/Y2 Room.txtpb b/data/maps/the_sweet/rooms/Y2 Room.txtpb index 4da87f3..d448f57 100644 --- a/data/maps/the_sweet/rooms/Y2 Room.txtpb +++ b/data/maps/the_sweet/rooms/Y2 Room.txtpb | |||
@@ -1,5 +1,4 @@ | |||
1 | name: "Y2 Room" | 1 | name: "Y2 Room" |
2 | display_name: "Sweet" | ||
3 | letters { | 2 | letters { |
4 | key: "y" | 3 | key: "y" |
5 | level2: true | 4 | level2: true |
diff --git a/data/maps/the_symbolic/doors.txtpb b/data/maps/the_symbolic/doors.txtpb index e84811e..5a443e7 100644 --- a/data/maps/the_symbolic/doors.txtpb +++ b/data/maps/the_symbolic/doors.txtpb | |||
@@ -1,62 +1,55 @@ | |||
1 | doors { | 1 | doors { |
2 | name: "White Door" | 2 | name: "White Door" |
3 | type: STANDARD | 3 | type: EVENT |
4 | receivers: "Components/Doors/Door18" | 4 | #receivers: "Components/Doors/Door18" |
5 | panels { room: "White Room" name: "WRITE" } | 5 | panels { room: "White Room" name: "WRITE" } |
6 | location_room: "White Room" | ||
7 | } | 6 | } |
8 | doors { | 7 | doors { |
9 | name: "Black Door" | 8 | name: "Black Door" |
10 | type: STANDARD | 9 | type: EVENT |
11 | receivers: "Components/Doors/Door19" | 10 | #receivers: "Components/Doors/Door19" |
12 | panels { room: "Black Room" name: "HERE" } | 11 | panels { room: "Black Room" name: "HERE" } |
13 | location_room: "Black Room" | ||
14 | } | 12 | } |
15 | doors { | 13 | doors { |
16 | name: "Red Door" | 14 | name: "Red Door" |
17 | type: STANDARD | 15 | type: EVENT |
18 | receivers: "Components/Doors/Door20" | 16 | #receivers: "Components/Doors/Door20" |
19 | panels { room: "Red Room" name: "SYNONYM" } | 17 | panels { room: "Red Room" name: "SYNONYM" } |
20 | location_room: "Red Room" | ||
21 | } | 18 | } |
22 | doors { | 19 | doors { |
23 | name: "Blue Door" | 20 | name: "Blue Door" |
24 | type: STANDARD | 21 | type: EVENT |
25 | receivers: "Components/Doors/Door21" | 22 | #receivers: "Components/Doors/Door21" |
26 | panels { room: "Blue Room" name: "DEPLETE" } | 23 | panels { room: "Blue Room" name: "DEPLETE" } |
27 | location_room: "Blue Room" | ||
28 | } | 24 | } |
29 | doors { | 25 | doors { |
30 | name: "Green Door" | 26 | name: "Green Door" |
31 | type: STANDARD | 27 | type: EVENT |
32 | receivers: "Components/Doors/Door22" | 28 | #receivers: "Components/Doors/Door22" |
33 | panels { room: "Green Room" name: "INERT" } | 29 | panels { room: "Green Room" name: "INERT" } |
34 | location_room: "Green Room" | ||
35 | } | 30 | } |
36 | doors { | 31 | doors { |
37 | name: "Yellow Door" | 32 | name: "Yellow Door" |
38 | type: STANDARD | 33 | type: EVENT |
39 | receivers: "Components/Doors/Door23" | 34 | #receivers: "Components/Doors/Door23" |
40 | panels { room: "Yellow Room" name: "WHOLE" } | 35 | panels { room: "Yellow Room" name: "WHOLE" } |
41 | location_room: "Yellow Room" | ||
42 | } | 36 | } |
43 | doors { | 37 | doors { |
44 | name: "Purple Door" | 38 | name: "Purple Door" |
45 | type: STANDARD | 39 | type: EVENT |
46 | receivers: "Components/Doors/Door24" | 40 | #receivers: "Components/Doors/Door24" |
47 | panels { room: "Purple Room" name: "TIME" } | 41 | panels { room: "Purple Room" name: "TIME" } |
48 | location_room: "Purple Room" | ||
49 | } | 42 | } |
50 | doors { | 43 | doors { |
51 | name: "Orange Door" | 44 | name: "Orange Door" |
52 | type: STANDARD | 45 | type: EVENT |
53 | receivers: "Components/Doors/Door25" | 46 | #receivers: "Components/Doors/Door25" |
54 | panels { room: "Orange Room" name: "YOUNG" } | 47 | panels { room: "Orange Room" name: "YOUNG" } |
55 | location_room: "Orange Room" | ||
56 | } | 48 | } |
57 | doors { | 49 | doors { |
58 | name: "Tutorial Door" | 50 | name: "Tutorial Door" |
59 | type: EVENT | 51 | type: ITEM_ONLY |
52 | receivers: "Components/Doors/Door" | ||
60 | panels { room: "Tutorial" name: "<- (1)" } | 53 | panels { room: "Tutorial" name: "<- (1)" } |
61 | panels { room: "Tutorial" name: "<- (2)" } | 54 | panels { room: "Tutorial" name: "<- (2)" } |
62 | panels { room: "Tutorial" name: "<- (3)" } | 55 | panels { room: "Tutorial" name: "<- (3)" } |
diff --git a/data/maps/the_symbolic/rooms/Poetry Room 1.txtpb b/data/maps/the_symbolic/rooms/Poetry Room 1.txtpb index 523e260..a6ae04c 100644 --- a/data/maps/the_symbolic/rooms/Poetry Room 1.txtpb +++ b/data/maps/the_symbolic/rooms/Poetry Room 1.txtpb | |||
@@ -5,7 +5,7 @@ panels { | |||
5 | clue: "absorbed" | 5 | clue: "absorbed" |
6 | answer: "abs" | 6 | answer: "abs" |
7 | symbols: EVAL | 7 | symbols: EVAL |
8 | #proxies { answer: "abs" path: "Panels/Proxy/absorbed_proxied_1" } | 8 | proxies { answer: "abs" path: "Panels/Proxy/absorbed_proxied_1" } |
9 | proxies { answer: "bed" path: "Panels/Proxy/absorbed_proxied_2" } | 9 | proxies { answer: "bed" path: "Panels/Proxy/absorbed_proxied_2" } |
10 | } | 10 | } |
11 | panels { | 11 | panels { |
@@ -14,6 +14,6 @@ panels { | |||
14 | clue: "primordial" | 14 | clue: "primordial" |
15 | answer: "prim" | 15 | answer: "prim" |
16 | symbols: EVAL | 16 | symbols: EVAL |
17 | #proxies { answer: "prim" path: "Panels/Proxy/primordial_proxied_1" } | 17 | proxies { answer: "prim" path: "Panels/Proxy/primordial_proxied_1" } |
18 | proxies { answer: "dial" path: "Panels/Proxy/primordial_proxied_2" } | 18 | proxies { answer: "dial" path: "Panels/Proxy/primordial_proxied_2" } |
19 | } | 19 | } |
diff --git a/data/maps/the_symbolic/rooms/Poetry Room 3.txtpb b/data/maps/the_symbolic/rooms/Poetry Room 3.txtpb index 5c62301..e70be1c 100644 --- a/data/maps/the_symbolic/rooms/Poetry Room 3.txtpb +++ b/data/maps/the_symbolic/rooms/Poetry Room 3.txtpb | |||
@@ -18,6 +18,6 @@ panels { | |||
18 | answer: "ugly" | 18 | answer: "ugly" |
19 | symbols: EVAL | 19 | symbols: EVAL |
20 | symbols: LINGO | 20 | symbols: LINGO |
21 | #proxies { answer: "ugly" path: "Panels/NotNoT/not_pretty_proxied_1" } | 21 | proxies { answer: "ugly" path: "Panels/NotNoT/not_pretty_proxied_1" } |
22 | proxies { answer: "prey" path: "Panels/NotNoT/not_pretty_proxied_2" } | 22 | proxies { answer: "prey" path: "Panels/NotNoT/not_pretty_proxied_2" } |
23 | } | 23 | } |
diff --git a/data/maps/the_symbolic/rooms/Poetry Room Left.txtpb b/data/maps/the_symbolic/rooms/Poetry Room Left.txtpb index 561c034..2d2eb3f 100644 --- a/data/maps/the_symbolic/rooms/Poetry Room Left.txtpb +++ b/data/maps/the_symbolic/rooms/Poetry Room Left.txtpb | |||
@@ -18,6 +18,6 @@ panels { | |||
18 | answer: "false" | 18 | answer: "false" |
19 | symbols: EVAL | 19 | symbols: EVAL |
20 | symbols: LINGO | 20 | symbols: LINGO |
21 | #proxies { answer: "false" path: "Panels/NotNoT/not_true_proxied_1" } | 21 | proxies { answer: "false" path: "Panels/NotNoT/not_true_proxied_1" } |
22 | proxies { answer: "rue" path: "Panels/NotNoT/not_true_proxied_2" } | 22 | proxies { answer: "rue" path: "Panels/NotNoT/not_true_proxied_2" } |
23 | } | 23 | } |
diff --git a/data/maps/the_symbolic/rooms/Poetry Room Right.txtpb b/data/maps/the_symbolic/rooms/Poetry Room Right.txtpb index 4928191..490a6a7 100644 --- a/data/maps/the_symbolic/rooms/Poetry Room Right.txtpb +++ b/data/maps/the_symbolic/rooms/Poetry Room Right.txtpb | |||
@@ -18,6 +18,6 @@ panels { | |||
18 | answer: "worse" | 18 | answer: "worse" |
19 | symbols: EVAL | 19 | symbols: EVAL |
20 | symbols: LINGO | 20 | symbols: LINGO |
21 | #proxies { answer: "worse" path: "Panels/NotNoT/not_better_proxied_1" } | 21 | proxies { answer: "worse" path: "Panels/NotNoT/not_better_proxied_1" } |
22 | proxies { answer: "beer" path: "Panels/NotNoT/not_better_proxied_2" } | 22 | proxies { answer: "beer" path: "Panels/NotNoT/not_better_proxied_2" } |
23 | } | 23 | } |
diff --git a/data/maps/the_symbolic/rooms/Red Blue Room.txtpb b/data/maps/the_symbolic/rooms/Red Blue Room.txtpb index cb057b0..c246853 100644 --- a/data/maps/the_symbolic/rooms/Red Blue Room.txtpb +++ b/data/maps/the_symbolic/rooms/Red Blue Room.txtpb | |||
@@ -6,7 +6,7 @@ panels { | |||
6 | answer: "word" | 6 | answer: "word" |
7 | symbols: ZERO | 7 | symbols: ZERO |
8 | symbols: EVAL | 8 | symbols: EVAL |
9 | #proxies { answer: "word" path: "Panels/Entry/rightward_proxyied_1" } | 9 | proxies { answer: "word" path: "Panels/Entry/rightward_proxyied_1" } |
10 | proxies { answer: "whirred" path: "Panels/Entry/rightward_proxyied_2" } | 10 | proxies { answer: "whirred" path: "Panels/Entry/rightward_proxyied_2" } |
11 | } | 11 | } |
12 | panels { | 12 | panels { |
@@ -15,6 +15,6 @@ panels { | |||
15 | clue: "typewriting" | 15 | clue: "typewriting" |
16 | answer: "writing" | 16 | answer: "writing" |
17 | symbols: EVAL | 17 | symbols: EVAL |
18 | #proxies { answer: "writing" path: "Panels/Entry/typewriter_proxied_1" } | 18 | proxies { answer: "writing" path: "Panels/Entry/typewriter_proxied_1" } |
19 | proxies { answer: "poetry" path: "Panels/Entry/typewriter_proxied_2" } | 19 | proxies { answer: "poetry" path: "Panels/Entry/typewriter_proxied_2" } |
20 | } | 20 | } |
diff --git a/data/maps/the_symbolic/rooms/White Room.txtpb b/data/maps/the_symbolic/rooms/White Room.txtpb index 808588e..d3509cb 100644 --- a/data/maps/the_symbolic/rooms/White Room.txtpb +++ b/data/maps/the_symbolic/rooms/White Room.txtpb | |||
@@ -7,5 +7,8 @@ panels { | |||
7 | } | 7 | } |
8 | ports { | 8 | ports { |
9 | name: "PLAZA" | 9 | name: "PLAZA" |
10 | display_name: "Entrance" | ||
10 | path: "Components/Warps/worldport" | 11 | path: "Components/Warps/worldport" |
12 | destination { x: 0 y: 0 z: 2.5 } | ||
13 | rotation: 0 | ||
11 | } | 14 | } |
diff --git a/data/maps/the_talented/rooms/Main Area.txtpb b/data/maps/the_talented/rooms/Main Area.txtpb index cc3e222..a0dac7b 100644 --- a/data/maps/the_talented/rooms/Main Area.txtpb +++ b/data/maps/the_talented/rooms/Main Area.txtpb | |||
@@ -107,8 +107,12 @@ panels { | |||
107 | keyholders { | 107 | keyholders { |
108 | name: "Y" | 108 | name: "Y" |
109 | path: "Components/KeyHolders/keyHolderY" | 109 | path: "Components/KeyHolders/keyHolderY" |
110 | key: "y" | ||
110 | } | 111 | } |
111 | ports { | 112 | ports { |
112 | name: "GREAT" | 113 | name: "GREAT" |
114 | display_name: "Entrance" | ||
113 | path: "Components/Warps/worldport" | 115 | path: "Components/Warps/worldport" |
116 | destination { x: -3.5 y: 0 z: 21 } | ||
117 | rotation: 270 | ||
114 | } | 118 | } |
diff --git a/data/maps/the_tenacious/rooms/Control Center Entrance.txtpb b/data/maps/the_tenacious/rooms/Control Center Entrance.txtpb index 45a0d12..873fabe 100644 --- a/data/maps/the_tenacious/rooms/Control Center Entrance.txtpb +++ b/data/maps/the_tenacious/rooms/Control Center Entrance.txtpb | |||
@@ -8,5 +8,10 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "CC" | 10 | name: "CC" |
11 | display_name: "Control Center Connector" | ||
11 | path: "Components/Warps/worldport" | 12 | path: "Components/Warps/worldport" |
13 | destination { x: 0 y: 0 z: 10 } | ||
14 | rotation: 0 | ||
15 | # TODO: shuffle entrances with dependent keyholders | ||
16 | no_shuffle: true | ||
12 | } | 17 | } |
diff --git a/data/maps/the_tenacious/rooms/Main Area.txtpb b/data/maps/the_tenacious/rooms/Main Area.txtpb index 8190827..18356e7 100644 --- a/data/maps/the_tenacious/rooms/Main Area.txtpb +++ b/data/maps/the_tenacious/rooms/Main Area.txtpb | |||
@@ -2,4 +2,5 @@ name: "Main Area" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "K" | 3 | name: "K" |
4 | path: "Components/KeyHolders/keyHolderK" | 4 | path: "Components/KeyHolders/keyHolderK" |
5 | key: "k" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_three_doors/doors.txtpb b/data/maps/the_three_doors/doors.txtpb index 99fbcee..5ae9d90 100644 --- a/data/maps/the_three_doors/doors.txtpb +++ b/data/maps/the_three_doors/doors.txtpb | |||
@@ -50,4 +50,5 @@ doors { | |||
50 | panels { room: "Dead End Room" name: "DEAD" } | 50 | panels { room: "Dead End Room" name: "DEAD" } |
51 | panels { room: "Dead End Room" name: "END" } | 51 | panels { room: "Dead End Room" name: "END" } |
52 | location_room: "Loose Strings Room" | 52 | location_room: "Loose Strings Room" |
53 | location_name: "Gravestone" | ||
53 | } | 54 | } |
diff --git a/data/maps/the_three_doors/rooms/Dead End Room.txtpb b/data/maps/the_three_doors/rooms/Dead End Room.txtpb index c752368..8bfe193 100644 --- a/data/maps/the_three_doors/rooms/Dead End Room.txtpb +++ b/data/maps/the_three_doors/rooms/Dead End Room.txtpb | |||
@@ -29,9 +29,15 @@ panels { | |||
29 | } | 29 | } |
30 | ports { | 30 | ports { |
31 | name: "BEGIN" | 31 | name: "BEGIN" |
32 | display_name: "Door Ways Worldport" | ||
32 | path: "Components/Warps/worldport6" | 33 | path: "Components/Warps/worldport6" |
34 | destination { x: -38 y: 0 z: 41.5 } | ||
35 | rotation: 0 | ||
33 | } | 36 | } |
34 | ports { | 37 | ports { |
35 | name: "BEGIN2" | 38 | name: "BEGIN2" |
39 | display_name: "Dead End Worldport" | ||
36 | path: "Components/Warps/worldport5" | 40 | path: "Components/Warps/worldport5" |
41 | destination { x: -38 y: 0 z: 27.5 } | ||
42 | rotation: 180 | ||
37 | } | 43 | } |
diff --git a/data/maps/the_three_doors/rooms/First Second Room.txtpb b/data/maps/the_three_doors/rooms/First Second Room.txtpb index 1bee8c7..bdf5b49 100644 --- a/data/maps/the_three_doors/rooms/First Second Room.txtpb +++ b/data/maps/the_three_doors/rooms/First Second Room.txtpb | |||
@@ -29,9 +29,15 @@ panels { | |||
29 | } | 29 | } |
30 | ports { | 30 | ports { |
31 | name: "GREAT" | 31 | name: "GREAT" |
32 | display_name: "First Worldport" | ||
32 | path: "Components/Warps/worldport" | 33 | path: "Components/Warps/worldport" |
34 | destination { x: -16 y: 0 z: 0.5 } | ||
35 | rotation: 180 | ||
33 | } | 36 | } |
34 | ports { | 37 | ports { |
35 | name: "TTD" | 38 | name: "TTD" |
39 | display_name: "Second Worldport" | ||
36 | path: "Components/Warps/worldport2" | 40 | path: "Components/Warps/worldport2" |
41 | destination { x: -16 y: 0 z: 14.5 } | ||
42 | rotation: 0 | ||
37 | } | 43 | } |
diff --git a/data/maps/the_three_doors/rooms/Loose Strings Room.txtpb b/data/maps/the_three_doors/rooms/Loose Strings Room.txtpb index 9d4430f..21e3c64 100644 --- a/data/maps/the_three_doors/rooms/Loose Strings Room.txtpb +++ b/data/maps/the_three_doors/rooms/Loose Strings Room.txtpb | |||
@@ -15,5 +15,8 @@ panels { | |||
15 | } | 15 | } |
16 | ports { | 16 | ports { |
17 | name: "BEGIN" | 17 | name: "BEGIN" |
18 | display_name: "Loose Strings Worldport" | ||
18 | path: "Components/Warps/worldport7" | 19 | path: "Components/Warps/worldport7" |
20 | destination { x: -16 y: 0 z: 41.5 } | ||
21 | rotation: 0 | ||
19 | } | 22 | } |
diff --git a/data/maps/the_three_doors/rooms/One Luck Room.txtpb b/data/maps/the_three_doors/rooms/One Luck Room.txtpb index 816b4e3..f5053be 100644 --- a/data/maps/the_three_doors/rooms/One Luck Room.txtpb +++ b/data/maps/the_three_doors/rooms/One Luck Room.txtpb | |||
@@ -15,5 +15,8 @@ panels { | |||
15 | } | 15 | } |
16 | ports { | 16 | ports { |
17 | name: "BEGIN" | 17 | name: "BEGIN" |
18 | display_name: "Lone Chance Worldport" | ||
18 | path: "Components/Warps/worldport8" | 19 | path: "Components/Warps/worldport8" |
20 | destination { x: -16 y: 0 z: 27.5 } | ||
21 | rotation: 180 | ||
19 | } | 22 | } |
diff --git a/data/maps/the_three_doors/rooms/Silver Portal Room.txtpb b/data/maps/the_three_doors/rooms/Silver Portal Room.txtpb index aeab9da..1c00045 100644 --- a/data/maps/the_three_doors/rooms/Silver Portal Room.txtpb +++ b/data/maps/the_three_doors/rooms/Silver Portal Room.txtpb | |||
@@ -27,9 +27,15 @@ panels { | |||
27 | } | 27 | } |
28 | ports { | 28 | ports { |
29 | name: "BEGIN" | 29 | name: "BEGIN" |
30 | display_name: "Third Fourth Worldport" | ||
30 | path: "Components/Warps/worldport3" | 31 | path: "Components/Warps/worldport3" |
32 | destination { x: -38 y: 0 z: 14.5 } | ||
33 | rotation: 0 | ||
31 | } | 34 | } |
32 | ports { | 35 | ports { |
33 | name: "NEXT" | 36 | name: "NEXT" |
37 | display_name: "Silver Portal Worldport" | ||
34 | path: "Components/Warps/worldport4" | 38 | path: "Components/Warps/worldport4" |
39 | destination { x: -38 y: 0 z: 0.5 } | ||
40 | rotation: 180 | ||
35 | } | 41 | } |
diff --git a/data/maps/the_tower/rooms/First Floor.txtpb b/data/maps/the_tower/rooms/First Floor.txtpb index 33398a3..7a811bf 100644 --- a/data/maps/the_tower/rooms/First Floor.txtpb +++ b/data/maps/the_tower/rooms/First Floor.txtpb | |||
@@ -97,5 +97,8 @@ panels { | |||
97 | } | 97 | } |
98 | ports { | 98 | ports { |
99 | name: "GREAT" | 99 | name: "GREAT" |
100 | display_name: "Entrance" | ||
100 | path: "Components/Warps/worldport" | 101 | path: "Components/Warps/worldport" |
102 | destination { x: -0 y: 0 z: 13 } | ||
103 | rotation: 0 | ||
101 | } | 104 | } |
diff --git a/data/maps/the_tree/doors.txtpb b/data/maps/the_tree/doors.txtpb index b62a881..6cb4086 100644 --- a/data/maps/the_tree/doors.txtpb +++ b/data/maps/the_tree/doors.txtpb | |||
@@ -38,4 +38,5 @@ doors { | |||
38 | panels { room: "Main Area" name: "SMALL (3)" } | 38 | panels { room: "Main Area" name: "SMALL (3)" } |
39 | panels { room: "Main Area" name: "SPRINKLE" } | 39 | panels { room: "Main Area" name: "SPRINKLE" } |
40 | location_room: "Main Area" | 40 | location_room: "Main Area" |
41 | location_name: "Gravestone" | ||
41 | } | 42 | } |
diff --git a/data/maps/the_tree/rooms/Bearer Entrance.txtpb b/data/maps/the_tree/rooms/Bearer Entrance.txtpb index 797e5d0..263a8e8 100644 --- a/data/maps/the_tree/rooms/Bearer Entrance.txtpb +++ b/data/maps/the_tree/rooms/Bearer Entrance.txtpb | |||
@@ -1,5 +1,8 @@ | |||
1 | name: "Bearer Entrance" | 1 | name: "Bearer Entrance" |
2 | ports { | 2 | ports { |
3 | name: "BEARER" | 3 | name: "BEARER" |
4 | display_name: "Brown Control Center Hallway" | ||
4 | path: "Components/Warps/worldport" | 5 | path: "Components/Warps/worldport" |
6 | destination { x: -15.5 y: 0 z: 20 } | ||
7 | rotation: 270 | ||
5 | } | 8 | } |
diff --git a/data/maps/the_tree/rooms/Main Area.txtpb b/data/maps/the_tree/rooms/Main Area.txtpb index b232d1e..bd22c2b 100644 --- a/data/maps/the_tree/rooms/Main Area.txtpb +++ b/data/maps/the_tree/rooms/Main Area.txtpb | |||
@@ -211,19 +211,33 @@ panels { | |||
211 | } | 211 | } |
212 | ports { | 212 | ports { |
213 | name: "UNKEMPT" | 213 | name: "UNKEMPT" |
214 | display_name: "SW Worldport" | ||
214 | path: "Components/Warps/worldport4" | 215 | path: "Components/Warps/worldport4" |
216 | destination { x: -21 y: 0 z: 7 } | ||
217 | rotation: 0 | ||
218 | # enterable from either side | ||
215 | } | 219 | } |
216 | ports { | 220 | ports { |
217 | name: "DIGITAL" | 221 | name: "DIGITAL" |
222 | display_name: "NW Worldport" | ||
218 | path: "Components/Warps/worldport5" | 223 | path: "Components/Warps/worldport5" |
224 | destination { x: -21 y: 0 z: -7 } | ||
225 | rotation: 180 | ||
226 | # enterable from either side | ||
219 | } | 227 | } |
220 | ports { | 228 | ports { |
221 | name: "GREAT" | 229 | name: "GREAT" |
230 | display_name: "E Worldport" | ||
222 | path: "Components/Warps/worldport2" | 231 | path: "Components/Warps/worldport2" |
232 | destination { x: 21 y: 0 z: -4 } | ||
233 | rotation: 180 | ||
223 | } | 234 | } |
224 | ports { | 235 | ports { |
225 | name: "DAEDALUS" | 236 | name: "DAEDALUS" |
237 | display_name: "NE Worldport" | ||
226 | path: "Components/Warps/worldport3" | 238 | path: "Components/Warps/worldport3" |
239 | destination { x: 15.5 y: 0 z: -19 } | ||
240 | rotation: 90 | ||
227 | } | 241 | } |
228 | paintings { | 242 | paintings { |
229 | name: "SEA" | 243 | name: "SEA" |
diff --git a/data/maps/the_unkempt/connections.txtpb b/data/maps/the_unkempt/connections.txtpb index a9e30db..d4a046c 100644 --- a/data/maps/the_unkempt/connections.txtpb +++ b/data/maps/the_unkempt/connections.txtpb | |||
@@ -1,7 +1,7 @@ | |||
1 | connections { | 1 | connections { |
2 | from_room: "Main Area" | 2 | from_room: "Main Area" |
3 | to_room: "Right Area" | 3 | to_room: "Right Area" |
4 | door { name: "Right Door" } | 4 | door { name: "East Door" } |
5 | } | 5 | } |
6 | connections { | 6 | connections { |
7 | from_room: "Middle Room" | 7 | from_room: "Middle Room" |
diff --git a/data/maps/the_unkempt/doors.txtpb b/data/maps/the_unkempt/doors.txtpb index 5c16ac0..29065ec 100644 --- a/data/maps/the_unkempt/doors.txtpb +++ b/data/maps/the_unkempt/doors.txtpb | |||
@@ -1,5 +1,5 @@ | |||
1 | doors { | 1 | doors { |
2 | name: "Right Door" | 2 | name: "East Door" |
3 | type: STANDARD | 3 | type: STANDARD |
4 | receivers: "Components/Doors/entry_2" | 4 | receivers: "Components/Doors/entry_2" |
5 | panels { room: "Main Area" name: "EYE" } | 5 | panels { room: "Main Area" name: "EYE" } |
@@ -21,7 +21,8 @@ doors { | |||
21 | doors { | 21 | doors { |
22 | name: "Cyan Doors" | 22 | name: "Cyan Doors" |
23 | type: EVENT | 23 | type: EVENT |
24 | switches: "double_letters" | 24 | receivers: "Components/Doors/entry_12" |
25 | double_letters: true | ||
25 | } | 26 | } |
26 | doors { | 27 | doors { |
27 | name: "Sun Temple Entrance" | 28 | name: "Sun Temple Entrance" |
@@ -65,8 +66,11 @@ doors { | |||
65 | doors { | 66 | doors { |
66 | name: "Control Center Orange Door" | 67 | name: "Control Center Orange Door" |
67 | type: CONTROL_CENTER_COLOR | 68 | type: CONTROL_CENTER_COLOR |
69 | receivers: "Components/Doors/entry_6" | ||
68 | receivers: "Components/Doors/entry_13" | 70 | receivers: "Components/Doors/entry_13" |
71 | receivers: "Panels/Assorted/panel_1/teleportListener" | ||
69 | control_center_color: "orange" | 72 | control_center_color: "orange" |
73 | double_letters: true | ||
70 | } | 74 | } |
71 | doors { | 75 | doors { |
72 | name: "W2 Door" | 76 | name: "W2 Door" |
diff --git a/data/maps/the_unkempt/rooms/Control Center Entrance.txtpb b/data/maps/the_unkempt/rooms/Control Center Entrance.txtpb index e8fa13a..847b8ad 100644 --- a/data/maps/the_unkempt/rooms/Control Center Entrance.txtpb +++ b/data/maps/the_unkempt/rooms/Control Center Entrance.txtpb | |||
@@ -8,5 +8,10 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "CC" | 10 | name: "CC" |
11 | display_name: "Control Center Connector" | ||
11 | path: "Components/Warps/worldport2" | 12 | path: "Components/Warps/worldport2" |
13 | destination { x: -4.5 y: 0 z: 7 } | ||
14 | rotation: 0 | ||
15 | # TODO: shuffle entrances with dependent keyholders | ||
16 | no_shuffle: true | ||
12 | } | 17 | } |
diff --git a/data/maps/the_unkempt/rooms/Daedalus Entrance.txtpb b/data/maps/the_unkempt/rooms/Daedalus Entrance.txtpb index 851c863..f20d2cf 100644 --- a/data/maps/the_unkempt/rooms/Daedalus Entrance.txtpb +++ b/data/maps/the_unkempt/rooms/Daedalus Entrance.txtpb | |||
@@ -1,5 +1,8 @@ | |||
1 | name: "Daedalus Entrance" | 1 | name: "Daedalus Entrance" |
2 | ports { | 2 | ports { |
3 | name: "DAEDALUS" | 3 | name: "DAEDALUS" |
4 | display_name: "Orange Hallway" | ||
4 | path: "Components/Warps/worldport4" | 5 | path: "Components/Warps/worldport4" |
6 | destination { x: 33 y: 0 z: -10 } | ||
7 | rotation: 90 | ||
5 | } | 8 | } |
diff --git a/data/maps/the_unkempt/rooms/Main Area.txtpb b/data/maps/the_unkempt/rooms/Main Area.txtpb index ed3ce21..f98220d 100644 --- a/data/maps/the_unkempt/rooms/Main Area.txtpb +++ b/data/maps/the_unkempt/rooms/Main Area.txtpb | |||
@@ -212,17 +212,27 @@ panels { | |||
212 | keyholders { | 212 | keyholders { |
213 | name: "I" | 213 | name: "I" |
214 | path: "Components/KeyHolders/keyHolderL" | 214 | path: "Components/KeyHolders/keyHolderL" |
215 | key: "i" | ||
215 | } | 216 | } |
216 | ports { | 217 | ports { |
217 | name: "GREAT" | 218 | name: "GREAT" |
219 | display_name: "Main Entrance" | ||
218 | path: "Components/Warps/worldport" | 220 | path: "Components/Warps/worldport" |
221 | destination { x: -3 y: 0 z: 11 } | ||
222 | rotation: 270 | ||
219 | } | 223 | } |
220 | ports { | 224 | ports { |
221 | name: "TREE" | 225 | name: "TREE" |
226 | display_name: "Brown Hallway" | ||
222 | path: "Components/Warps/worldport5" | 227 | path: "Components/Warps/worldport5" |
228 | destination { x: -34 y: 0 z: 7 } | ||
229 | rotation: 270 | ||
223 | } | 230 | } |
224 | ports { | 231 | ports { |
225 | name: "SUNTEMPLE" | 232 | name: "SUNTEMPLE" |
233 | display_name: "Sun Temple Entrance" | ||
226 | path: "Components/Warps/worldport3" | 234 | path: "Components/Warps/worldport3" |
235 | destination { x: -42 y: 0 z: -2 } | ||
236 | rotation: 270 | ||
227 | required_door { name: "Sun Temple Entrance" } | 237 | required_door { name: "Sun Temple Entrance" } |
228 | } | 238 | } |
diff --git a/data/maps/the_unkempt/rooms/Right Area.txtpb b/data/maps/the_unkempt/rooms/Right Area.txtpb index 1475fb0..03d7cea 100644 --- a/data/maps/the_unkempt/rooms/Right Area.txtpb +++ b/data/maps/the_unkempt/rooms/Right Area.txtpb | |||
@@ -159,6 +159,5 @@ panels { | |||
159 | clue: "color" | 159 | clue: "color" |
160 | answer: "orange" | 160 | answer: "orange" |
161 | symbols: EXAMPLE | 161 | symbols: EXAMPLE |
162 | # TODO: This is hidden in-game until double letters are unlocked AND "orange" | 162 | required_door { name: "Control Center Orange Door" } |
163 | # is entered in the control center. | ||
164 | } | 163 | } |
diff --git a/data/maps/the_unkempt/rooms/V Keyholder.txtpb b/data/maps/the_unkempt/rooms/V Keyholder.txtpb index a7ec93f..8a4941d 100644 --- a/data/maps/the_unkempt/rooms/V Keyholder.txtpb +++ b/data/maps/the_unkempt/rooms/V Keyholder.txtpb | |||
@@ -1,5 +1,6 @@ | |||
1 | name: "V Keyholder" | 1 | name: "V Keyholder" |
2 | keyholders { | 2 | keyholders { |
3 | name: "KEYHOLDERV" | 3 | name: "V" |
4 | path: "Components/KeyHolders/keyHolderV" | 4 | path: "Components/KeyHolders/keyHolderV" |
5 | key: "v" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_unkempt/rooms/W Keyholder.txtpb b/data/maps/the_unkempt/rooms/W Keyholder.txtpb index ae367b2..e16f997 100644 --- a/data/maps/the_unkempt/rooms/W Keyholder.txtpb +++ b/data/maps/the_unkempt/rooms/W Keyholder.txtpb | |||
@@ -2,4 +2,5 @@ name: "W Keyholder" | |||
2 | keyholders { | 2 | keyholders { |
3 | name: "W" | 3 | name: "W" |
4 | path: "Components/KeyHolders/keyHolderW" | 4 | path: "Components/KeyHolders/keyHolderW" |
5 | key: "w" | ||
5 | } | 6 | } |
diff --git a/data/maps/the_unyielding/doors.txtpb b/data/maps/the_unyielding/doors.txtpb index b969c0b..a3c3999 100644 --- a/data/maps/the_unyielding/doors.txtpb +++ b/data/maps/the_unyielding/doors.txtpb | |||
@@ -183,6 +183,21 @@ doors { | |||
183 | panels { room: "Central Connected Area" name: "CHIN" } | 183 | panels { room: "Central Connected Area" name: "CHIN" } |
184 | panels { room: "Central Connected Area" name: "DING" } | 184 | panels { room: "Central Connected Area" name: "DING" } |
185 | location_room: "Central Connected Area" | 185 | location_room: "Central Connected Area" |
186 | location_name: "East Room 2" | ||
187 | } | ||
188 | doors { | ||
189 | name: "East Room 1" | ||
190 | type: LOCATION_ONLY | ||
191 | panels { room: "East Room 1" name: "CHIN" } | ||
192 | panels { room: "East Room 1" name: "HEAT" } | ||
193 | panels { room: "East Room 1" name: "END" } | ||
194 | panels { room: "East Room 1" name: "FLY" } | ||
195 | panels { room: "East Room 1" name: "OUCH" } | ||
196 | panels { room: "East Room 1" name: "HAG" } | ||
197 | panels { room: "East Room 1" name: "TIN" } | ||
198 | panels { room: "East Room 1" name: "RID" } | ||
199 | panels { room: "East Room 1" name: "TUG" } | ||
200 | location_room: "East Room 1" | ||
186 | } | 201 | } |
187 | doors { | 202 | doors { |
188 | name: "Orange Alcove" | 203 | name: "Orange Alcove" |
@@ -199,6 +214,7 @@ doors { | |||
199 | } | 214 | } |
200 | doors { | 215 | doors { |
201 | name: "Black Alcove" | 216 | name: "Black Alcove" |
217 | type: EVENT | ||
202 | panels { room: "Star Rooms" name: "TURN" } | 218 | panels { room: "Star Rooms" name: "TURN" } |
203 | panels { room: "Central Connected Area" name: "HAD" } | 219 | panels { room: "Central Connected Area" name: "HAD" } |
204 | panels { room: "Central Connected Area" name: "SOW" } | 220 | panels { room: "Central Connected Area" name: "SOW" } |
@@ -218,6 +234,7 @@ doors { | |||
218 | panels { room: "Northeast Room 1" name: "CAR" } | 234 | panels { room: "Northeast Room 1" name: "CAR" } |
219 | panels { room: "Northeast Room 1" name: "SIR" } | 235 | panels { room: "Northeast Room 1" name: "SIR" } |
220 | location_room: "Northeast Room 1" | 236 | location_room: "Northeast Room 1" |
237 | location_name: "Northeast Room 1" | ||
221 | } | 238 | } |
222 | doors { | 239 | doors { |
223 | name: "Northeast Corner Behind" | 240 | name: "Northeast Corner Behind" |
@@ -245,6 +262,7 @@ doors { | |||
245 | panels { room: "Northwest Room" name: "HER" } | 262 | panels { room: "Northwest Room" name: "HER" } |
246 | panels { room: "Northwest Room" name: "DAM" } | 263 | panels { room: "Northwest Room" name: "DAM" } |
247 | location_room: "Northwest Room" | 264 | location_room: "Northwest Room" |
265 | location_name: "Northwest Room" | ||
248 | } | 266 | } |
249 | doors { | 267 | doors { |
250 | name: "Cyan Alcove" | 268 | name: "Cyan Alcove" |
@@ -274,6 +292,7 @@ doors { | |||
274 | panels { room: "Southwest Room 3" name: "HOST" } | 292 | panels { room: "Southwest Room 3" name: "HOST" } |
275 | panels { room: "Southwest Room 3" name: "MUG" } | 293 | panels { room: "Southwest Room 3" name: "MUG" } |
276 | location_room: "Southwest Room 3" | 294 | location_room: "Southwest Room 3" |
295 | location_name: "Southwest Room 3" | ||
277 | } | 296 | } |
278 | doors { | 297 | doors { |
279 | name: "Southwest Room 2 Entrance" | 298 | name: "Southwest Room 2 Entrance" |
@@ -293,6 +312,7 @@ doors { | |||
293 | panels { room: "Southwest Room 2" name: "ION" } | 312 | panels { room: "Southwest Room 2" name: "ION" } |
294 | panels { room: "Southwest Room 2" name: "INN" } | 313 | panels { room: "Southwest Room 2" name: "INN" } |
295 | location_room: "Southwest Room 2" | 314 | location_room: "Southwest Room 2" |
315 | location_name: "Southwest Room 2" | ||
296 | } | 316 | } |
297 | doors { | 317 | doors { |
298 | name: "Southwest 4" | 318 | name: "Southwest 4" |
@@ -411,6 +431,7 @@ doors { | |||
411 | panels { room: "Central Connected Area" name: "SON (1)" } | 431 | panels { room: "Central Connected Area" name: "SON (1)" } |
412 | panels { room: "Central Connected Area" name: "URGE" } | 432 | panels { room: "Central Connected Area" name: "URGE" } |
413 | location_room: "Central Connected Area" | 433 | location_room: "Central Connected Area" |
434 | location_name: "Northeast Room 2" | ||
414 | } | 435 | } |
415 | doors { | 436 | doors { |
416 | name: "South Right Painting" | 437 | name: "South Right Painting" |
@@ -478,5 +499,8 @@ doors { | |||
478 | doors { | 499 | doors { |
479 | name: "Cyan Doors" | 500 | name: "Cyan Doors" |
480 | type: EVENT | 501 | type: EVENT |
481 | switches: "double_letters" | 502 | receivers: "Components/Doors/entry_4" |
503 | receivers: "Panels/Miscellaneous/entry_2/teleportListener" | ||
504 | receivers: "Panels/Miscellaneous/entry_3/teleportListener" | ||
505 | double_letters: true | ||
482 | } | 506 | } |
diff --git a/data/maps/the_unyielding/rooms/Bearer Entrance.txtpb b/data/maps/the_unyielding/rooms/Bearer Entrance.txtpb index 4c1440f..6ce69da 100644 --- a/data/maps/the_unyielding/rooms/Bearer Entrance.txtpb +++ b/data/maps/the_unyielding/rooms/Bearer Entrance.txtpb | |||
@@ -1,5 +1,8 @@ | |||
1 | name: "Bearer Entrance" | 1 | name: "Bearer Entrance" |
2 | ports { | 2 | ports { |
3 | name: "BEARER" | 3 | name: "BEARER" |
4 | display_name: "East of Yellow Worldport" | ||
4 | path: "Components/Warps/worldport4" | 5 | path: "Components/Warps/worldport4" |
6 | destination { x: 23 y: 0 z: -29 } | ||
7 | rotation: 90 | ||
5 | } | 8 | } |
diff --git a/data/maps/the_unyielding/rooms/Digital Entrance.txtpb b/data/maps/the_unyielding/rooms/Digital Entrance.txtpb index 74665a2..853c5f0 100644 --- a/data/maps/the_unyielding/rooms/Digital Entrance.txtpb +++ b/data/maps/the_unyielding/rooms/Digital Entrance.txtpb | |||
@@ -8,5 +8,8 @@ panels { | |||
8 | } | 8 | } |
9 | ports { | 9 | ports { |
10 | name: "DIGITAL" | 10 | name: "DIGITAL" |
11 | display_name: "South of Yellow Worldport" | ||
11 | path: "Components/Warps/worldport" | 12 | path: "Components/Warps/worldport" |
13 | destination { x: 0 y: 0 z: 0 } | ||
14 | rotation: 0 | ||
12 | } | 15 | } |
diff --git a/data/maps/the_unyielding/rooms/Nuanced Entrance.txtpb b/data/maps/the_unyielding/rooms/Nuanced Entrance.txtpb index f011b32..454dc3f 100644 --- a/data/maps/the_unyielding/rooms/Nuanced Entrance.txtpb +++ b/data/maps/the_unyielding/rooms/Nuanced Entrance.txtpb | |||
@@ -1,5 +1,8 @@ | |||
1 | name: "Nuanced Entrance" | 1 | name: "Nuanced Entrance" |
2 | ports { | 2 | ports { |
3 | name: "NUANCED" | 3 | name: "NUANCED" |
4 | display_name: "West of Yellow Worldport" | ||
4 | path: "Components/Warps/worldport3" | 5 | path: "Components/Warps/worldport3" |
6 | destination { x: -23 y: 0 z: -29 } | ||
7 | rotation: 270 | ||
5 | } | 8 | } |
diff --git a/data/maps/the_unyielding/rooms/Plaza Entrance.txtpb b/data/maps/the_unyielding/rooms/Plaza Entrance.txtpb index 0bc60a7..f866d87 100644 --- a/data/maps/the_unyielding/rooms/Plaza Entrance.txtpb +++ b/data/maps/the_unyielding/rooms/Plaza Entrance.txtpb | |||
@@ -15,5 +15,8 @@ panels { | |||
15 | } | 15 | } |
16 | ports { | 16 | ports { |
17 | name: "PLAZA" | 17 | name: "PLAZA" |
18 | display_name: "Dark Hallway" | ||
18 | path: "Components/Warps/worldport5" | 19 | path: "Components/Warps/worldport5" |
20 | destination { x: 35 y: 0 z: 44 } | ||
21 | rotation: 270 | ||
19 | } | 22 | } |
diff --git a/data/maps/the_unyielding/rooms/Yellow Left.txtpb b/data/maps/the_unyielding/rooms/Yellow Left.txtpb index 9c7d023..192d901 100644 --- a/data/maps/the_unyielding/rooms/Yellow Left.txtpb +++ b/data/maps/the_unyielding/rooms/Yellow Left.txtpb | |||
@@ -5,4 +5,5 @@ panels { | |||
5 | clue: "sickness" | 5 | clue: "sickness" |
6 | answer: "health" | 6 | answer: "health" |
7 | symbols: SUN | 7 | symbols: SUN |
8 | required_door { name: "Cyan Doors" } | ||
8 | } | 9 | } |
diff --git a/data/maps/the_unyielding/rooms/Yellow Right.txtpb b/data/maps/the_unyielding/rooms/Yellow Right.txtpb index 0599f29..d554c73 100644 --- a/data/maps/the_unyielding/rooms/Yellow Right.txtpb +++ b/data/maps/the_unyielding/rooms/Yellow Right.txtpb | |||
@@ -5,4 +5,5 @@ panels { | |||
5 | clue: "health" | 5 | clue: "health" |
6 | answer: "sickness" | 6 | answer: "sickness" |
7 | symbols: SUN | 7 | symbols: SUN |
8 | required_door { name: "Cyan Doors" } | ||
8 | } | 9 | } |
diff --git a/data/maps/the_wondrous/rooms/Entry.txtpb b/data/maps/the_wondrous/rooms/Entry.txtpb index e15f75c..543d193 100644 --- a/data/maps/the_wondrous/rooms/Entry.txtpb +++ b/data/maps/the_wondrous/rooms/Entry.txtpb | |||
@@ -7,5 +7,8 @@ panels { | |||
7 | } | 7 | } |
8 | ports { | 8 | ports { |
9 | name: "DAEDALUS" | 9 | name: "DAEDALUS" |
10 | display_name: "Entrance" | ||
10 | path: "Components/Warps/worldport" | 11 | path: "Components/Warps/worldport" |
12 | destination { x: 18 y: 0 z: 41 } | ||
13 | rotation: 180 | ||
11 | } | 14 | } |
diff --git a/data/maps/the_wondrous/rooms/Huge.txtpb b/data/maps/the_wondrous/rooms/Huge.txtpb index c4425e7..6ca6ef8 100644 --- a/data/maps/the_wondrous/rooms/Huge.txtpb +++ b/data/maps/the_wondrous/rooms/Huge.txtpb | |||
@@ -4,6 +4,7 @@ panels { | |||
4 | path: "Panels/panel_3" | 4 | path: "Panels/panel_3" |
5 | clue: "shrink" | 5 | clue: "shrink" |
6 | answer: "shrink" | 6 | answer: "shrink" |
7 | display_name: "SHRINK (2)" | ||
7 | } | 8 | } |
8 | panels { | 9 | panels { |
9 | name: "IRE" | 10 | name: "IRE" |
diff --git a/data/maps/the_wondrous/rooms/Regular.txtpb b/data/maps/the_wondrous/rooms/Regular.txtpb index bd167d3..65df029 100644 --- a/data/maps/the_wondrous/rooms/Regular.txtpb +++ b/data/maps/the_wondrous/rooms/Regular.txtpb | |||
@@ -4,4 +4,5 @@ panels { | |||
4 | path: "Panels/panel_2" | 4 | path: "Panels/panel_2" |
5 | clue: "shrink" | 5 | clue: "shrink" |
6 | answer: "shrink" | 6 | answer: "shrink" |
7 | display_name: "SHRINK (1)" | ||
7 | } | 8 | } |
diff --git a/data/maps/the_words/rooms/Main Area.txtpb b/data/maps/the_words/rooms/Main Area.txtpb index 503408c..ae57252 100644 --- a/data/maps/the_words/rooms/Main Area.txtpb +++ b/data/maps/the_words/rooms/Main Area.txtpb | |||
@@ -57,5 +57,8 @@ panels { | |||
57 | } | 57 | } |
58 | ports { | 58 | ports { |
59 | name: "ENTRY" | 59 | name: "ENTRY" |
60 | display_name: "Worldport" | ||
60 | path: "Components/Warps/worldport" | 61 | path: "Components/Warps/worldport" |
62 | destination { x: 0 y: 0 z: 9.5 } | ||
63 | rotation: 0 | ||
61 | } | 64 | } |
diff --git a/data/metadata.txtpb b/data/metadata.txtpb new file mode 100644 index 0000000..c5c48c2 --- /dev/null +++ b/data/metadata.txtpb | |||
@@ -0,0 +1,54 @@ | |||
1 | version { | ||
2 | major: 7 | ||
3 | minor: 1 | ||
4 | patch: 0 | ||
5 | } | ||
6 | # Filler item. | ||
7 | special_names: "A Job Well Done" | ||
8 | # Symbol items. | ||
9 | special_names: "Age Symbol" | ||
10 | special_names: "Anagram Symbol" | ||
11 | special_names: "Boxes Symbol" | ||
12 | special_names: "Cross Symbol" | ||
13 | special_names: "Eval Symbol" | ||
14 | special_names: "Example Symbol" | ||
15 | special_names: "Gender Symbol" | ||
16 | special_names: "Job Symbol" | ||
17 | special_names: "Lingo Symbol" | ||
18 | special_names: "Null Symbol" | ||
19 | special_names: "Planet Symbol" | ||
20 | special_names: "Pyramid Symbol" | ||
21 | special_names: "Question Symbol" | ||
22 | special_names: "Sound Symbol" | ||
23 | special_names: "Sparkles Symbol" | ||
24 | special_names: "Stars Symbol" | ||
25 | special_names: "Sun Symbol" | ||
26 | special_names: "Sweet Symbol" | ||
27 | special_names: "Zero Symbol" | ||
28 | # Anti collectable traps | ||
29 | special_names: "Anti A" | ||
30 | special_names: "Anti B" | ||
31 | special_names: "Anti C" | ||
32 | special_names: "Anti D" | ||
33 | special_names: "Anti E" | ||
34 | special_names: "Anti F" | ||
35 | special_names: "Anti G" | ||
36 | special_names: "Anti H" | ||
37 | special_names: "Anti I" | ||
38 | special_names: "Anti J" | ||
39 | special_names: "Anti K" | ||
40 | special_names: "Anti L" | ||
41 | special_names: "Anti M" | ||
42 | special_names: "Anti N" | ||
43 | special_names: "Anti O" | ||
44 | special_names: "Anti P" | ||
45 | special_names: "Anti Q" | ||
46 | special_names: "Anti R" | ||
47 | special_names: "Anti S" | ||
48 | special_names: "Anti T" | ||
49 | special_names: "Anti U" | ||
50 | special_names: "Anti V" | ||
51 | special_names: "Anti W" | ||
52 | special_names: "Anti X" | ||
53 | special_names: "Anti Y" | ||
54 | special_names: "Anti Z" | ||
diff --git a/data/progressives.txtpb b/data/progressives.txtpb new file mode 100644 index 0000000..0eba2bf --- /dev/null +++ b/data/progressives.txtpb | |||
@@ -0,0 +1,11 @@ | |||
1 | progressives { | ||
2 | name: "Progressive Gold Ending" | ||
3 | doors { map: "daedalus" name: "Red Rainbow Room" } | ||
4 | doors { map: "daedalus" name: "Orange Rainbow Room" } | ||
5 | doors { map: "daedalus" name: "Yellow Rainbow Room" } | ||
6 | doors { map: "daedalus" name: "Green Rainbow Room" } | ||
7 | doors { map: "daedalus" name: "Blue Rainbow Room" } | ||
8 | doors { map: "daedalus" name: "Purple Rainbow Room" } | ||
9 | doors { map: "daedalus" name: "Cyan Rainbow Room" } | ||
10 | doors { map: "daedalus" name: "Brown Rainbow Room" } | ||
11 | } | ||
diff --git a/proto/data.proto b/proto/data.proto index 211a7ac..d79f47d 100644 --- a/proto/data.proto +++ b/proto/data.proto | |||
@@ -27,6 +27,29 @@ enum DoorType { | |||
27 | 27 | ||
28 | // This door is an item if gravestone shuffle is enabled, and is a location as long as panelsanity is not on. | 28 | // This door is an item if gravestone shuffle is enabled, and is a location as long as panelsanity is not on. |
29 | GRAVESTONE = 6; | 29 | GRAVESTONE = 6; |
30 | |||
31 | // This door is never a location, and is an item as long as gallery painting shuffle is on. | ||
32 | GALLERY_PAINTING = 7; | ||
33 | } | ||
34 | |||
35 | enum DoorGroupType { | ||
36 | DOOR_GROUP_TYPE_UNKNOWN = 0; | ||
37 | |||
38 | // These doors border a worldport. They should be grouped when connections are | ||
39 | // not shuffled. | ||
40 | CONNECTOR = 1; | ||
41 | |||
42 | // Similar to CONNECTOR, but these doors are also ordinarily opened by solving | ||
43 | // the COLOR panel in the Control Center. These should be grouped when | ||
44 | // connections are not shuffled, but are not items at all when control center | ||
45 | // colors are not shuffled. | ||
46 | COLOR_CONNECTOR = 2; | ||
47 | |||
48 | // Groups with this type become an item if cyan door behavior is set to item. | ||
49 | CYAN_DOORS = 3; | ||
50 | |||
51 | // Groups with this type always become an item if door shuffle is on. | ||
52 | SHUFFLE_GROUP = 4; | ||
30 | } | 53 | } |
31 | 54 | ||
32 | enum AxisDirection { | 55 | enum AxisDirection { |
@@ -64,6 +87,18 @@ enum PuzzleSymbol { | |||
64 | QUESTION = 19; | 87 | QUESTION = 19; |
65 | } | 88 | } |
66 | 89 | ||
90 | message Vec3d { | ||
91 | optional double x = 1; | ||
92 | optional double y = 2; | ||
93 | optional double z = 3; | ||
94 | } | ||
95 | |||
96 | message VersionNumber { | ||
97 | optional uint64 major = 1; | ||
98 | optional uint64 minor = 2; | ||
99 | optional uint64 patch = 3; | ||
100 | } | ||
101 | |||
67 | message ProxyIdentifier { | 102 | message ProxyIdentifier { |
68 | optional uint64 panel = 1; | 103 | optional uint64 panel = 1; |
69 | optional string answer = 2; | 104 | optional string answer = 2; |
@@ -84,6 +119,11 @@ message Connection { | |||
84 | uint64 painting = 5; | 119 | uint64 painting = 5; |
85 | ProxyIdentifier panel = 6; | 120 | ProxyIdentifier panel = 6; |
86 | } | 121 | } |
122 | |||
123 | optional bool roof_access = 7; | ||
124 | optional bool purple_ending = 8; | ||
125 | optional bool cyan_ending = 9; | ||
126 | optional bool vanilla_only = 10; | ||
87 | } | 127 | } |
88 | 128 | ||
89 | message Door { | 129 | message Door { |
@@ -100,13 +140,16 @@ message Door { | |||
100 | optional uint64 complete_at = 12; | 140 | optional uint64 complete_at = 12; |
101 | 141 | ||
102 | optional string control_center_color = 6; | 142 | optional string control_center_color = 6; |
103 | repeated string switches = 7; | ||
104 | repeated KeyholderAnswer keyholders = 13; | 143 | repeated KeyholderAnswer keyholders = 13; |
105 | repeated uint64 rooms = 14; | 144 | repeated uint64 rooms = 14; |
106 | repeated uint64 doors = 15; | 145 | repeated uint64 doors = 15; |
107 | repeated uint64 endings = 16; | 146 | repeated uint64 endings = 16; |
147 | optional bool double_letters = 18; | ||
148 | repeated string senders = 19; | ||
108 | 149 | ||
109 | optional DoorType type = 8; | 150 | optional DoorType type = 8; |
151 | |||
152 | optional string location_name = 17; | ||
110 | } | 153 | } |
111 | 154 | ||
112 | message PanelData { | 155 | message PanelData { |
@@ -124,9 +167,11 @@ message PanelData { | |||
124 | 167 | ||
125 | optional uint64 required_door = 9; | 168 | optional uint64 required_door = 9; |
126 | optional uint64 required_room = 11; | 169 | optional uint64 required_room = 11; |
170 | |||
171 | optional string display_name = 12; | ||
127 | } | 172 | } |
128 | 173 | ||
129 | message Painting { | 174 | message PaintingData { |
130 | optional uint64 id = 1; | 175 | optional uint64 id = 1; |
131 | optional uint64 room_id = 2; | 176 | optional uint64 room_id = 2; |
132 | optional string name = 9; | 177 | optional string name = 9; |
@@ -148,19 +193,24 @@ message Port { | |||
148 | optional uint64 room_id = 2; | 193 | optional uint64 room_id = 2; |
149 | optional string name = 3; | 194 | optional string name = 3; |
150 | 195 | ||
196 | optional string display_name = 10; | ||
151 | optional string path = 4; | 197 | optional string path = 4; |
152 | optional string orientation = 5; | 198 | optional Vec3d destination = 5; |
199 | optional double rotation = 8; | ||
153 | optional AxisDirection gravity = 7; | 200 | optional AxisDirection gravity = 7; |
201 | optional bool no_shuffle = 9; | ||
154 | 202 | ||
155 | optional uint64 required_door = 6; | 203 | optional uint64 required_door = 6; |
156 | } | 204 | } |
157 | 205 | ||
158 | message Keyholder { | 206 | message KeyholderData { |
159 | optional uint64 id = 1; | 207 | optional uint64 id = 1; |
208 | optional uint64 ap_id = 6; | ||
160 | optional uint64 room_id = 2; | 209 | optional uint64 room_id = 2; |
161 | 210 | ||
162 | optional string name = 3; | 211 | optional string name = 3; |
163 | optional string path = 4; | 212 | optional string path = 4; |
213 | optional string key = 5; | ||
164 | } | 214 | } |
165 | 215 | ||
166 | message Letter { | 216 | message Letter { |
@@ -198,6 +248,7 @@ message Room { | |||
198 | optional uint64 map_id = 8; | 248 | optional uint64 map_id = 8; |
199 | optional string name = 2; | 249 | optional string name = 2; |
200 | optional string display_name = 3; | 250 | optional string display_name = 3; |
251 | optional string panel_display_name = 13; | ||
201 | 252 | ||
202 | repeated uint64 panels = 4; | 253 | repeated uint64 panels = 4; |
203 | repeated uint64 paintings = 5; | 254 | repeated uint64 paintings = 5; |
@@ -215,17 +266,36 @@ message Map { | |||
215 | optional string display_name = 3; | 266 | optional string display_name = 3; |
216 | } | 267 | } |
217 | 268 | ||
269 | message Progressive { | ||
270 | optional uint64 id = 1; | ||
271 | optional string name = 2; | ||
272 | optional uint64 ap_id = 3; | ||
273 | repeated uint64 doors = 4; | ||
274 | } | ||
275 | |||
276 | message DoorGroup { | ||
277 | optional uint64 id = 1; | ||
278 | optional string name = 2; | ||
279 | optional uint64 ap_id = 3; | ||
280 | optional DoorGroupType type = 4; | ||
281 | repeated uint64 doors = 5; | ||
282 | } | ||
283 | |||
218 | message AllObjects { | 284 | message AllObjects { |
285 | optional VersionNumber version = 15; | ||
286 | |||
219 | repeated Map maps = 7; | 287 | repeated Map maps = 7; |
220 | repeated Room rooms = 1; | 288 | repeated Room rooms = 1; |
221 | repeated Door doors = 2; | 289 | repeated Door doors = 2; |
222 | repeated PanelData panels = 3; | 290 | repeated PanelData panels = 3; |
223 | repeated Painting paintings = 4; | 291 | repeated PaintingData paintings = 4; |
224 | repeated Port ports = 5; | 292 | repeated Port ports = 5; |
225 | repeated Keyholder keyholders = 11; | 293 | repeated KeyholderData keyholders = 11; |
226 | repeated Letter letters = 9; | 294 | repeated Letter letters = 9; |
227 | repeated Mastery masteries = 10; | 295 | repeated Mastery masteries = 10; |
228 | repeated Ending endings = 12; | 296 | repeated Ending endings = 12; |
229 | repeated Connection connections = 6; | 297 | repeated Connection connections = 6; |
298 | repeated Progressive progressives = 13; | ||
299 | repeated DoorGroup door_groups = 14; | ||
230 | map<string, uint64> special_ids = 8; | 300 | map<string, uint64> special_ids = 8; |
231 | } | 301 | } |
diff --git a/proto/human.proto b/proto/human.proto index 1a15c59..8e7767a 100644 --- a/proto/human.proto +++ b/proto/human.proto | |||
@@ -62,6 +62,25 @@ message HumanConnection { | |||
62 | 62 | ||
63 | optional bool oneway = 3; | 63 | optional bool oneway = 3; |
64 | optional DoorIdentifier door = 4; | 64 | optional DoorIdentifier door = 4; |
65 | |||
66 | // If true, this connection will only be logically allowed if the Daedalus | ||
67 | // Roof Access option is enabled. | ||
68 | optional bool roof_access = 7; | ||
69 | |||
70 | // This means that the connection intentionally skips the target object's | ||
71 | // required door. | ||
72 | optional bool bypass_target_door = 8; | ||
73 | |||
74 | // This means that the connection should additionally require all purple | ||
75 | // letters when the Strict Purple Ending option is on. | ||
76 | optional bool purple_ending = 9; | ||
77 | |||
78 | // This means that the connection should additionally require all cyan letters | ||
79 | // when the Strict Cyan Ending option is on. | ||
80 | optional bool cyan_ending = 10; | ||
81 | |||
82 | // This means that the connection only exists when doors are not shuffled. | ||
83 | optional bool vanilla_only = 11; | ||
65 | } | 84 | } |
66 | 85 | ||
67 | message HumanConnections { | 86 | message HumanConnections { |
@@ -82,14 +101,19 @@ message HumanDoor { | |||
82 | optional uint64 complete_at = 9; | 101 | optional uint64 complete_at = 9; |
83 | 102 | ||
84 | optional string control_center_color = 6; | 103 | optional string control_center_color = 6; |
85 | repeated string switches = 7; | ||
86 | repeated KeyholderIdentifier keyholders = 10; | 104 | repeated KeyholderIdentifier keyholders = 10; |
87 | repeated RoomIdentifier rooms = 11; | 105 | repeated RoomIdentifier rooms = 11; |
88 | repeated DoorIdentifier doors = 12; | 106 | repeated DoorIdentifier doors = 12; |
89 | repeated string endings = 13; | 107 | repeated string endings = 13; |
108 | optional bool double_letters = 15; | ||
109 | |||
110 | // Sender nodes to be added to the list of requirements for triggering the | ||
111 | // location. Only for senders that have no logic requirements. | ||
112 | repeated string senders = 16; | ||
90 | 113 | ||
91 | optional DoorType type = 4; | 114 | optional DoorType type = 4; |
92 | optional string location_room = 5; | 115 | optional string location_room = 5; |
116 | optional string location_name = 14; | ||
93 | } | 117 | } |
94 | 118 | ||
95 | message HumanDoors { | 119 | message HumanDoors { |
@@ -108,6 +132,8 @@ message HumanPanel { | |||
108 | 132 | ||
109 | optional DoorIdentifier required_door = 7; | 133 | optional DoorIdentifier required_door = 7; |
110 | optional RoomIdentifier required_room = 8; | 134 | optional RoomIdentifier required_room = 8; |
135 | |||
136 | optional string display_name = 9; | ||
111 | } | 137 | } |
112 | 138 | ||
113 | message HumanPainting { | 139 | message HumanPainting { |
@@ -127,9 +153,16 @@ message HumanPainting { | |||
127 | 153 | ||
128 | message HumanPort { | 154 | message HumanPort { |
129 | optional string name = 1; | 155 | optional string name = 1; |
156 | optional string display_name = 8; | ||
130 | optional string path = 2; | 157 | optional string path = 2; |
131 | 158 | ||
132 | optional string orientation = 3; | 159 | optional bool no_shuffle = 7; |
160 | |||
161 | // These specify how the player should be placed when a randomized entrance | ||
162 | // sends them to this port. "rotation" is in degrees and is counter-clockwise | ||
163 | // from the positive X axis. | ||
164 | optional Vec3d destination = 3; | ||
165 | optional double rotation = 6; | ||
133 | optional AxisDirection gravity = 5 [default = Y_MINUS]; | 166 | optional AxisDirection gravity = 5 [default = Y_MINUS]; |
134 | 167 | ||
135 | optional DoorIdentifier required_door = 4; | 168 | optional DoorIdentifier required_door = 4; |
@@ -138,6 +171,13 @@ message HumanPort { | |||
138 | message HumanKeyholder { | 171 | message HumanKeyholder { |
139 | optional string name = 1; | 172 | optional string name = 1; |
140 | optional string path = 2; | 173 | optional string path = 2; |
174 | |||
175 | // If this is set, the keyholder will become a location when keyholder shuffle | ||
176 | // is enabled. This value specifies the key that is required to clear the | ||
177 | // location. It should be the same as the key needed for Green Ending. The | ||
178 | // only cases when this shouldn't be set is the two disappearing keyholders in | ||
179 | // The Congruent. | ||
180 | optional string key = 3; | ||
141 | } | 181 | } |
142 | 182 | ||
143 | message HumanLetter { | 183 | message HumanLetter { |
@@ -161,6 +201,10 @@ message HumanRoom { | |||
161 | optional string name = 1; | 201 | optional string name = 1; |
162 | optional string display_name = 2; | 202 | optional string display_name = 2; |
163 | 203 | ||
204 | // This is used in panelsanity location names and location names for STANDARD | ||
205 | // doors generated from panels in the same area. | ||
206 | optional string panel_display_name = 10; | ||
207 | |||
164 | repeated HumanPanel panels = 3; | 208 | repeated HumanPanel panels = 3; |
165 | repeated HumanPainting paintings = 4; | 209 | repeated HumanPainting paintings = 4; |
166 | repeated HumanLetter letters = 5; | 210 | repeated HumanLetter letters = 5; |
@@ -175,10 +219,35 @@ message HumanMap { | |||
175 | repeated string excluded_nodes = 2; | 219 | repeated string excluded_nodes = 2; |
176 | } | 220 | } |
177 | 221 | ||
222 | message HumanProgressive { | ||
223 | optional string name = 1; | ||
224 | repeated DoorIdentifier doors = 2; | ||
225 | } | ||
226 | |||
227 | message HumanProgressives { | ||
228 | repeated HumanProgressive progressives = 1; | ||
229 | } | ||
230 | |||
231 | message HumanDoorGroup { | ||
232 | optional string name = 1; | ||
233 | optional DoorGroupType type = 2; | ||
234 | repeated DoorIdentifier doors = 3; | ||
235 | } | ||
236 | |||
237 | message HumanDoorGroups { | ||
238 | repeated HumanDoorGroup door_groups = 1; | ||
239 | } | ||
240 | |||
241 | message HumanGlobalMetadata { | ||
242 | repeated string special_names = 1; | ||
243 | optional VersionNumber version = 2; | ||
244 | } | ||
245 | |||
178 | message IdMappings { | 246 | message IdMappings { |
179 | message RoomIds { | 247 | message RoomIds { |
180 | map<string, uint64> panels = 1; | 248 | map<string, uint64> panels = 1; |
181 | map<string, uint64> masteries = 2; | 249 | map<string, uint64> masteries = 2; |
250 | map<string, uint64> keyholders = 3; | ||
182 | } | 251 | } |
183 | 252 | ||
184 | message MapIds { | 253 | message MapIds { |
@@ -190,4 +259,6 @@ message IdMappings { | |||
190 | map<string, uint64> special = 2; | 259 | map<string, uint64> special = 2; |
191 | map<string, uint64> letters = 3; | 260 | map<string, uint64> letters = 3; |
192 | map<string, uint64> endings = 4; | 261 | map<string, uint64> endings = 4; |
262 | map<string, uint64> progressives = 5; | ||
263 | map<string, uint64> door_groups = 6; | ||
193 | } | 264 | } |
diff --git a/tools/assign_ids/main.cpp b/tools/assign_ids/main.cpp index e65e5e4..3e16f78 100644 --- a/tools/assign_ids/main.cpp +++ b/tools/assign_ids/main.cpp | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <google/protobuf/text_format.h> | 2 | #include <google/protobuf/text_format.h> |
3 | 3 | ||
4 | #include <cstdint> | 4 | #include <cstdint> |
5 | #include <filesystem> | ||
5 | #include <fstream> | 6 | #include <fstream> |
6 | #include <iostream> | 7 | #include <iostream> |
7 | #include <map> | 8 | #include <map> |
@@ -40,6 +41,10 @@ class AssignIds { | |||
40 | ReadIds(ids_path); | 41 | ReadIds(ids_path); |
41 | 42 | ||
42 | ProcessMaps(datadir_path); | 43 | ProcessMaps(datadir_path); |
44 | ProcessSpecialIds(); | ||
45 | ProcessProgressivesFile(datadir_path / "progressives.txtpb"); | ||
46 | ProcessDoorGroupsFile(datadir_path / "door_groups.txtpb"); | ||
47 | ProcessGlobalMetadataFile(datadir_path / "metadata.txtpb"); | ||
43 | 48 | ||
44 | WriteIds(ids_path); | 49 | WriteIds(ids_path); |
45 | 50 | ||
@@ -54,50 +59,26 @@ class AssignIds { | |||
54 | id_mappings_ = ReadIdsFromYaml(path.string()); | 59 | id_mappings_ = ReadIdsFromYaml(path.string()); |
55 | 60 | ||
56 | for (const auto& [_, map] : id_mappings_.maps()) { | 61 | for (const auto& [_, map] : id_mappings_.maps()) { |
57 | for (const auto& [_, id] : map.doors()) { | 62 | UpdateNextId(map.doors()); |
58 | if (id > next_id_) { | ||
59 | next_id_ = id; | ||
60 | } | ||
61 | } | ||
62 | 63 | ||
63 | for (const auto& [_, room] : map.rooms()) { | 64 | for (const auto& [_, room] : map.rooms()) { |
64 | for (const auto& [_, id] : room.panels()) { | 65 | UpdateNextId(room.panels()); |
65 | if (id > next_id_) { | 66 | UpdateNextId(room.masteries()); |
66 | next_id_ = id; | 67 | UpdateNextId(room.keyholders()); |
67 | } | ||
68 | } | ||
69 | |||
70 | for (const auto& [_, id] : room.masteries()) { | ||
71 | if (id > next_id_) { | ||
72 | next_id_ = id; | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | for (const auto& [_, id] : id_mappings_.special()) { | ||
79 | if (id > next_id_) { | ||
80 | next_id_ = id; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | for (const auto& [_, id] : id_mappings_.letters()) { | ||
85 | if (id > next_id_) { | ||
86 | next_id_ = id; | ||
87 | } | 68 | } |
88 | } | 69 | } |
89 | 70 | ||
90 | for (const auto& [_, id] : id_mappings_.endings()) { | 71 | UpdateNextId(id_mappings_.special()); |
91 | if (id > next_id_) { | 72 | UpdateNextId(id_mappings_.letters()); |
92 | next_id_ = id; | 73 | UpdateNextId(id_mappings_.endings()); |
93 | } | 74 | UpdateNextId(id_mappings_.progressives()); |
94 | } | 75 | UpdateNextId(id_mappings_.door_groups()); |
95 | 76 | ||
96 | next_id_++; | 77 | next_id_++; |
97 | } | 78 | } |
98 | 79 | ||
99 | void WriteIds(std::filesystem::path path) { | 80 | void WriteIds(std::filesystem::path path) { |
100 | WriteIdsAsYaml(id_mappings_, path.string()); | 81 | WriteIdsAsYaml(output_, path.string()); |
101 | } | 82 | } |
102 | 83 | ||
103 | void ProcessMaps(std::filesystem::path path) { | 84 | void ProcessMaps(std::filesystem::path path) { |
@@ -134,14 +115,18 @@ class AssignIds { | |||
134 | return; | 115 | return; |
135 | } | 116 | } |
136 | 117 | ||
118 | auto& maps = *output_.mutable_maps(); | ||
119 | auto& doors = *maps[current_map_name].mutable_doors(); | ||
120 | |||
137 | if (!id_mappings_.maps().contains(current_map_name) || | 121 | if (!id_mappings_.maps().contains(current_map_name) || |
138 | !id_mappings_.maps() | 122 | !id_mappings_.maps() |
139 | .at(current_map_name) | 123 | .at(current_map_name) |
140 | .doors() | 124 | .doors() |
141 | .contains(h_door.name())) { | 125 | .contains(h_door.name())) { |
142 | auto& maps = *id_mappings_.mutable_maps(); | ||
143 | auto& doors = *maps[current_map_name].mutable_doors(); | ||
144 | doors[h_door.name()] = next_id_++; | 126 | doors[h_door.name()] = next_id_++; |
127 | } else { | ||
128 | doors[h_door.name()] = | ||
129 | id_mappings_.maps().at(current_map_name).doors().at(h_door.name()); | ||
145 | } | 130 | } |
146 | } | 131 | } |
147 | 132 | ||
@@ -156,6 +141,10 @@ class AssignIds { | |||
156 | void ProcessRoom(const HumanRoom& h_room, | 141 | void ProcessRoom(const HumanRoom& h_room, |
157 | const std::string& current_map_name) { | 142 | const std::string& current_map_name) { |
158 | for (const HumanPanel& h_panel : h_room.panels()) { | 143 | for (const HumanPanel& h_panel : h_room.panels()) { |
144 | auto& maps = *output_.mutable_maps(); | ||
145 | auto& rooms = *maps[current_map_name].mutable_rooms(); | ||
146 | auto& panels = *rooms[h_room.name()].mutable_panels(); | ||
147 | |||
159 | if (!id_mappings_.maps().contains(current_map_name) || | 148 | if (!id_mappings_.maps().contains(current_map_name) || |
160 | !id_mappings_.maps() | 149 | !id_mappings_.maps() |
161 | .at(current_map_name) | 150 | .at(current_map_name) |
@@ -167,23 +156,33 @@ class AssignIds { | |||
167 | .at(h_room.name()) | 156 | .at(h_room.name()) |
168 | .panels() | 157 | .panels() |
169 | .contains(h_panel.name())) { | 158 | .contains(h_panel.name())) { |
170 | auto& maps = *id_mappings_.mutable_maps(); | ||
171 | auto& rooms = *maps[current_map_name].mutable_rooms(); | ||
172 | auto& panels = *rooms[h_room.name()].mutable_panels(); | ||
173 | panels[h_panel.name()] = next_id_++; | 159 | panels[h_panel.name()] = next_id_++; |
160 | } else { | ||
161 | panels[h_panel.name()] = id_mappings_.maps() | ||
162 | .at(current_map_name) | ||
163 | .rooms() | ||
164 | .at(h_room.name()) | ||
165 | .panels() | ||
166 | .at(h_panel.name()); | ||
174 | } | 167 | } |
175 | } | 168 | } |
176 | 169 | ||
177 | for (const HumanLetter& h_letter : h_room.letters()) { | 170 | for (const HumanLetter& h_letter : h_room.letters()) { |
178 | std::string lettername = GetLetterName(h_letter.key(), h_letter.level2()); | 171 | std::string lettername = GetLetterName(h_letter.key(), h_letter.level2()); |
179 | 172 | ||
173 | auto& letters = *output_.mutable_letters(); | ||
180 | if (!id_mappings_.letters().contains(lettername)) { | 174 | if (!id_mappings_.letters().contains(lettername)) { |
181 | auto& letters = *id_mappings_.mutable_letters(); | ||
182 | letters[lettername] = next_id_++; | 175 | letters[lettername] = next_id_++; |
176 | } else { | ||
177 | letters[lettername] = id_mappings_.letters().at(lettername); | ||
183 | } | 178 | } |
184 | } | 179 | } |
185 | 180 | ||
186 | for (const HumanMastery& h_mastery : h_room.masteries()) { | 181 | for (const HumanMastery& h_mastery : h_room.masteries()) { |
182 | auto& maps = *output_.mutable_maps(); | ||
183 | auto& rooms = *maps[current_map_name].mutable_rooms(); | ||
184 | auto& masteries = *rooms[h_room.name()].mutable_masteries(); | ||
185 | |||
187 | if (!id_mappings_.maps().contains(current_map_name) || | 186 | if (!id_mappings_.maps().contains(current_map_name) || |
188 | !id_mappings_.maps() | 187 | !id_mappings_.maps() |
189 | .at(current_map_name) | 188 | .at(current_map_name) |
@@ -195,27 +194,133 @@ class AssignIds { | |||
195 | .at(h_room.name()) | 194 | .at(h_room.name()) |
196 | .masteries() | 195 | .masteries() |
197 | .contains(h_mastery.name())) { | 196 | .contains(h_mastery.name())) { |
198 | auto& maps = *id_mappings_.mutable_maps(); | ||
199 | auto& rooms = *maps[current_map_name].mutable_rooms(); | ||
200 | auto& masteries = *rooms[h_room.name()].mutable_masteries(); | ||
201 | masteries[h_mastery.name()] = next_id_++; | 197 | masteries[h_mastery.name()] = next_id_++; |
198 | } else { | ||
199 | masteries[h_mastery.name()] = id_mappings_.maps() | ||
200 | .at(current_map_name) | ||
201 | .rooms() | ||
202 | .at(h_room.name()) | ||
203 | .masteries() | ||
204 | .at(h_mastery.name()); | ||
202 | } | 205 | } |
203 | } | 206 | } |
204 | 207 | ||
205 | for (const HumanEnding& h_ending : h_room.endings()) { | 208 | for (const HumanEnding& h_ending : h_room.endings()) { |
209 | auto& endings = *output_.mutable_endings(); | ||
210 | |||
206 | if (!id_mappings_.endings().contains(h_ending.name())) { | 211 | if (!id_mappings_.endings().contains(h_ending.name())) { |
207 | auto& endings = *id_mappings_.mutable_endings(); | ||
208 | endings[h_ending.name()] = next_id_++; | 212 | endings[h_ending.name()] = next_id_++; |
213 | } else { | ||
214 | endings[h_ending.name()] = id_mappings_.endings().at(h_ending.name()); | ||
215 | } | ||
216 | } | ||
217 | |||
218 | for (const HumanKeyholder& h_keyholder : h_room.keyholders()) { | ||
219 | if (!h_keyholder.has_key()) { | ||
220 | continue; | ||
221 | } | ||
222 | |||
223 | auto& maps = *output_.mutable_maps(); | ||
224 | auto& rooms = *maps[current_map_name].mutable_rooms(); | ||
225 | auto& keyholders = *rooms[h_room.name()].mutable_keyholders(); | ||
226 | |||
227 | if (!id_mappings_.maps().contains(current_map_name) || | ||
228 | !id_mappings_.maps() | ||
229 | .at(current_map_name) | ||
230 | .rooms() | ||
231 | .contains(h_room.name()) || | ||
232 | !id_mappings_.maps() | ||
233 | .at(current_map_name) | ||
234 | .rooms() | ||
235 | .at(h_room.name()) | ||
236 | .keyholders() | ||
237 | .contains(h_keyholder.name())) { | ||
238 | keyholders[h_keyholder.name()] = next_id_++; | ||
239 | } else { | ||
240 | keyholders[h_keyholder.name()] = id_mappings_.maps() | ||
241 | .at(current_map_name) | ||
242 | .rooms() | ||
243 | .at(h_room.name()) | ||
244 | .keyholders() | ||
245 | .at(h_keyholder.name()); | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | |||
250 | void ProcessSpecialIds() { | ||
251 | auto& specials = *output_.mutable_special(); | ||
252 | |||
253 | for (const auto& [special_name, ap_id] : id_mappings_.special()) { | ||
254 | specials[special_name] = ap_id; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | void ProcessProgressivesFile(std::filesystem::path path) { | ||
259 | if (!std::filesystem::exists(path)) { | ||
260 | return; | ||
261 | } | ||
262 | |||
263 | auto h_progs = ReadMessageFromFile<HumanProgressives>(path.string()); | ||
264 | auto& progs = *output_.mutable_progressives(); | ||
265 | |||
266 | for (const HumanProgressive& h_prog : h_progs.progressives()) { | ||
267 | if (!id_mappings_.progressives().contains(h_prog.name())) { | ||
268 | progs[h_prog.name()] = next_id_++; | ||
269 | } else { | ||
270 | progs[h_prog.name()] = id_mappings_.progressives().at(h_prog.name()); | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
275 | void ProcessDoorGroupsFile(std::filesystem::path path) { | ||
276 | if (!std::filesystem::exists(path)) { | ||
277 | return; | ||
278 | } | ||
279 | |||
280 | auto h_groups = ReadMessageFromFile<HumanDoorGroups>(path.string()); | ||
281 | auto& groups = *output_.mutable_door_groups(); | ||
282 | |||
283 | for (const HumanDoorGroup& h_group : h_groups.door_groups()) { | ||
284 | if (!id_mappings_.door_groups().contains(h_group.name())) { | ||
285 | groups[h_group.name()] = next_id_++; | ||
286 | } else { | ||
287 | groups[h_group.name()] = id_mappings_.door_groups().at(h_group.name()); | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | |||
292 | void ProcessGlobalMetadataFile(std::filesystem::path path) { | ||
293 | if (!std::filesystem::exists(path)) { | ||
294 | return; | ||
295 | } | ||
296 | |||
297 | auto h_metadata = ReadMessageFromFile<HumanGlobalMetadata>(path.string()); | ||
298 | auto& specials = *output_.mutable_special(); | ||
299 | |||
300 | for (const std::string& h_special : h_metadata.special_names()) { | ||
301 | if (!id_mappings_.special().contains(h_special)) { | ||
302 | specials[h_special] = next_id_++; | ||
303 | } else { | ||
304 | specials[h_special] = id_mappings_.special().at(h_special); | ||
209 | } | 305 | } |
210 | } | 306 | } |
211 | } | 307 | } |
212 | 308 | ||
213 | private: | 309 | private: |
310 | void UpdateNextId(const google::protobuf::Map<std::string, uint64_t>& ids) { | ||
311 | for (const auto& [_, id] : ids) { | ||
312 | if (id > next_id_) { | ||
313 | next_id_ = id; | ||
314 | } | ||
315 | } | ||
316 | } | ||
317 | |||
214 | std::string mapdir_; | 318 | std::string mapdir_; |
215 | 319 | ||
216 | uint64_t next_id_ = 1; | 320 | uint64_t next_id_ = 1; |
217 | 321 | ||
218 | IdMappings id_mappings_; | 322 | IdMappings id_mappings_; |
323 | IdMappings output_; | ||
219 | }; | 324 | }; |
220 | 325 | ||
221 | } // namespace | 326 | } // namespace |
diff --git a/tools/datapacker/container.cpp b/tools/datapacker/container.cpp index 0d3417e..4a656b3 100644 --- a/tools/datapacker/container.cpp +++ b/tools/datapacker/container.cpp | |||
@@ -79,7 +79,7 @@ uint64_t Container::FindOrAddPainting( | |||
79 | auto it = room_container.find(painting_name); | 79 | auto it = room_container.find(painting_name); |
80 | if (it == room_container.end()) { | 80 | if (it == room_container.end()) { |
81 | uint64_t new_id = all_objects_.paintings_size(); | 81 | uint64_t new_id = all_objects_.paintings_size(); |
82 | Painting* painting = all_objects_.add_paintings(); | 82 | PaintingData* painting = all_objects_.add_paintings(); |
83 | painting->set_id(new_id); | 83 | painting->set_id(new_id); |
84 | painting->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt)); | 84 | painting->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt)); |
85 | painting->set_name(painting_name); | 85 | painting->set_name(painting_name); |
@@ -289,7 +289,7 @@ uint64_t Container::FindOrAddKeyholder( | |||
289 | auto it = room_container.find(keyholder_name); | 289 | auto it = room_container.find(keyholder_name); |
290 | if (it == room_container.end()) { | 290 | if (it == room_container.end()) { |
291 | uint64_t new_id = all_objects_.keyholders_size(); | 291 | uint64_t new_id = all_objects_.keyholders_size(); |
292 | Keyholder* keyholder = all_objects_.add_keyholders(); | 292 | KeyholderData* keyholder = all_objects_.add_keyholders(); |
293 | keyholder->set_id(new_id); | 293 | keyholder->set_id(new_id); |
294 | keyholder->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt)); | 294 | keyholder->set_room_id(FindOrAddRoom(map_name, *room_name, std::nullopt)); |
295 | keyholder->set_name(keyholder_name); | 295 | keyholder->set_name(keyholder_name); |
@@ -331,6 +331,40 @@ uint64_t Container::FindOrAddDoor(std::optional<std::string> map_name, | |||
331 | } | 331 | } |
332 | } | 332 | } |
333 | 333 | ||
334 | uint64_t Container::FindOrAddProgressive(std::string prog_name) { | ||
335 | auto it = progressive_id_by_name_.find(prog_name); | ||
336 | |||
337 | if (it == progressive_id_by_name_.end()) { | ||
338 | uint64_t new_id = all_objects_.progressives_size(); | ||
339 | Progressive* progressive = all_objects_.add_progressives(); | ||
340 | progressive->set_id(new_id); | ||
341 | progressive->set_name(prog_name); | ||
342 | |||
343 | progressive_id_by_name_[prog_name] = new_id; | ||
344 | |||
345 | return new_id; | ||
346 | } else { | ||
347 | return it->second; | ||
348 | } | ||
349 | } | ||
350 | |||
351 | uint64_t Container::FindOrAddDoorGroup(std::string group_name) { | ||
352 | auto it = door_group_id_by_name_.find(group_name); | ||
353 | |||
354 | if (it == door_group_id_by_name_.end()) { | ||
355 | uint64_t new_id = all_objects_.door_groups_size(); | ||
356 | DoorGroup* door_group = all_objects_.add_door_groups(); | ||
357 | door_group->set_id(new_id); | ||
358 | door_group->set_name(group_name); | ||
359 | |||
360 | door_group_id_by_name_[group_name] = new_id; | ||
361 | |||
362 | return new_id; | ||
363 | } else { | ||
364 | return it->second; | ||
365 | } | ||
366 | } | ||
367 | |||
334 | void Container::AddConnection(const Connection& connection) { | 368 | void Container::AddConnection(const Connection& connection) { |
335 | *all_objects_.add_connections() = connection; | 369 | *all_objects_.add_connections() = connection; |
336 | } | 370 | } |
diff --git a/tools/datapacker/container.h b/tools/datapacker/container.h index 68f5875..bc02ba4 100644 --- a/tools/datapacker/container.h +++ b/tools/datapacker/container.h | |||
@@ -60,6 +60,10 @@ class Container { | |||
60 | 60 | ||
61 | void AddConnection(const Connection& connection); | 61 | void AddConnection(const Connection& connection); |
62 | 62 | ||
63 | uint64_t FindOrAddProgressive(std::string prog_name); | ||
64 | |||
65 | uint64_t FindOrAddDoorGroup(std::string group_name); | ||
66 | |||
63 | AllObjects& all_objects() { return all_objects_; } | 67 | AllObjects& all_objects() { return all_objects_; } |
64 | 68 | ||
65 | private: | 69 | private: |
@@ -82,6 +86,8 @@ class Container { | |||
82 | std::map<std::string, std::map<std::string, uint64_t>> | 86 | std::map<std::string, std::map<std::string, uint64_t>> |
83 | door_id_by_map_door_names_; | 87 | door_id_by_map_door_names_; |
84 | std::map<std::string, uint64_t> ending_id_by_name_; | 88 | std::map<std::string, uint64_t> ending_id_by_name_; |
89 | std::map<std::string, uint64_t> progressive_id_by_name_; | ||
90 | std::map<std::string, uint64_t> door_group_id_by_name_; | ||
85 | }; | 91 | }; |
86 | 92 | ||
87 | } // namespace com::fourisland::lingo2_archipelago | 93 | } // namespace com::fourisland::lingo2_archipelago |
diff --git a/tools/datapacker/main.cpp b/tools/datapacker/main.cpp index d9fcbe2..e807d74 100644 --- a/tools/datapacker/main.cpp +++ b/tools/datapacker/main.cpp | |||
@@ -43,6 +43,9 @@ class DataPacker { | |||
43 | 43 | ||
44 | ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt); | 44 | ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt); |
45 | ProcessMaps(datadir_path); | 45 | ProcessMaps(datadir_path); |
46 | ProcessProgressivesFile(datadir_path / "progressives.txtpb"); | ||
47 | ProcessDoorGroupsFile(datadir_path / "door_groups.txtpb"); | ||
48 | ProcessGlobalMetadataFile(datadir_path / "metadata.txtpb"); | ||
46 | ProcessIdsFile(datadir_path / "ids.yaml"); | 49 | ProcessIdsFile(datadir_path / "ids.yaml"); |
47 | 50 | ||
48 | { | 51 | { |
@@ -104,7 +107,11 @@ class DataPacker { | |||
104 | container_.FindOrAddRoom(current_map_name, h_room.name(), std::nullopt); | 107 | container_.FindOrAddRoom(current_map_name, h_room.name(), std::nullopt); |
105 | Room& room = *container_.all_objects().mutable_rooms(room_id); | 108 | Room& room = *container_.all_objects().mutable_rooms(room_id); |
106 | 109 | ||
107 | room.set_display_name(h_room.display_name()); | 110 | // room.set_display_name(h_room.display_name()); |
111 | |||
112 | if (h_room.has_panel_display_name()) { | ||
113 | room.set_panel_display_name(h_room.panel_display_name()); | ||
114 | } | ||
108 | 115 | ||
109 | for (const HumanPanel& h_panel : h_room.panels()) { | 116 | for (const HumanPanel& h_panel : h_room.panels()) { |
110 | room.add_panels(ProcessPanel(h_panel, current_map_name, room.name())); | 117 | room.add_panels(ProcessPanel(h_panel, current_map_name, room.name())); |
@@ -175,6 +182,10 @@ class DataPacker { | |||
175 | map_name, h_panel.required_room().name(), current_map_name)); | 182 | map_name, h_panel.required_room().name(), current_map_name)); |
176 | } | 183 | } |
177 | 184 | ||
185 | if (h_panel.has_display_name()) { | ||
186 | panel.set_display_name(h_panel.display_name()); | ||
187 | } | ||
188 | |||
178 | return panel_id; | 189 | return panel_id; |
179 | } | 190 | } |
180 | 191 | ||
@@ -184,7 +195,7 @@ class DataPacker { | |||
184 | uint64_t painting_id = container_.FindOrAddPainting( | 195 | uint64_t painting_id = container_.FindOrAddPainting( |
185 | current_map_name, current_room_name, h_painting.name(), std::nullopt, | 196 | current_map_name, current_room_name, h_painting.name(), std::nullopt, |
186 | std::nullopt); | 197 | std::nullopt); |
187 | Painting& painting = | 198 | PaintingData& painting = |
188 | *container_.all_objects().mutable_paintings(painting_id); | 199 | *container_.all_objects().mutable_paintings(painting_id); |
189 | 200 | ||
190 | painting.set_path(h_painting.path()); | 201 | painting.set_path(h_painting.path()); |
@@ -228,7 +239,14 @@ class DataPacker { | |||
228 | Port& port = *container_.all_objects().mutable_ports(port_id); | 239 | Port& port = *container_.all_objects().mutable_ports(port_id); |
229 | 240 | ||
230 | port.set_path(h_port.path()); | 241 | port.set_path(h_port.path()); |
231 | port.set_orientation(h_port.orientation()); | 242 | port.set_display_name(h_port.display_name()); |
243 | |||
244 | if (h_port.no_shuffle()) { | ||
245 | port.set_no_shuffle(h_port.no_shuffle()); | ||
246 | } else { | ||
247 | *port.mutable_destination() = h_port.destination(); | ||
248 | port.set_rotation(h_port.rotation()); | ||
249 | } | ||
232 | 250 | ||
233 | // Setting this explicitly because the Godot protobuf doesn't support | 251 | // Setting this explicitly because the Godot protobuf doesn't support |
234 | // custom defaults. | 252 | // custom defaults. |
@@ -279,11 +297,15 @@ class DataPacker { | |||
279 | uint64_t keyholder_id = container_.FindOrAddKeyholder( | 297 | uint64_t keyholder_id = container_.FindOrAddKeyholder( |
280 | current_map_name, current_room_name, h_keyholder.name(), std::nullopt, | 298 | current_map_name, current_room_name, h_keyholder.name(), std::nullopt, |
281 | std::nullopt); | 299 | std::nullopt); |
282 | Keyholder& keyholder = | 300 | KeyholderData& keyholder = |
283 | *container_.all_objects().mutable_keyholders(keyholder_id); | 301 | *container_.all_objects().mutable_keyholders(keyholder_id); |
284 | 302 | ||
285 | keyholder.set_path(h_keyholder.path()); | 303 | keyholder.set_path(h_keyholder.path()); |
286 | 304 | ||
305 | if (h_keyholder.has_key()) { | ||
306 | keyholder.set_key(h_keyholder.key()); | ||
307 | } | ||
308 | |||
287 | return keyholder_id; | 309 | return keyholder_id; |
288 | } | 310 | } |
289 | 311 | ||
@@ -331,8 +353,8 @@ class DataPacker { | |||
331 | h_door.receivers().begin(), h_door.receivers().end(), | 353 | h_door.receivers().begin(), h_door.receivers().end(), |
332 | google::protobuf::RepeatedFieldBackInserter(door.mutable_receivers())); | 354 | google::protobuf::RepeatedFieldBackInserter(door.mutable_receivers())); |
333 | std::copy( | 355 | std::copy( |
334 | h_door.switches().begin(), h_door.switches().end(), | 356 | h_door.senders().begin(), h_door.senders().end(), |
335 | google::protobuf::RepeatedFieldBackInserter(door.mutable_switches())); | 357 | google::protobuf::RepeatedFieldBackInserter(door.mutable_senders())); |
336 | 358 | ||
337 | for (const PaintingIdentifier& pi : h_door.move_paintings()) { | 359 | for (const PaintingIdentifier& pi : h_door.move_paintings()) { |
338 | std::optional<std::string> map_name = | 360 | std::optional<std::string> map_name = |
@@ -380,7 +402,7 @@ class DataPacker { | |||
380 | door.add_doors( | 402 | door.add_doors( |
381 | container_.FindOrAddDoor(map_name, di.name(), current_map_name)); | 403 | container_.FindOrAddDoor(map_name, di.name(), current_map_name)); |
382 | } | 404 | } |
383 | 405 | ||
384 | for (const std::string& ending_name : h_door.endings()) { | 406 | for (const std::string& ending_name : h_door.endings()) { |
385 | door.add_endings(container_.FindOrAddEnding(ending_name)); | 407 | door.add_endings(container_.FindOrAddEnding(ending_name)); |
386 | } | 408 | } |
@@ -394,6 +416,14 @@ class DataPacker { | |||
394 | } | 416 | } |
395 | 417 | ||
396 | door.set_type(h_door.type()); | 418 | door.set_type(h_door.type()); |
419 | |||
420 | if (h_door.has_location_name()) { | ||
421 | door.set_location_name(h_door.location_name()); | ||
422 | } | ||
423 | |||
424 | if (h_door.has_double_letters()) { | ||
425 | door.set_double_letters(h_door.double_letters()); | ||
426 | } | ||
397 | } | 427 | } |
398 | 428 | ||
399 | void ProcessConnectionsFile(std::filesystem::path path, | 429 | void ProcessConnectionsFile(std::filesystem::path path, |
@@ -445,6 +475,26 @@ class DataPacker { | |||
445 | r_connection.set_required_door(door_id); | 475 | r_connection.set_required_door(door_id); |
446 | } | 476 | } |
447 | 477 | ||
478 | if (human_connection.has_roof_access()) { | ||
479 | f_connection.set_roof_access(human_connection.roof_access()); | ||
480 | r_connection.set_roof_access(human_connection.roof_access()); | ||
481 | } | ||
482 | |||
483 | if (human_connection.has_purple_ending()) { | ||
484 | f_connection.set_purple_ending(human_connection.purple_ending()); | ||
485 | r_connection.set_purple_ending(human_connection.purple_ending()); | ||
486 | } | ||
487 | |||
488 | if (human_connection.has_cyan_ending()) { | ||
489 | f_connection.set_cyan_ending(human_connection.cyan_ending()); | ||
490 | r_connection.set_cyan_ending(human_connection.cyan_ending()); | ||
491 | } | ||
492 | |||
493 | if (human_connection.has_vanilla_only()) { | ||
494 | f_connection.set_vanilla_only(human_connection.vanilla_only()); | ||
495 | r_connection.set_vanilla_only(human_connection.vanilla_only()); | ||
496 | } | ||
497 | |||
448 | container_.AddConnection(f_connection); | 498 | container_.AddConnection(f_connection); |
449 | if (!human_connection.oneway()) { | 499 | if (!human_connection.oneway()) { |
450 | container_.AddConnection(r_connection); | 500 | container_.AddConnection(r_connection); |
@@ -528,6 +578,63 @@ class DataPacker { | |||
528 | } | 578 | } |
529 | } | 579 | } |
530 | 580 | ||
581 | void ProcessProgressivesFile(std::filesystem::path path) { | ||
582 | if (!std::filesystem::exists(path)) { | ||
583 | return; | ||
584 | } | ||
585 | |||
586 | auto h_progs = ReadMessageFromFile<HumanProgressives>(path.string()); | ||
587 | |||
588 | for (const HumanProgressive& h_prog : h_progs.progressives()) { | ||
589 | ProcessProgressive(h_prog); | ||
590 | } | ||
591 | } | ||
592 | |||
593 | void ProcessProgressive(const HumanProgressive& h_prog) { | ||
594 | uint64_t prog_id = container_.FindOrAddProgressive(h_prog.name()); | ||
595 | Progressive& prog = *container_.all_objects().mutable_progressives(prog_id); | ||
596 | |||
597 | for (const DoorIdentifier& di : h_prog.doors()) { | ||
598 | uint64_t door_id = | ||
599 | container_.FindOrAddDoor(di.map(), di.name(), std::nullopt); | ||
600 | prog.add_doors(door_id); | ||
601 | } | ||
602 | } | ||
603 | |||
604 | void ProcessDoorGroupsFile(std::filesystem::path path) { | ||
605 | if (!std::filesystem::exists(path)) { | ||
606 | return; | ||
607 | } | ||
608 | |||
609 | auto h_groups = ReadMessageFromFile<HumanDoorGroups>(path.string()); | ||
610 | |||
611 | for (const HumanDoorGroup& h_group : h_groups.door_groups()) { | ||
612 | ProcessDoorGroup(h_group); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | void ProcessDoorGroup(const HumanDoorGroup& h_group) { | ||
617 | uint64_t group_id = container_.FindOrAddDoorGroup(h_group.name()); | ||
618 | DoorGroup& group = *container_.all_objects().mutable_door_groups(group_id); | ||
619 | |||
620 | group.set_type(h_group.type()); | ||
621 | |||
622 | for (const DoorIdentifier& di : h_group.doors()) { | ||
623 | uint64_t door_id = | ||
624 | container_.FindOrAddDoor(di.map(), di.name(), std::nullopt); | ||
625 | group.add_doors(door_id); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | void ProcessGlobalMetadataFile(std::filesystem::path path) { | ||
630 | if (!std::filesystem::exists(path)) { | ||
631 | return; | ||
632 | } | ||
633 | |||
634 | auto h_metadata = ReadMessageFromFile<HumanGlobalMetadata>(path.string()); | ||
635 | *container_.all_objects().mutable_version() = h_metadata.version(); | ||
636 | } | ||
637 | |||
531 | void ProcessIdsFile(std::filesystem::path path) { | 638 | void ProcessIdsFile(std::filesystem::path path) { |
532 | auto ids = ReadIdsFromYaml(path.string()); | 639 | auto ids = ReadIdsFromYaml(path.string()); |
533 | 640 | ||
@@ -552,6 +659,14 @@ class DataPacker { | |||
552 | .mutable_masteries(mastery_id) | 659 | .mutable_masteries(mastery_id) |
553 | ->set_ap_id(ap_id); | 660 | ->set_ap_id(ap_id); |
554 | } | 661 | } |
662 | |||
663 | for (const auto& [keyholder_name, ap_id] : room.keyholders()) { | ||
664 | uint64_t keyholder_id = container_.FindOrAddKeyholder( | ||
665 | map_name, room_name, keyholder_name, std::nullopt, std::nullopt); | ||
666 | container_.all_objects() | ||
667 | .mutable_keyholders(keyholder_id) | ||
668 | ->set_ap_id(ap_id); | ||
669 | } | ||
555 | } | 670 | } |
556 | } | 671 | } |
557 | 672 | ||
@@ -569,6 +684,16 @@ class DataPacker { | |||
569 | uint64_t ending_id = container_.FindOrAddEnding(ending_name); | 684 | uint64_t ending_id = container_.FindOrAddEnding(ending_name); |
570 | container_.all_objects().mutable_endings(ending_id)->set_ap_id(ap_id); | 685 | container_.all_objects().mutable_endings(ending_id)->set_ap_id(ap_id); |
571 | } | 686 | } |
687 | |||
688 | for (const auto& [prog_name, ap_id] : ids.progressives()) { | ||
689 | uint64_t prog_id = container_.FindOrAddProgressive(prog_name); | ||
690 | container_.all_objects().mutable_progressives(prog_id)->set_ap_id(ap_id); | ||
691 | } | ||
692 | |||
693 | for (const auto& [group_name, ap_id] : ids.door_groups()) { | ||
694 | uint64_t group_id = container_.FindOrAddDoorGroup(group_name); | ||
695 | container_.all_objects().mutable_door_groups(group_id)->set_ap_id(ap_id); | ||
696 | } | ||
572 | } | 697 | } |
573 | 698 | ||
574 | std::string mapdir_; | 699 | std::string mapdir_; |
diff --git a/tools/util/godot_scene.cpp b/tools/util/godot_scene.cpp index 1e77c9e..f788d21 100644 --- a/tools/util/godot_scene.cpp +++ b/tools/util/godot_scene.cpp | |||
@@ -1,10 +1,8 @@ | |||
1 | #include "godot_scene.h" | 1 | #include "godot_scene.h" |
2 | 2 | ||
3 | #include <absl/strings/str_split.h> | ||
4 | #include <absl/strings/string_view.h> | ||
5 | |||
6 | #include <fstream> | 3 | #include <fstream> |
7 | #include <sstream> | 4 | #include <sstream> |
5 | #include <string_view> | ||
8 | #include <variant> | 6 | #include <variant> |
9 | 7 | ||
10 | namespace com::fourisland::lingo2_archipelago { | 8 | namespace com::fourisland::lingo2_archipelago { |
@@ -23,7 +21,7 @@ struct Heading { | |||
23 | GodotInstanceType instance_type; | 21 | GodotInstanceType instance_type; |
24 | }; | 22 | }; |
25 | 23 | ||
26 | Heading ParseTscnHeading(absl::string_view line) { | 24 | Heading ParseTscnHeading(std::string_view line) { |
27 | std::string original_line(line); | 25 | std::string original_line(line); |
28 | Heading heading; | 26 | Heading heading; |
29 | 27 | ||
diff --git a/tools/util/ids_yaml_format.cpp b/tools/util/ids_yaml_format.cpp index f72f60e..71bfd63 100644 --- a/tools/util/ids_yaml_format.cpp +++ b/tools/util/ids_yaml_format.cpp | |||
@@ -56,6 +56,14 @@ IdMappings ReadIdsFromYaml(const std::string& filename) { | |||
56 | mastery_it.second.as<uint64_t>(); | 56 | mastery_it.second.as<uint64_t>(); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | |||
60 | if (room_it.second["keyholders"]) { | ||
61 | for (const auto& keyholder_it : room_it.second["keyholders"]) { | ||
62 | (*room_ids.mutable_keyholders())[keyholder_it.first | ||
63 | .as<std::string>()] = | ||
64 | keyholder_it.second.as<uint64_t>(); | ||
65 | } | ||
66 | } | ||
59 | } | 67 | } |
60 | } | 68 | } |
61 | 69 | ||
@@ -89,6 +97,20 @@ IdMappings ReadIdsFromYaml(const std::string& filename) { | |||
89 | } | 97 | } |
90 | } | 98 | } |
91 | 99 | ||
100 | if (document["progressives"]) { | ||
101 | for (const auto& prog_it : document["progressives"]) { | ||
102 | (*result.mutable_progressives())[prog_it.first.as<std::string>()] = | ||
103 | prog_it.second.as<uint64_t>(); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | if (document["door_groups"]) { | ||
108 | for (const auto& group_it : document["door_groups"]) { | ||
109 | (*result.mutable_door_groups())[group_it.first.as<std::string>()] = | ||
110 | group_it.second.as<uint64_t>(); | ||
111 | } | ||
112 | } | ||
113 | |||
92 | return result; | 114 | return result; |
93 | } | 115 | } |
94 | 116 | ||
@@ -117,6 +139,13 @@ void WriteIdsAsYaml(const IdMappings& ids, const std::string& filename) { | |||
117 | mastery_id; | 139 | mastery_id; |
118 | }); | 140 | }); |
119 | 141 | ||
142 | OperateOnSortedMap(room_ids.keyholders(), | ||
143 | [&room_node](const std::string& keyholder_name, | ||
144 | uint64_t keyholder_id) { | ||
145 | room_node["keyholders"][keyholder_name] = | ||
146 | keyholder_id; | ||
147 | }); | ||
148 | |||
120 | map_node["rooms"][room_name] = std::move(room_node); | 149 | map_node["rooms"][room_name] = std::move(room_node); |
121 | }); | 150 | }); |
122 | 151 | ||
@@ -144,6 +173,16 @@ void WriteIdsAsYaml(const IdMappings& ids, const std::string& filename) { | |||
144 | result["special"][special_name] = special_id; | 173 | result["special"][special_name] = special_id; |
145 | }); | 174 | }); |
146 | 175 | ||
176 | OperateOnSortedMap(ids.progressives(), | ||
177 | [&result](const std::string& prog_name, uint64_t prog_id) { | ||
178 | result["progressives"][prog_name] = prog_id; | ||
179 | }); | ||
180 | |||
181 | OperateOnSortedMap(ids.door_groups(), [&result](const std::string& group_name, | ||
182 | uint64_t group_id) { | ||
183 | result["door_groups"][group_name] = group_id; | ||
184 | }); | ||
185 | |||
147 | std::ofstream output_stream(filename); | 186 | std::ofstream output_stream(filename); |
148 | output_stream << result << std::endl; | 187 | output_stream << result << std::endl; |
149 | } | 188 | } |
diff --git a/tools/validator/CMakeLists.txt b/tools/validator/CMakeLists.txt index 967b890..1a8fd9c 100644 --- a/tools/validator/CMakeLists.txt +++ b/tools/validator/CMakeLists.txt | |||
@@ -1,3 +1,4 @@ | |||
1 | find_package(fmt REQUIRED) | ||
1 | find_package(Protobuf REQUIRED) | 2 | find_package(Protobuf REQUIRED) |
2 | 3 | ||
3 | add_executable(validator | 4 | add_executable(validator |
@@ -9,4 +10,4 @@ add_executable(validator | |||
9 | set_property(TARGET validator PROPERTY CXX_STANDARD 20) | 10 | set_property(TARGET validator PROPERTY CXX_STANDARD 20) |
10 | set_property(TARGET validator PROPERTY CXX_STANDARD_REQUIRED ON) | 11 | set_property(TARGET validator PROPERTY CXX_STANDARD_REQUIRED ON) |
11 | target_include_directories(validator PUBLIC ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/tools) | 12 | target_include_directories(validator PUBLIC ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/tools) |
12 | target_link_libraries(validator PUBLIC protos util protobuf::libprotobuf) | 13 | target_link_libraries(validator PUBLIC protos util fmt::fmt protobuf::libprotobuf) |
diff --git a/tools/validator/human_processor.cpp b/tools/validator/human_processor.cpp index f53dc79..2c978bf 100644 --- a/tools/validator/human_processor.cpp +++ b/tools/validator/human_processor.cpp | |||
@@ -1,5 +1,6 @@ | |||
1 | #include "human_processor.h" | 1 | #include "human_processor.h" |
2 | 2 | ||
3 | #include <fmt/core.h> | ||
3 | #include <google/protobuf/message.h> | 4 | #include <google/protobuf/message.h> |
4 | #include <google/protobuf/text_format.h> | 5 | #include <google/protobuf/text_format.h> |
5 | 6 | ||
@@ -12,6 +13,7 @@ | |||
12 | #include <string> | 13 | #include <string> |
13 | 14 | ||
14 | #include "structs.h" | 15 | #include "structs.h" |
16 | #include "util/ids_yaml_format.h" | ||
15 | 17 | ||
16 | namespace com::fourisland::lingo2_archipelago { | 18 | namespace com::fourisland::lingo2_archipelago { |
17 | namespace { | 19 | namespace { |
@@ -40,7 +42,9 @@ class HumanProcessor { | |||
40 | 42 | ||
41 | ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt); | 43 | ProcessConnectionsFile(datadir_path / "connections.txtpb", std::nullopt); |
42 | ProcessMaps(datadir_path); | 44 | ProcessMaps(datadir_path); |
43 | ProcessIdsFile(datadir_path / "ids.txtpb"); | 45 | ProcessProgressivesFile(datadir_path / "progressives.txtpb"); |
46 | ProcessDoorGroupsFile(datadir_path / "door_groups.txtpb"); | ||
47 | ProcessIdsFile(datadir_path / "ids.yaml"); | ||
44 | } | 48 | } |
45 | 49 | ||
46 | private: | 50 | private: |
@@ -93,7 +97,7 @@ class HumanProcessor { | |||
93 | room_info.definitions.push_back(h_room); | 97 | room_info.definitions.push_back(h_room); |
94 | 98 | ||
95 | for (const HumanPanel& h_panel : h_room.panels()) { | 99 | for (const HumanPanel& h_panel : h_room.panels()) { |
96 | ProcessPanel(h_panel, current_map_name, h_room.name()); | 100 | ProcessPanel(h_panel, current_map_name, h_room); |
97 | } | 101 | } |
98 | 102 | ||
99 | for (const HumanPainting& h_painting : h_room.paintings()) { | 103 | for (const HumanPainting& h_painting : h_room.paintings()) { |
@@ -123,15 +127,14 @@ class HumanProcessor { | |||
123 | 127 | ||
124 | void ProcessPanel(const HumanPanel& h_panel, | 128 | void ProcessPanel(const HumanPanel& h_panel, |
125 | const std::string& current_map_name, | 129 | const std::string& current_map_name, |
126 | const std::string& current_room_name) { | 130 | const HumanRoom& h_room) { |
127 | PanelIdentifier panel_identifier; | 131 | PanelIdentifier panel_identifier; |
128 | panel_identifier.set_map(current_map_name); | 132 | panel_identifier.set_map(current_map_name); |
129 | panel_identifier.set_room(current_room_name); | 133 | panel_identifier.set_room(h_room.name()); |
130 | panel_identifier.set_name(h_panel.name()); | 134 | panel_identifier.set_name(h_panel.name()); |
131 | 135 | ||
132 | PanelInfo& panel_info = info_.panels[panel_identifier]; | 136 | PanelInfo& panel_info = info_.panels[panel_identifier]; |
133 | panel_info.definitions.push_back(h_panel); | 137 | panel_info.definitions.push_back(h_panel); |
134 | panel_info.proxies[h_panel.answer()].definitions.push_back(Proxy()); | ||
135 | 138 | ||
136 | MapInfo& map_info = info_.maps[current_map_name]; | 139 | MapInfo& map_info = info_.maps[current_map_name]; |
137 | map_info.game_nodes[h_panel.path()].uses++; | 140 | map_info.game_nodes[h_panel.path()].uses++; |
@@ -156,6 +159,24 @@ class HumanProcessor { | |||
156 | RoomInfo& required_room_info = info_.rooms[required_room_identifier]; | 159 | RoomInfo& required_room_info = info_.rooms[required_room_identifier]; |
157 | required_room_info.panels_referenced_by.push_back(panel_identifier); | 160 | required_room_info.panels_referenced_by.push_back(panel_identifier); |
158 | } | 161 | } |
162 | |||
163 | std::string map_area_name = current_map_name; | ||
164 | if (h_room.has_panel_display_name()) { | ||
165 | map_area_name = | ||
166 | fmt::format("{} ({})", current_map_name, h_room.panel_display_name()); | ||
167 | } | ||
168 | |||
169 | panel_info.map_area_name = map_area_name; | ||
170 | |||
171 | std::string panelsanity_name; | ||
172 | if (h_panel.has_display_name()) { | ||
173 | panelsanity_name = | ||
174 | fmt::format("{} - {}", map_area_name, h_panel.display_name()); | ||
175 | } else { | ||
176 | panelsanity_name = fmt::format("{} - {}", map_area_name, h_panel.name()); | ||
177 | } | ||
178 | info_.panel_names[panelsanity_name].panels_used_by.push_back( | ||
179 | panel_identifier); | ||
159 | } | 180 | } |
160 | 181 | ||
161 | void ProcessPainting(const HumanPainting& h_painting, | 182 | void ProcessPainting(const HumanPainting& h_painting, |
@@ -373,7 +394,9 @@ class HumanProcessor { | |||
373 | } | 394 | } |
374 | } else if (human_connection.has_from()) { | 395 | } else if (human_connection.has_from()) { |
375 | ProcessSingleConnection(human_connection, human_connection.from(), | 396 | ProcessSingleConnection(human_connection, human_connection.from(), |
376 | current_map_name); | 397 | current_map_name, |
398 | /*is_target=*/!human_connection.oneway() && | ||
399 | !human_connection.bypass_target_door()); | ||
377 | } | 400 | } |
378 | 401 | ||
379 | if (human_connection.has_to_room()) { | 402 | if (human_connection.has_to_room()) { |
@@ -389,8 +412,9 @@ class HumanProcessor { | |||
389 | std::cout << "A global connection used to_room." << std::endl; | 412 | std::cout << "A global connection used to_room." << std::endl; |
390 | } | 413 | } |
391 | } else if (human_connection.has_to()) { | 414 | } else if (human_connection.has_to()) { |
392 | ProcessSingleConnection(human_connection, human_connection.to(), | 415 | ProcessSingleConnection( |
393 | current_map_name); | 416 | human_connection, human_connection.to(), current_map_name, |
417 | /*is_target=*/!human_connection.bypass_target_door()); | ||
394 | } | 418 | } |
395 | 419 | ||
396 | if (human_connection.has_door()) { | 420 | if (human_connection.has_door()) { |
@@ -411,7 +435,7 @@ class HumanProcessor { | |||
411 | void ProcessSingleConnection( | 435 | void ProcessSingleConnection( |
412 | const HumanConnection& human_connection, | 436 | const HumanConnection& human_connection, |
413 | const HumanConnection::Endpoint& endpoint, | 437 | const HumanConnection::Endpoint& endpoint, |
414 | const std::optional<std::string>& current_map_name) { | 438 | const std::optional<std::string>& current_map_name, bool is_target) { |
415 | if (endpoint.has_room()) { | 439 | if (endpoint.has_room()) { |
416 | auto room_identifier = | 440 | auto room_identifier = |
417 | GetCompleteRoomIdentifier(endpoint.room(), current_map_name); | 441 | GetCompleteRoomIdentifier(endpoint.room(), current_map_name); |
@@ -430,6 +454,11 @@ class HumanProcessor { | |||
430 | if (painting_identifier) { | 454 | if (painting_identifier) { |
431 | PaintingInfo& painting_info = info_.paintings[*painting_identifier]; | 455 | PaintingInfo& painting_info = info_.paintings[*painting_identifier]; |
432 | painting_info.connections_referenced_by.push_back(human_connection); | 456 | painting_info.connections_referenced_by.push_back(human_connection); |
457 | |||
458 | if (is_target) { | ||
459 | painting_info.target_connections_referenced_by.push_back( | ||
460 | human_connection); | ||
461 | } | ||
433 | } else { | 462 | } else { |
434 | // Not sure where else to store this right now. | 463 | // Not sure where else to store this right now. |
435 | std::cout | 464 | std::cout |
@@ -442,6 +471,11 @@ class HumanProcessor { | |||
442 | if (port_identifier) { | 471 | if (port_identifier) { |
443 | PortInfo& port_info = info_.ports[*port_identifier]; | 472 | PortInfo& port_info = info_.ports[*port_identifier]; |
444 | port_info.connections_referenced_by.push_back(human_connection); | 473 | port_info.connections_referenced_by.push_back(human_connection); |
474 | |||
475 | if (is_target) { | ||
476 | port_info.target_connections_referenced_by.push_back( | ||
477 | human_connection); | ||
478 | } | ||
445 | } else { | 479 | } else { |
446 | // Not sure where else to store this right now. | 480 | // Not sure where else to store this right now. |
447 | std::cout | 481 | std::cout |
@@ -459,12 +493,137 @@ class HumanProcessor { | |||
459 | panel_info.proxies[endpoint.panel().answer()] | 493 | panel_info.proxies[endpoint.panel().answer()] |
460 | .connections_referenced_by.push_back(human_connection); | 494 | .connections_referenced_by.push_back(human_connection); |
461 | } | 495 | } |
496 | |||
497 | if (is_target) { | ||
498 | panel_info.target_connections_referenced_by.push_back( | ||
499 | human_connection); | ||
500 | } | ||
462 | } | 501 | } |
463 | } | 502 | } |
464 | } | 503 | } |
465 | 504 | ||
505 | void ProcessProgressivesFile(std::filesystem::path path) { | ||
506 | if (!std::filesystem::exists(path)) { | ||
507 | return; | ||
508 | } | ||
509 | |||
510 | auto h_progs = ReadMessageFromFile<HumanProgressives>(path.string()); | ||
511 | |||
512 | for (const HumanProgressive& h_prog : h_progs.progressives()) { | ||
513 | ProcessProgressive(h_prog); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | void ProcessProgressive(const HumanProgressive& h_prog) { | ||
518 | ProgressiveInfo& prog_info = info_.progressives[h_prog.name()]; | ||
519 | prog_info.definitions.push_back(h_prog); | ||
520 | |||
521 | for (const DoorIdentifier& di : h_prog.doors()) { | ||
522 | if (!di.has_map()) { | ||
523 | prog_info.malformed_doors.push_back(di); | ||
524 | continue; | ||
525 | } | ||
526 | |||
527 | DoorInfo& door_info = info_.doors[di]; | ||
528 | door_info.progressives_referenced_by.push_back(h_prog.name()); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | void ProcessDoorGroupsFile(std::filesystem::path path) { | ||
533 | if (!std::filesystem::exists(path)) { | ||
534 | return; | ||
535 | } | ||
536 | |||
537 | auto h_groups = ReadMessageFromFile<HumanDoorGroups>(path.string()); | ||
538 | |||
539 | for (const HumanDoorGroup& h_group : h_groups.door_groups()) { | ||
540 | ProcessDoorGroup(h_group); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | void ProcessDoorGroup(const HumanDoorGroup& h_group) { | ||
545 | DoorGroupInfo& group_info = info_.door_groups[h_group.name()]; | ||
546 | group_info.definitions.push_back(h_group); | ||
547 | |||
548 | for (const DoorIdentifier& di : h_group.doors()) { | ||
549 | if (!di.has_map()) { | ||
550 | group_info.malformed_doors.push_back(di); | ||
551 | continue; | ||
552 | } | ||
553 | |||
554 | DoorInfo& door_info = info_.doors[di]; | ||
555 | door_info.door_groups_referenced_by.push_back(h_group.name()); | ||
556 | } | ||
557 | } | ||
558 | |||
466 | void ProcessIdsFile(std::filesystem::path path) { | 559 | void ProcessIdsFile(std::filesystem::path path) { |
467 | // Ignore this for now. | 560 | auto ids = ReadIdsFromYaml(path.string()); |
561 | |||
562 | DoorIdentifier di; | ||
563 | PanelIdentifier pi; | ||
564 | KeyholderIdentifier ki; | ||
565 | |||
566 | for (const auto& [map_name, map] : ids.maps()) { | ||
567 | di.set_map(map_name); | ||
568 | pi.set_map(map_name); | ||
569 | ki.set_map(map_name); | ||
570 | |||
571 | for (const auto& [door_name, ap_id] : map.doors()) { | ||
572 | di.set_name(door_name); | ||
573 | |||
574 | DoorInfo& door_info = info_.doors[di]; | ||
575 | door_info.has_id = true; | ||
576 | } | ||
577 | |||
578 | for (const auto& [room_name, room] : map.rooms()) { | ||
579 | pi.set_room(room_name); | ||
580 | ki.set_room(room_name); | ||
581 | |||
582 | for (const auto& [panel_name, ap_id] : room.panels()) { | ||
583 | pi.set_name(panel_name); | ||
584 | |||
585 | PanelInfo& panel_info = info_.panels[pi]; | ||
586 | panel_info.has_id = true; | ||
587 | } | ||
588 | |||
589 | for (const auto& [mastery_name, ap_id] : room.masteries()) { | ||
590 | // TODO: Mastery | ||
591 | } | ||
592 | |||
593 | for (const auto& [keyholder_name, ap_id] : room.keyholders()) { | ||
594 | ki.set_name(keyholder_name); | ||
595 | |||
596 | KeyholderInfo& keyholder_info = info_.keyholders[ki]; | ||
597 | keyholder_info.has_id = true; | ||
598 | } | ||
599 | } | ||
600 | } | ||
601 | |||
602 | for (const auto& [tag, id] : ids.special()) { | ||
603 | // TODO: Specials | ||
604 | } | ||
605 | |||
606 | for (const auto& [letter_name, ap_id] : ids.letters()) { | ||
607 | LetterIdentifier li = | ||
608 | std::make_tuple(letter_name[0], letter_name[1] == '2'); | ||
609 | LetterInfo& letter_info = info_.letters[li]; | ||
610 | letter_info.has_id = true; | ||
611 | } | ||
612 | |||
613 | for (const auto& [ending_name, ap_id] : ids.endings()) { | ||
614 | EndingInfo& ending_info = info_.endings[ending_name]; | ||
615 | ending_info.has_id = true; | ||
616 | } | ||
617 | |||
618 | for (const auto& [prog_name, ap_id] : ids.progressives()) { | ||
619 | ProgressiveInfo& prog_info = info_.progressives[prog_name]; | ||
620 | prog_info.has_id = true; | ||
621 | } | ||
622 | |||
623 | for (const auto& [group_name, ap_id] : ids.door_groups()) { | ||
624 | DoorGroupInfo& group_info = info_.door_groups[group_name]; | ||
625 | group_info.has_id = true; | ||
626 | } | ||
468 | } | 627 | } |
469 | 628 | ||
470 | std::string mapdir_; | 629 | std::string mapdir_; |
diff --git a/tools/validator/structs.h b/tools/validator/structs.h index 958038d..d1d45f2 100644 --- a/tools/validator/structs.h +++ b/tools/validator/structs.h | |||
@@ -39,12 +39,15 @@ struct RoomInfo { | |||
39 | 39 | ||
40 | struct DoorInfo { | 40 | struct DoorInfo { |
41 | std::vector<HumanDoor> definitions; | 41 | std::vector<HumanDoor> definitions; |
42 | bool has_id = false; | ||
42 | 43 | ||
43 | std::vector<HumanConnection> connections_referenced_by; | 44 | std::vector<HumanConnection> connections_referenced_by; |
44 | std::vector<DoorIdentifier> doors_referenced_by; | 45 | std::vector<DoorIdentifier> doors_referenced_by; |
45 | std::vector<PanelIdentifier> panels_referenced_by; | 46 | std::vector<PanelIdentifier> panels_referenced_by; |
46 | std::vector<PaintingIdentifier> paintings_referenced_by; | 47 | std::vector<PaintingIdentifier> paintings_referenced_by; |
47 | std::vector<PortIdentifier> ports_referenced_by; | 48 | std::vector<PortIdentifier> ports_referenced_by; |
49 | std::vector<std::string> progressives_referenced_by; | ||
50 | std::vector<std::string> door_groups_referenced_by; | ||
48 | 51 | ||
49 | MalformedIdentifiers malformed_identifiers; | 52 | MalformedIdentifiers malformed_identifiers; |
50 | }; | 53 | }; |
@@ -53,12 +56,14 @@ struct PortInfo { | |||
53 | std::vector<HumanPort> definitions; | 56 | std::vector<HumanPort> definitions; |
54 | 57 | ||
55 | std::vector<HumanConnection> connections_referenced_by; | 58 | std::vector<HumanConnection> connections_referenced_by; |
59 | std::vector<HumanConnection> target_connections_referenced_by; | ||
56 | }; | 60 | }; |
57 | 61 | ||
58 | struct PaintingInfo { | 62 | struct PaintingInfo { |
59 | std::vector<HumanPainting> definitions; | 63 | std::vector<HumanPainting> definitions; |
60 | 64 | ||
61 | std::vector<HumanConnection> connections_referenced_by; | 65 | std::vector<HumanConnection> connections_referenced_by; |
66 | std::vector<HumanConnection> target_connections_referenced_by; | ||
62 | std::vector<DoorIdentifier> doors_referenced_by; | 67 | std::vector<DoorIdentifier> doors_referenced_by; |
63 | }; | 68 | }; |
64 | 69 | ||
@@ -71,8 +76,12 @@ struct ProxyInfo { | |||
71 | 76 | ||
72 | struct PanelInfo { | 77 | struct PanelInfo { |
73 | std::vector<HumanPanel> definitions; | 78 | std::vector<HumanPanel> definitions; |
79 | bool has_id = false; | ||
80 | |||
81 | std::string map_area_name; | ||
74 | 82 | ||
75 | std::vector<HumanConnection> connections_referenced_by; | 83 | std::vector<HumanConnection> connections_referenced_by; |
84 | std::vector<HumanConnection> target_connections_referenced_by; | ||
76 | std::vector<DoorIdentifier> doors_referenced_by; | 85 | std::vector<DoorIdentifier> doors_referenced_by; |
77 | 86 | ||
78 | std::map<std::string, ProxyInfo> proxies; | 87 | std::map<std::string, ProxyInfo> proxies; |
@@ -80,6 +89,7 @@ struct PanelInfo { | |||
80 | 89 | ||
81 | struct KeyholderInfo { | 90 | struct KeyholderInfo { |
82 | std::vector<HumanKeyholder> definitions; | 91 | std::vector<HumanKeyholder> definitions; |
92 | bool has_id = false; | ||
83 | 93 | ||
84 | std::vector<DoorIdentifier> doors_referenced_by; | 94 | std::vector<DoorIdentifier> doors_referenced_by; |
85 | }; | 95 | }; |
@@ -88,14 +98,34 @@ using LetterIdentifier = std::tuple<char, bool>; | |||
88 | 98 | ||
89 | struct LetterInfo { | 99 | struct LetterInfo { |
90 | std::vector<RoomIdentifier> defined_in; | 100 | std::vector<RoomIdentifier> defined_in; |
101 | bool has_id = false; | ||
91 | }; | 102 | }; |
92 | 103 | ||
93 | struct EndingInfo { | 104 | struct EndingInfo { |
94 | std::vector<RoomIdentifier> defined_in; | 105 | std::vector<RoomIdentifier> defined_in; |
106 | bool has_id = false; | ||
95 | 107 | ||
96 | std::vector<DoorIdentifier> doors_referenced_by; | 108 | std::vector<DoorIdentifier> doors_referenced_by; |
97 | }; | 109 | }; |
98 | 110 | ||
111 | struct PanelNameInfo { | ||
112 | std::vector<PanelIdentifier> panels_used_by; | ||
113 | }; | ||
114 | |||
115 | struct ProgressiveInfo { | ||
116 | std::vector<HumanProgressive> definitions; | ||
117 | bool has_id = false; | ||
118 | |||
119 | std::vector<DoorIdentifier> malformed_doors; | ||
120 | }; | ||
121 | |||
122 | struct DoorGroupInfo { | ||
123 | std::vector<HumanDoorGroup> definitions; | ||
124 | bool has_id = false; | ||
125 | |||
126 | std::vector<DoorIdentifier> malformed_doors; | ||
127 | }; | ||
128 | |||
99 | struct CollectedInfo { | 129 | struct CollectedInfo { |
100 | std::map<std::string, MapInfo> maps; | 130 | std::map<std::string, MapInfo> maps; |
101 | std::map<RoomIdentifier, RoomInfo, RoomIdentifierLess> rooms; | 131 | std::map<RoomIdentifier, RoomInfo, RoomIdentifierLess> rooms; |
@@ -107,6 +137,9 @@ struct CollectedInfo { | |||
107 | keyholders; | 137 | keyholders; |
108 | std::map<LetterIdentifier, LetterInfo> letters; | 138 | std::map<LetterIdentifier, LetterInfo> letters; |
109 | std::map<std::string, EndingInfo> endings; | 139 | std::map<std::string, EndingInfo> endings; |
140 | std::map<std::string, PanelNameInfo> panel_names; | ||
141 | std::map<std::string, ProgressiveInfo> progressives; | ||
142 | std::map<std::string, DoorGroupInfo> door_groups; | ||
110 | }; | 143 | }; |
111 | 144 | ||
112 | } // namespace com::fourisland::lingo2_archipelago | 145 | } // namespace com::fourisland::lingo2_archipelago |
diff --git a/tools/validator/validator.cpp b/tools/validator/validator.cpp index f802460..93efdc6 100644 --- a/tools/validator/validator.cpp +++ b/tools/validator/validator.cpp | |||
@@ -9,291 +9,557 @@ | |||
9 | namespace com::fourisland::lingo2_archipelago { | 9 | namespace com::fourisland::lingo2_archipelago { |
10 | namespace { | 10 | namespace { |
11 | 11 | ||
12 | void ValidateMap(const std::string& map_name, const MapInfo& map_info) { | 12 | class Validator { |
13 | for (const auto& [node_path, node_info] : map_info.game_nodes) { | 13 | public: |
14 | if (node_info.uses > 1) { | 14 | explicit Validator(const CollectedInfo& info) : info_(info) {} |
15 | std::cout << "Map " << map_name << " node " << node_path | ||
16 | << " is used in multiple places." << std::endl; | ||
17 | } else if (node_info.uses == 0) { | ||
18 | std::cout << "Map " << map_name << " node " << node_path | ||
19 | << " is not used." << std::endl; | ||
20 | } | ||
21 | 15 | ||
22 | if (!node_info.defined) { | 16 | void Validate() const { |
23 | std::cout << "Map " << map_name << " node " << node_path | 17 | for (const auto& [map_name, map_info] : info_.maps) { |
24 | << " is not defined in the game file." << std::endl; | 18 | ValidateMap(map_name, map_info); |
19 | } | ||
20 | for (const auto& [room_identifier, room_info] : info_.rooms) { | ||
21 | ValidateRoom(room_identifier, room_info); | ||
22 | } | ||
23 | for (const auto& [door_identifier, door_info] : info_.doors) { | ||
24 | ValidateDoor(door_identifier, door_info); | ||
25 | } | ||
26 | for (const auto& [port_identifier, port_info] : info_.ports) { | ||
27 | ValidatePort(port_identifier, port_info); | ||
28 | } | ||
29 | for (const auto& [painting_identifier, painting_info] : info_.paintings) { | ||
30 | ValidatePainting(painting_identifier, painting_info); | ||
31 | } | ||
32 | for (const auto& [panel_identifier, panel_info] : info_.panels) { | ||
33 | ValidatePanel(panel_identifier, panel_info); | ||
34 | } | ||
35 | for (const auto& [keyholder_identifier, keyholder_info] : | ||
36 | info_.keyholders) { | ||
37 | ValidateKeyholder(keyholder_identifier, keyholder_info); | ||
38 | } | ||
39 | for (const auto& [letter_identifier, letter_info] : info_.letters) { | ||
40 | ValidateLetter(letter_identifier, letter_info); | ||
41 | } | ||
42 | for (const auto& [ending_name, ending_info] : info_.endings) { | ||
43 | ValidateEnding(ending_name, ending_info); | ||
44 | } | ||
45 | for (const auto& [panel_name, panel_info] : info_.panel_names) { | ||
46 | ValidatePanelName(panel_name, panel_info); | ||
47 | } | ||
48 | for (const auto& [prog_name, prog_info] : info_.progressives) { | ||
49 | ValidateProgressive(prog_name, prog_info); | ||
50 | } | ||
51 | for (const auto& [group_name, group_info] : info_.door_groups) { | ||
52 | ValidateDoorGroup(group_name, group_info); | ||
25 | } | 53 | } |
26 | } | 54 | } |
27 | } | ||
28 | 55 | ||
29 | void ValidateRoom(const RoomIdentifier& room_identifier, | 56 | private: |
30 | const RoomInfo& room_info) { | 57 | void ValidateMap(const std::string& map_name, const MapInfo& map_info) const { |
31 | if (room_info.definitions.empty()) { | 58 | for (const auto& [node_path, node_info] : map_info.game_nodes) { |
32 | std::cout << "Room " << room_identifier.ShortDebugString() | 59 | if (node_info.uses > 1) { |
33 | << " has no definition, but was referenced:" << std::endl; | 60 | std::cout << "Map " << map_name << " node " << node_path |
61 | << " is used in multiple places." << std::endl; | ||
62 | } else if (node_info.uses == 0) { | ||
63 | std::cout << "Map " << map_name << " node " << node_path | ||
64 | << " is not used." << std::endl; | ||
65 | } | ||
34 | 66 | ||
35 | for (const DoorIdentifier& door_identifier : | 67 | if (!node_info.defined) { |
36 | room_info.doors_referenced_by) { | 68 | std::cout << "Map " << map_name << " node " << node_path |
37 | std::cout << " DOOR " << door_identifier.ShortDebugString() | 69 | << " is not defined in the game file." << std::endl; |
38 | << std::endl; | 70 | } |
39 | } | 71 | } |
72 | } | ||
40 | 73 | ||
41 | for (const PanelIdentifier& panel_identifier : | 74 | void ValidateRoom(const RoomIdentifier& room_identifier, |
42 | room_info.panels_referenced_by) { | 75 | const RoomInfo& room_info) const { |
43 | std::cout << " PANEL " << panel_identifier.ShortDebugString() | 76 | if (room_info.definitions.empty()) { |
44 | << std::endl; | 77 | std::cout << "Room " << room_identifier.ShortDebugString() |
45 | } | 78 | << " has no definition, but was referenced:" << std::endl; |
46 | 79 | ||
47 | for (const HumanConnection& connection : | 80 | for (const DoorIdentifier& door_identifier : |
48 | room_info.connections_referenced_by) { | 81 | room_info.doors_referenced_by) { |
49 | std::cout << " CONNECTION " << connection.ShortDebugString() | 82 | std::cout << " DOOR " << door_identifier.ShortDebugString() |
50 | << std::endl; | 83 | << std::endl; |
84 | } | ||
85 | |||
86 | for (const PanelIdentifier& panel_identifier : | ||
87 | room_info.panels_referenced_by) { | ||
88 | std::cout << " PANEL " << panel_identifier.ShortDebugString() | ||
89 | << std::endl; | ||
90 | } | ||
91 | |||
92 | for (const HumanConnection& connection : | ||
93 | room_info.connections_referenced_by) { | ||
94 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
95 | << std::endl; | ||
96 | } | ||
97 | } else if (room_info.definitions.size() > 1) { | ||
98 | std::cout << "Room " << room_identifier.ShortDebugString() | ||
99 | << " was defined multiple times." << std::endl; | ||
51 | } | 100 | } |
52 | } else if (room_info.definitions.size() > 1) { | ||
53 | std::cout << "Room " << room_identifier.ShortDebugString() | ||
54 | << " was defined multiple times." << std::endl; | ||
55 | } | 101 | } |
56 | } | ||
57 | |||
58 | void ValidateDoor(const DoorIdentifier& door_identifier, | ||
59 | const DoorInfo& door_info) { | ||
60 | if (door_info.definitions.empty()) { | ||
61 | std::cout << "Door " << door_identifier.ShortDebugString() | ||
62 | << " has no definition, but was referenced:" << std::endl; | ||
63 | 102 | ||
64 | for (const DoorIdentifier& other_door_identifier : | 103 | bool DoesDoorNeedLocationName(const HumanDoor& h_door, |
65 | door_info.doors_referenced_by) { | 104 | const std::string& map_name) const { |
66 | std::cout << " DOOR " << other_door_identifier.ShortDebugString() | 105 | if (h_door.type() != DoorType::STANDARD) { |
67 | << std::endl; | 106 | return false; |
68 | } | 107 | } |
69 | 108 | ||
70 | for (const PanelIdentifier& panel_identifier : | 109 | if (h_door.keyholders_size() > 0 || h_door.endings_size() > 0 || |
71 | door_info.panels_referenced_by) { | 110 | h_door.complete_at() > 0) { |
72 | std::cout << " PANEL " << panel_identifier.ShortDebugString() | 111 | return true; |
73 | << std::endl; | ||
74 | } | 112 | } |
75 | 113 | ||
76 | for (const PaintingIdentifier& painting_identifier : | 114 | if (h_door.panels_size() > 4) { |
77 | door_info.paintings_referenced_by) { | 115 | return true; |
78 | std::cout << " PAINTING " << painting_identifier.ShortDebugString() | ||
79 | << std::endl; | ||
80 | } | 116 | } |
81 | 117 | ||
82 | for (const PortIdentifier& port_identifier : | 118 | std::set<std::string> map_areas; |
83 | door_info.ports_referenced_by) { | 119 | for (const PanelIdentifier& pi : h_door.panels()) { |
84 | std::cout << " PORT " << port_identifier.ShortDebugString() | 120 | auto full_pi = |
85 | << std::endl; | 121 | GetCompletePanelIdentifierWithoutAnswer(pi, map_name, std::nullopt); |
122 | if (full_pi) { | ||
123 | auto panel_info_it = info_.panels.find(*full_pi); | ||
124 | if (panel_info_it != info_.panels.end()) { | ||
125 | const PanelInfo& panel_info = panel_info_it->second; | ||
126 | |||
127 | map_areas.insert(panel_info.map_area_name); | ||
128 | } | ||
129 | } | ||
86 | } | 130 | } |
87 | 131 | ||
88 | for (const HumanConnection& connection : | 132 | if (map_areas.size() > 1) { |
89 | door_info.connections_referenced_by) { | 133 | return true; |
90 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
91 | << std::endl; | ||
92 | } | 134 | } |
93 | } else if (door_info.definitions.size() > 1) { | 135 | |
94 | std::cout << "Door " << door_identifier.ShortDebugString() | 136 | return false; |
95 | << " was defined multiple times." << std::endl; | ||
96 | } | 137 | } |
97 | 138 | ||
98 | if (door_info.malformed_identifiers.HasAny()) { | 139 | void ValidateDoor(const DoorIdentifier& door_identifier, |
99 | std::cout << "Door " << door_identifier.ShortDebugString() | 140 | const DoorInfo& door_info) const { |
100 | << " has malformed identifiers:" << std::endl; | 141 | if (door_info.definitions.empty()) { |
142 | std::cout << "Door " << door_identifier.ShortDebugString() | ||
143 | << " has no definition, but was referenced:" << std::endl; | ||
101 | 144 | ||
102 | for (const PaintingIdentifier& painting_identifier : | 145 | for (const DoorIdentifier& other_door_identifier : |
103 | door_info.malformed_identifiers.paintings) { | 146 | door_info.doors_referenced_by) { |
104 | std::cout << " PAINTING " << painting_identifier.ShortDebugString() | 147 | std::cout << " DOOR " << other_door_identifier.ShortDebugString() |
105 | << std::endl; | 148 | << std::endl; |
106 | } | 149 | } |
107 | 150 | ||
108 | for (const PanelIdentifier& panel_identifier : | 151 | for (const PanelIdentifier& panel_identifier : |
109 | door_info.malformed_identifiers.panels) { | 152 | door_info.panels_referenced_by) { |
110 | std::cout << " PANEL " << panel_identifier.ShortDebugString() | 153 | std::cout << " PANEL " << panel_identifier.ShortDebugString() |
111 | << std::endl; | 154 | << std::endl; |
155 | } | ||
156 | |||
157 | for (const PaintingIdentifier& painting_identifier : | ||
158 | door_info.paintings_referenced_by) { | ||
159 | std::cout << " PAINTING " << painting_identifier.ShortDebugString() | ||
160 | << std::endl; | ||
161 | } | ||
162 | |||
163 | for (const PortIdentifier& port_identifier : | ||
164 | door_info.ports_referenced_by) { | ||
165 | std::cout << " PORT " << port_identifier.ShortDebugString() | ||
166 | << std::endl; | ||
167 | } | ||
168 | |||
169 | for (const HumanConnection& connection : | ||
170 | door_info.connections_referenced_by) { | ||
171 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
172 | << std::endl; | ||
173 | } | ||
174 | |||
175 | for (const std::string& prog_name : | ||
176 | door_info.progressives_referenced_by) { | ||
177 | std::cout << " PROGRESSIVE " << prog_name << std::endl; | ||
178 | } | ||
179 | |||
180 | for (const std::string& group_name : | ||
181 | door_info.door_groups_referenced_by) { | ||
182 | std::cout << " DOOR GROUP " << group_name << std::endl; | ||
183 | } | ||
184 | |||
185 | if (door_info.has_id) { | ||
186 | std::cout << " An AP ID is present." << std::endl; | ||
187 | } | ||
188 | } else if (door_info.definitions.size() > 1) { | ||
189 | std::cout << "Door " << door_identifier.ShortDebugString() | ||
190 | << " was defined multiple times." << std::endl; | ||
112 | } | 191 | } |
113 | 192 | ||
114 | for (const KeyholderIdentifier& keyholder_identifier : | 193 | if (door_info.malformed_identifiers.HasAny()) { |
115 | door_info.malformed_identifiers.keyholders) { | 194 | std::cout << "Door " << door_identifier.ShortDebugString() |
116 | std::cout << " KEYHOLDER " << keyholder_identifier.ShortDebugString() | 195 | << " has malformed identifiers:" << std::endl; |
117 | << std::endl; | 196 | |
197 | for (const PaintingIdentifier& painting_identifier : | ||
198 | door_info.malformed_identifiers.paintings) { | ||
199 | std::cout << " PAINTING " << painting_identifier.ShortDebugString() | ||
200 | << std::endl; | ||
201 | } | ||
202 | |||
203 | for (const PanelIdentifier& panel_identifier : | ||
204 | door_info.malformed_identifiers.panels) { | ||
205 | std::cout << " PANEL " << panel_identifier.ShortDebugString() | ||
206 | << std::endl; | ||
207 | } | ||
208 | |||
209 | for (const KeyholderIdentifier& keyholder_identifier : | ||
210 | door_info.malformed_identifiers.keyholders) { | ||
211 | std::cout << " KEYHOLDER " << keyholder_identifier.ShortDebugString() | ||
212 | << std::endl; | ||
213 | } | ||
118 | } | 214 | } |
119 | } | ||
120 | } | ||
121 | 215 | ||
122 | void ValidatePort(const PortIdentifier& port_identifier, | 216 | for (const HumanDoor& h_door : door_info.definitions) { |
123 | const PortInfo& port_info) { | 217 | if (DoesDoorNeedLocationName(h_door, door_identifier.map()) && |
124 | if (port_info.definitions.empty()) { | 218 | !h_door.has_location_name()) { |
125 | std::cout << "Port " << port_identifier.ShortDebugString() | 219 | std::cout << "Door " << door_identifier.ShortDebugString() |
126 | << " has no definition, but was referenced:" << std::endl; | 220 | << " needs an explicit location name." << std::endl; |
221 | } | ||
127 | 222 | ||
128 | for (const HumanConnection& connection : | 223 | if (h_door.double_letters() && |
129 | port_info.connections_referenced_by) { | 224 | (h_door.type() == DoorType::STANDARD || |
130 | std::cout << " CONNECTION " << connection.ShortDebugString() | 225 | h_door.type() == DoorType::LOCATION_ONLY || |
131 | << std::endl; | 226 | h_door.type() == DoorType::GRAVESTONE)) { |
227 | std::cout << "Door " << door_identifier.ShortDebugString() | ||
228 | << " is a location that depends on double_letters." | ||
229 | << std::endl; | ||
230 | } | ||
231 | |||
232 | bool needs_id = (h_door.type() != DoorType::EVENT); | ||
233 | if (door_info.has_id != needs_id) { | ||
234 | if (needs_id) { | ||
235 | std::cout << "Door " << door_identifier.ShortDebugString() | ||
236 | << " is missing an AP ID." << std::endl; | ||
237 | } else { | ||
238 | std::cout << "Door " << door_identifier.ShortDebugString() | ||
239 | << " should not have an AP ID." << std::endl; | ||
240 | } | ||
241 | } | ||
132 | } | 242 | } |
133 | } else if (port_info.definitions.size() > 1) { | ||
134 | std::cout << "Port " << port_identifier.ShortDebugString() | ||
135 | << " was defined multiple times." << std::endl; | ||
136 | } | 243 | } |
137 | } | ||
138 | 244 | ||
139 | void ValidatePainting(const PaintingIdentifier& painting_identifier, | 245 | void ValidatePort(const PortIdentifier& port_identifier, |
140 | const PaintingInfo& painting_info) { | 246 | const PortInfo& port_info) const { |
141 | if (painting_info.definitions.empty()) { | 247 | if (port_info.definitions.empty()) { |
142 | std::cout << "Painting " << painting_identifier.ShortDebugString() | 248 | std::cout << "Port " << port_identifier.ShortDebugString() |
143 | << " has no definition, but was referenced:" << std::endl; | 249 | << " has no definition, but was referenced:" << std::endl; |
144 | 250 | ||
145 | for (const DoorIdentifier& door_identifier : | 251 | for (const HumanConnection& connection : |
146 | painting_info.doors_referenced_by) { | 252 | port_info.connections_referenced_by) { |
147 | std::cout << " DOOR " << door_identifier.ShortDebugString() | 253 | std::cout << " CONNECTION " << connection.ShortDebugString() |
148 | << std::endl; | 254 | << std::endl; |
255 | } | ||
256 | } else if (port_info.definitions.size() > 1) { | ||
257 | std::cout << "Port " << port_identifier.ShortDebugString() | ||
258 | << " was defined multiple times." << std::endl; | ||
149 | } | 259 | } |
150 | 260 | ||
151 | for (const HumanConnection& connection : | 261 | if (!port_info.target_connections_referenced_by.empty()) { |
152 | painting_info.connections_referenced_by) { | 262 | for (const HumanPort& port : port_info.definitions) { |
153 | std::cout << " CONNECTION " << connection.ShortDebugString() | 263 | if (port.has_required_door()) { |
154 | << std::endl; | 264 | std::cout << "Port " << port_identifier.ShortDebugString() |
265 | << " has a required door but is the target of a connection:" | ||
266 | << std::endl; | ||
267 | |||
268 | for (const HumanConnection& connection : | ||
269 | port_info.target_connections_referenced_by) { | ||
270 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
271 | << std::endl; | ||
272 | } | ||
273 | } | ||
274 | } | ||
155 | } | 275 | } |
156 | } else if (painting_info.definitions.size() > 1) { | ||
157 | std::cout << "Painting " << painting_identifier.ShortDebugString() | ||
158 | << " was defined multiple times." << std::endl; | ||
159 | } | ||
160 | } | ||
161 | 276 | ||
162 | void ValidatePanel(const PanelIdentifier& panel_identifier, | 277 | for (const HumanPort& port : port_info.definitions) { |
163 | const PanelInfo& panel_info) { | 278 | if (!port.no_shuffle()) { |
164 | if (panel_identifier.name().empty()) { | 279 | if (!port.has_destination()) { |
165 | std::cout << "Panel " << panel_identifier.ShortDebugString() | 280 | std::cout << "Port " << port_identifier.ShortDebugString() |
166 | << " has no name." << std::endl; | 281 | << " is shuffleable and missing a destination." |
282 | << std::endl; | ||
283 | } | ||
284 | if (!port.has_rotation()) { | ||
285 | std::cout << "Port " << port_identifier.ShortDebugString() | ||
286 | << " is shuffleable and missing a rotation." | ||
287 | << std::endl; | ||
288 | } | ||
289 | } | ||
290 | } | ||
167 | } | 291 | } |
168 | 292 | ||
169 | if (panel_info.definitions.empty()) { | 293 | void ValidatePainting(const PaintingIdentifier& painting_identifier, |
170 | std::cout << "Panel " << panel_identifier.ShortDebugString() | 294 | const PaintingInfo& painting_info) const { |
171 | << " has no definition, but was referenced:" << std::endl; | 295 | if (painting_info.definitions.empty()) { |
296 | std::cout << "Painting " << painting_identifier.ShortDebugString() | ||
297 | << " has no definition, but was referenced:" << std::endl; | ||
172 | 298 | ||
173 | for (const DoorIdentifier& door_identifier : | 299 | for (const DoorIdentifier& door_identifier : |
174 | panel_info.doors_referenced_by) { | 300 | painting_info.doors_referenced_by) { |
175 | std::cout << " DOOR " << door_identifier.ShortDebugString() | 301 | std::cout << " DOOR " << door_identifier.ShortDebugString() |
176 | << std::endl; | 302 | << std::endl; |
303 | } | ||
304 | |||
305 | for (const HumanConnection& connection : | ||
306 | painting_info.connections_referenced_by) { | ||
307 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
308 | << std::endl; | ||
309 | } | ||
310 | } else if (painting_info.definitions.size() > 1) { | ||
311 | std::cout << "Painting " << painting_identifier.ShortDebugString() | ||
312 | << " was defined multiple times." << std::endl; | ||
177 | } | 313 | } |
178 | 314 | ||
179 | for (const HumanConnection& connection : | 315 | if (!painting_info.target_connections_referenced_by.empty()) { |
180 | panel_info.connections_referenced_by) { | 316 | for (const HumanPainting& painting : painting_info.definitions) { |
181 | std::cout << " CONNECTION " << connection.ShortDebugString() | 317 | if (painting.has_required_door()) { |
182 | << std::endl; | 318 | std::cout << "Painting " << painting_identifier.ShortDebugString() |
319 | << " has a required door but is the target of a connection:" | ||
320 | << std::endl; | ||
321 | |||
322 | for (const HumanConnection& connection : | ||
323 | painting_info.target_connections_referenced_by) { | ||
324 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
325 | << std::endl; | ||
326 | } | ||
327 | } | ||
328 | } | ||
183 | } | 329 | } |
184 | } else if (panel_info.definitions.size() > 1) { | ||
185 | std::cout << "Panel " << panel_identifier.ShortDebugString() | ||
186 | << " was defined multiple times." << std::endl; | ||
187 | } | 330 | } |
188 | 331 | ||
189 | for (const auto& [answer, proxy_info] : panel_info.proxies) { | 332 | void ValidatePanel(const PanelIdentifier& panel_identifier, |
190 | if (proxy_info.definitions.empty()) { | 333 | const PanelInfo& panel_info) const { |
334 | if (panel_identifier.name().empty()) { | ||
191 | std::cout << "Panel " << panel_identifier.ShortDebugString() | 335 | std::cout << "Panel " << panel_identifier.ShortDebugString() |
192 | << " with answer \"" << answer | 336 | << " has no name." << std::endl; |
193 | << "\" has no definition, but was referenced:" << std::endl; | 337 | } |
338 | |||
339 | if (panel_info.definitions.empty()) { | ||
340 | std::cout << "Panel " << panel_identifier.ShortDebugString() | ||
341 | << " has no definition, but was referenced:" << std::endl; | ||
194 | 342 | ||
195 | for (const DoorIdentifier& door_identifier : | 343 | for (const DoorIdentifier& door_identifier : |
196 | proxy_info.doors_referenced_by) { | 344 | panel_info.doors_referenced_by) { |
197 | std::cout << " DOOR " << door_identifier.ShortDebugString() | 345 | std::cout << " DOOR " << door_identifier.ShortDebugString() |
198 | << std::endl; | 346 | << std::endl; |
199 | } | 347 | } |
200 | 348 | ||
201 | for (const HumanConnection& connection : | 349 | for (const HumanConnection& connection : |
202 | proxy_info.connections_referenced_by) { | 350 | panel_info.connections_referenced_by) { |
203 | std::cout << " CONNECTION " << connection.ShortDebugString() | 351 | std::cout << " CONNECTION " << connection.ShortDebugString() |
204 | << std::endl; | 352 | << std::endl; |
205 | } | 353 | } |
206 | } else if (proxy_info.definitions.size() > 1) { | 354 | |
355 | if (panel_info.has_id) { | ||
356 | std::cout << " An AP ID is present." << std::endl; | ||
357 | } | ||
358 | } else if (panel_info.definitions.size() > 1) { | ||
359 | std::cout << "Panel " << panel_identifier.ShortDebugString() | ||
360 | << " was defined multiple times." << std::endl; | ||
361 | } | ||
362 | |||
363 | for (const auto& [answer, proxy_info] : panel_info.proxies) { | ||
364 | if (proxy_info.definitions.empty()) { | ||
365 | std::cout << "Panel " << panel_identifier.ShortDebugString() | ||
366 | << " with answer \"" << answer | ||
367 | << "\" has no definition, but was referenced:" << std::endl; | ||
368 | |||
369 | for (const DoorIdentifier& door_identifier : | ||
370 | proxy_info.doors_referenced_by) { | ||
371 | std::cout << " DOOR " << door_identifier.ShortDebugString() | ||
372 | << std::endl; | ||
373 | } | ||
374 | |||
375 | for (const HumanConnection& connection : | ||
376 | proxy_info.connections_referenced_by) { | ||
377 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
378 | << std::endl; | ||
379 | } | ||
380 | } else if (proxy_info.definitions.size() > 1) { | ||
381 | std::cout << "Panel " << panel_identifier.ShortDebugString() | ||
382 | << " with answer \"" << answer | ||
383 | << "\" was defined multiple times." << std::endl; | ||
384 | } | ||
385 | } | ||
386 | |||
387 | if (!panel_info.has_id) { | ||
207 | std::cout << "Panel " << panel_identifier.ShortDebugString() | 388 | std::cout << "Panel " << panel_identifier.ShortDebugString() |
208 | << " with answer \"" << answer | 389 | << " is missing an AP ID." << std::endl; |
209 | << "\" was defined multiple times." << std::endl; | 390 | } |
391 | |||
392 | if (!panel_info.target_connections_referenced_by.empty()) { | ||
393 | for (const HumanPanel& panel : panel_info.definitions) { | ||
394 | if (panel.has_required_door()) { | ||
395 | std::cout << "Panel " << panel_identifier.ShortDebugString() | ||
396 | << " has a required door but is the target of a connection:" | ||
397 | << std::endl; | ||
398 | |||
399 | for (const HumanConnection& connection : | ||
400 | panel_info.target_connections_referenced_by) { | ||
401 | std::cout << " CONNECTION " << connection.ShortDebugString() | ||
402 | << std::endl; | ||
403 | } | ||
404 | } | ||
405 | } | ||
210 | } | 406 | } |
211 | } | 407 | } |
212 | } | ||
213 | 408 | ||
214 | void ValidateKeyholder(const KeyholderIdentifier& keyholder_identifier, | 409 | void ValidateKeyholder(const KeyholderIdentifier& keyholder_identifier, |
215 | const KeyholderInfo& keyholder_info) { | 410 | const KeyholderInfo& keyholder_info) const { |
216 | if (keyholder_info.definitions.empty()) { | 411 | if (keyholder_info.definitions.empty()) { |
217 | std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() | 412 | std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() |
218 | << " has no definition, but was referenced:" << std::endl; | 413 | << " has no definition, but was referenced:" << std::endl; |
414 | |||
415 | for (const DoorIdentifier& door_identifier : | ||
416 | keyholder_info.doors_referenced_by) { | ||
417 | std::cout << " DOOR " << door_identifier.ShortDebugString() | ||
418 | << std::endl; | ||
419 | } | ||
420 | |||
421 | if (keyholder_info.has_id) { | ||
422 | std::cout << " An AP ID is present." << std::endl; | ||
423 | } | ||
424 | } else if (keyholder_info.definitions.size() > 1) { | ||
425 | std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() | ||
426 | << " was defined multiple times." << std::endl; | ||
427 | } | ||
428 | |||
429 | for (const HumanKeyholder& h_keyholder : keyholder_info.definitions) { | ||
430 | bool needs_id = (h_keyholder.has_key()); | ||
431 | |||
432 | if (needs_id != keyholder_info.has_id) { | ||
433 | if (needs_id) { | ||
434 | std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() | ||
435 | << " is missing an AP ID." << std::endl; | ||
436 | } else { | ||
437 | std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() | ||
438 | << " should not have an AP ID." << std::endl; | ||
439 | } | ||
440 | } | ||
441 | } | ||
442 | } | ||
443 | |||
444 | void ValidateLetter(const LetterIdentifier& letter_identifier, | ||
445 | const LetterInfo& letter_info) const { | ||
446 | std::string letter_name = std::string(1, std::get<0>(letter_identifier)) + | ||
447 | (std::get<1>(letter_identifier) ? "2" : "1"); | ||
448 | |||
449 | if (letter_info.defined_in.empty()) { | ||
450 | std::cout << "Letter " << letter_name | ||
451 | << " has no definition, but was referenced:" << std::endl; | ||
219 | 452 | ||
220 | for (const DoorIdentifier& door_identifier : | 453 | if (letter_info.has_id) { |
221 | keyholder_info.doors_referenced_by) { | 454 | std::cout << " An AP ID is present." << std::endl; |
222 | std::cout << " DOOR " << door_identifier.ShortDebugString() | 455 | } |
456 | } else if (letter_info.defined_in.size() > 1) { | ||
457 | std::cout << "Letter " << letter_name | ||
458 | << " was defined in multiple places:" << std::endl; | ||
459 | |||
460 | for (const RoomIdentifier& room_identifier : letter_info.defined_in) { | ||
461 | std::cout << " " << room_identifier.ShortDebugString() << std::endl; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | if (!letter_info.has_id) { | ||
466 | std::cout << "Letter " << letter_name << " is missing an AP ID." | ||
223 | << std::endl; | 467 | << std::endl; |
224 | } | 468 | } |
225 | } else if (keyholder_info.definitions.size() > 1) { | ||
226 | std::cout << "Keyholder " << keyholder_identifier.ShortDebugString() | ||
227 | << " was defined multiple times." << std::endl; | ||
228 | } | 469 | } |
229 | } | ||
230 | 470 | ||
231 | void ValidateLetter(const LetterIdentifier& letter_identifier, | 471 | void ValidateEnding(const std::string& ending_name, |
232 | const LetterInfo& letter_info) { | 472 | const EndingInfo& ending_info) const { |
233 | std::string letter_name = std::string(1, std::get<0>(letter_identifier)) + | 473 | if (ending_info.defined_in.empty()) { |
234 | (std::get<1>(letter_identifier) ? "2" : "1"); | 474 | std::cout << "Ending " << ending_name |
475 | << " has no definition, but was referenced:" << std::endl; | ||
235 | 476 | ||
236 | if (letter_info.defined_in.size() > 1) { | 477 | for (const DoorIdentifier& door_identifier : |
237 | std::cout << "Letter " << letter_name | 478 | ending_info.doors_referenced_by) { |
238 | << " was defined in multiple places:" << std::endl; | 479 | std::cout << " DOOR " << door_identifier.ShortDebugString() |
480 | << std::endl; | ||
481 | } | ||
482 | |||
483 | if (ending_info.has_id) { | ||
484 | std::cout << " An AP ID is present." << std::endl; | ||
485 | } | ||
486 | } else if (ending_info.defined_in.size() > 1) { | ||
487 | std::cout << "Ending " << ending_name | ||
488 | << " was defined in multiple places:" << std::endl; | ||
239 | 489 | ||
240 | for (const RoomIdentifier& room_identifier : letter_info.defined_in) { | 490 | for (const RoomIdentifier& room_identifier : ending_info.defined_in) { |
241 | std::cout << " " << room_identifier.ShortDebugString() << std::endl; | 491 | std::cout << " " << room_identifier.ShortDebugString() << std::endl; |
492 | } | ||
493 | } | ||
494 | |||
495 | if (!ending_info.has_id) { | ||
496 | std::cout << "Ending " << ending_name << " is missing an AP ID." | ||
497 | << std::endl; | ||
242 | } | 498 | } |
243 | } | 499 | } |
244 | } | ||
245 | 500 | ||
246 | void ValidateEnding(const std::string& ending_name, | 501 | void ValidatePanelName(const std::string& panel_name, |
247 | const EndingInfo& ending_info) { | 502 | const PanelNameInfo& panel_info) const { |
248 | if (ending_info.defined_in.empty()) { | 503 | if (panel_info.panels_used_by.size() > 1) { |
249 | std::cout << "Ending " << ending_name | 504 | std::cout << "The location name \"" << panel_name |
250 | << " has no definition, but was referenced:" << std::endl; | 505 | << "\" is used by multiple panels:" << std::endl; |
251 | 506 | ||
252 | for (const DoorIdentifier& door_identifier : | 507 | for (const PanelIdentifier& panel_identifier : |
253 | ending_info.doors_referenced_by) { | 508 | panel_info.panels_used_by) { |
254 | std::cout << " DOOR " << door_identifier.ShortDebugString() | 509 | std::cout << " PANEL " << panel_identifier.ShortDebugString() |
510 | << std::endl; | ||
511 | } | ||
512 | } | ||
513 | } | ||
514 | |||
515 | void ValidateProgressive(const std::string& prog_name, | ||
516 | const ProgressiveInfo& prog_info) const { | ||
517 | if (prog_info.definitions.empty()) { | ||
518 | std::cout << "Progressive \"" << prog_name | ||
519 | << "\" has no definition, but was referenced:" << std::endl; | ||
520 | |||
521 | if (prog_info.has_id) { | ||
522 | std::cout << " An AP ID is present." << std::endl; | ||
523 | } | ||
524 | } else if (prog_info.definitions.size() > 1) { | ||
525 | std::cout << "Progressive \"" << prog_name | ||
526 | << "\" has multiple definitions." << std::endl; | ||
527 | } | ||
528 | |||
529 | if (!prog_info.has_id) { | ||
530 | std::cout << "Progressive \"" << prog_name << "\" is missing an AP ID." | ||
255 | << std::endl; | 531 | << std::endl; |
256 | } | 532 | } |
257 | } else if (ending_info.defined_in.size() > 1) { | 533 | } |
258 | std::cout << "Ending " << ending_name | ||
259 | << " was defined in multiple places:" << std::endl; | ||
260 | 534 | ||
261 | for (const RoomIdentifier& room_identifier : ending_info.defined_in) { | 535 | void ValidateDoorGroup(const std::string& group_name, |
262 | std::cout << " " << room_identifier.ShortDebugString() << std::endl; | 536 | const DoorGroupInfo& group_info) const { |
537 | if (group_info.definitions.empty()) { | ||
538 | std::cout << "Door group \"" << group_name | ||
539 | << "\" has no definition, but was referenced:" << std::endl; | ||
540 | |||
541 | if (group_info.has_id) { | ||
542 | std::cout << " An AP ID is present." << std::endl; | ||
543 | } | ||
544 | } else if (group_info.definitions.size() > 1) { | ||
545 | std::cout << "Door group \"" << group_name | ||
546 | << "\" has multiple definitions." << std::endl; | ||
547 | } | ||
548 | |||
549 | if (!group_info.has_id) { | ||
550 | std::cout << "Door group \"" << group_name << "\" is missing an AP ID." | ||
551 | << std::endl; | ||
263 | } | 552 | } |
264 | } | 553 | } |
265 | } | 554 | |
555 | const CollectedInfo& info_; | ||
556 | }; | ||
266 | 557 | ||
267 | } // namespace | 558 | } // namespace |
268 | 559 | ||
269 | void ValidateCollectedInfo(const CollectedInfo& info) { | 560 | void ValidateCollectedInfo(const CollectedInfo& info) { |
270 | for (const auto& [map_name, map_info] : info.maps) { | 561 | Validator validator(info); |
271 | ValidateMap(map_name, map_info); | 562 | validator.Validate(); |
272 | } | ||
273 | for (const auto& [room_identifier, room_info] : info.rooms) { | ||
274 | ValidateRoom(room_identifier, room_info); | ||
275 | } | ||
276 | for (const auto& [door_identifier, door_info] : info.doors) { | ||
277 | ValidateDoor(door_identifier, door_info); | ||
278 | } | ||
279 | for (const auto& [port_identifier, port_info] : info.ports) { | ||
280 | ValidatePort(port_identifier, port_info); | ||
281 | } | ||
282 | for (const auto& [painting_identifier, painting_info] : info.paintings) { | ||
283 | ValidatePainting(painting_identifier, painting_info); | ||
284 | } | ||
285 | for (const auto& [panel_identifier, panel_info] : info.panels) { | ||
286 | ValidatePanel(panel_identifier, panel_info); | ||
287 | } | ||
288 | for (const auto& [keyholder_identifier, keyholder_info] : info.keyholders) { | ||
289 | ValidateKeyholder(keyholder_identifier, keyholder_info); | ||
290 | } | ||
291 | for (const auto& [letter_identifier, letter_info] : info.letters) { | ||
292 | ValidateLetter(letter_identifier, letter_info); | ||
293 | } | ||
294 | for (const auto& [ending_name, ending_info] : info.endings) { | ||
295 | ValidateEnding(ending_name, ending_info); | ||
296 | } | ||
297 | } | 563 | } |
298 | 564 | ||
299 | } // namespace com::fourisland::lingo2_archipelago | 565 | } // namespace com::fourisland::lingo2_archipelago |
diff --git a/tools/validator/validator.h b/tools/validator/validator.h index b710429..33bc7c9 100644 --- a/tools/validator/validator.h +++ b/tools/validator/validator.h | |||
@@ -1,4 +1,4 @@ | |||
1 | #ifndef TOOLS_VALIDATOR_VALIDATOR_H_ | 1 | #ifndef TOOLS_VALIDATOR_VALIDATOR_H |
2 | #define TOOLS_VALIDATOR_VALIDATOR_H | 2 | #define TOOLS_VALIDATOR_VALIDATOR_H |
3 | 3 | ||
4 | namespace com::fourisland::lingo2_archipelago { | 4 | namespace com::fourisland::lingo2_archipelago { |
diff --git a/vcpkg.json b/vcpkg.json index 6517f7e..ba6833f 100644 --- a/vcpkg.json +++ b/vcpkg.json | |||
@@ -1,12 +1,13 @@ | |||
1 | { | 1 | { |
2 | "dependencies": [ | 2 | "dependencies": [ |
3 | "fmt", | ||
3 | "protobuf", | 4 | "protobuf", |
4 | "yaml-cpp" | 5 | "yaml-cpp" |
5 | ], | 6 | ], |
6 | "overrides": [ | 7 | "overrides": [ |
7 | { | 8 | { |
8 | "name": "protobuf", | 9 | "name": "protobuf", |
9 | "version": "5.29.3" | 10 | "version": "3.21.12" |
10 | } | 11 | } |
11 | ] | 12 | ] |
12 | } \ No newline at end of file | 13 | } \ No newline at end of file |
diff --git a/vendor/godobuf/LICENSE b/vendor/godobuf/LICENSE new file mode 100644 index 0000000..5d473d8 --- /dev/null +++ b/vendor/godobuf/LICENSE | |||
@@ -0,0 +1,29 @@ | |||
1 | BSD 3-Clause License | ||
2 | |||
3 | Copyright (c) 2018, oniksan | ||
4 | All rights reserved. | ||
5 | |||
6 | Redistribution and use in source and binary forms, with or without | ||
7 | modification, are permitted provided that the following conditions are met: | ||
8 | |||
9 | * Redistributions of source code must retain the above copyright notice, this | ||
10 | list of conditions and the following disclaimer. | ||
11 | |||
12 | * Redistributions in binary form must reproduce the above copyright notice, | ||
13 | this list of conditions and the following disclaimer in the documentation | ||
14 | and/or other materials provided with the distribution. | ||
15 | |||
16 | * Neither the name of the copyright holder nor the names of its | ||
17 | contributors may be used to endorse or promote products derived from | ||
18 | this software without specific prior written permission. | ||
19 | |||
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
diff --git a/vendor/godobuf/README b/vendor/godobuf/README new file mode 100644 index 0000000..ce716bb --- /dev/null +++ b/vendor/godobuf/README | |||
@@ -0,0 +1,4 @@ | |||
1 | This is a fork of https://github.com/oniksan/godobuf with some minor changes so | ||
2 | that it is able to compile the Lingo 2 randomizer proto files. The plugin parts | ||
3 | of the project have also been removed since we only need the command line | ||
4 | script. | ||
diff --git a/vendor/godobuf/addons/protobuf/parser.gd b/vendor/godobuf/addons/protobuf/parser.gd new file mode 100644 index 0000000..dfc0bdd --- /dev/null +++ b/vendor/godobuf/addons/protobuf/parser.gd | |||
@@ -0,0 +1,2254 @@ | |||
1 | # | ||
2 | # BSD 3-Clause License | ||
3 | # | ||
4 | # Copyright (c) 2018 - 2023, Oleg Malyavkin | ||
5 | # All rights reserved. | ||
6 | # | ||
7 | # Redistribution and use in source and binary forms, with or without | ||
8 | # modification, are permitted provided that the following conditions are met: | ||
9 | # | ||
10 | # * Redistributions of source code must retain the above copyright notice, this | ||
11 | # list of conditions and the following disclaimer. | ||
12 | # | ||
13 | # * Redistributions in binary form must reproduce the above copyright notice, | ||
14 | # this list of conditions and the following disclaimer in the documentation | ||
15 | # and/or other materials provided with the distribution. | ||
16 | # | ||
17 | # * Neither the name of the copyright holder nor the names of its | ||
18 | # contributors may be used to endorse or promote products derived from | ||
19 | # this software without specific prior written permission. | ||
20 | # | ||
21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
29 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | extends Node | ||
33 | |||
34 | const PROTO_VERSION_CONST : String = "const PROTO_VERSION = " | ||
35 | const PROTO_VERSION_DEFAULT : String = PROTO_VERSION_CONST + "0" | ||
36 | |||
37 | class Document: | ||
38 | |||
39 | func _init(doc_name : String, doc_text : String): | ||
40 | name = doc_name | ||
41 | text = doc_text | ||
42 | |||
43 | var name : String | ||
44 | var text : String | ||
45 | |||
46 | class TokenPosition: | ||
47 | func _init(b : int, e : int): | ||
48 | begin = b | ||
49 | end = e | ||
50 | var begin : int = 0 | ||
51 | var end : int = 0 | ||
52 | |||
53 | class Helper: | ||
54 | |||
55 | class StringPosition: | ||
56 | func _init(s : int, c : int, l : int): | ||
57 | str_num = s | ||
58 | column = c | ||
59 | length = l | ||
60 | var str_num : int | ||
61 | var column : int | ||
62 | var length : int | ||
63 | |||
64 | static func str_pos(text : String, position : TokenPosition) -> StringPosition: | ||
65 | var cur_str : int = 1 | ||
66 | var cur_col : int = 1 | ||
67 | var res_str : int = 0 | ||
68 | var res_col : int = 0 | ||
69 | var res_length : int = 0 | ||
70 | for i in range(text.length()): | ||
71 | if text[i] == "\n": | ||
72 | cur_str += 1 | ||
73 | cur_col = 0 | ||
74 | if position.begin == i: | ||
75 | res_str = cur_str | ||
76 | res_col = cur_col | ||
77 | res_length = position.end - position.begin + 1 | ||
78 | break | ||
79 | cur_col += 1 | ||
80 | return StringPosition.new(res_str, res_col, res_length) | ||
81 | |||
82 | static func text_pos(tokens : Array, index : int) -> TokenPosition: | ||
83 | var res_begin : int = 0 | ||
84 | var res_end : int = 0 | ||
85 | if index < tokens.size() && index >= 0: | ||
86 | res_begin = tokens[index].position.begin | ||
87 | res_end = tokens[index].position.end | ||
88 | return TokenPosition.new(res_begin, res_end) | ||
89 | |||
90 | static func error_string(file_name, col, row, error_text): | ||
91 | return file_name + ":" + str(col) + ":" + str(row) + ": error: " + error_text | ||
92 | |||
93 | class AnalyzeResult: | ||
94 | var classes : Array = [] | ||
95 | var fields : Array = [] | ||
96 | var groups : Array = [] | ||
97 | var version : int = 0 | ||
98 | var state : bool = false | ||
99 | var tokens : Array = [] | ||
100 | var syntax : Analysis.TranslationResult | ||
101 | var imports : Array = [] | ||
102 | var doc : Document | ||
103 | |||
104 | func soft_copy() -> AnalyzeResult: | ||
105 | var res : AnalyzeResult = AnalyzeResult.new() | ||
106 | res.classes = classes | ||
107 | res.fields = fields | ||
108 | res.groups = groups | ||
109 | res.version = version | ||
110 | res.state = state | ||
111 | res.tokens = tokens | ||
112 | res.syntax = syntax | ||
113 | res.imports = imports | ||
114 | res.doc = doc | ||
115 | return res | ||
116 | |||
117 | class Analysis: | ||
118 | |||
119 | func _init(path : String, doc : Document): | ||
120 | path_dir = path | ||
121 | document = doc | ||
122 | |||
123 | var document : Document | ||
124 | var path_dir : String | ||
125 | |||
126 | const LEX = { | ||
127 | LETTER = "[A-Za-z]", | ||
128 | DIGIT_DEC = "[0-9]", | ||
129 | DIGIT_OCT = "[0-7]", | ||
130 | DIGIT_HEX = "[0-9]|[A-F]|[a-f]", | ||
131 | BRACKET_ROUND_LEFT = "\\(", | ||
132 | BRACKET_ROUND_RIGHT = "\\)", | ||
133 | BRACKET_CURLY_LEFT = "\\{", | ||
134 | BRACKET_CURLY_RIGHT = "\\}", | ||
135 | BRACKET_SQUARE_LEFT = "\\[", | ||
136 | BRACKET_SQUARE_RIGHT = "\\]", | ||
137 | BRACKET_ANGLE_LEFT = "\\<", | ||
138 | BRACKET_ANGLE_RIGHT = "\\>", | ||
139 | SEMICOLON = ";", | ||
140 | COMMA = ",", | ||
141 | EQUAL = "=", | ||
142 | SIGN = "\\+|\\-", | ||
143 | SPACE = "\\s", | ||
144 | QUOTE_SINGLE = "'", | ||
145 | QUOTE_DOUBLE = "\"", | ||
146 | } | ||
147 | |||
148 | const TOKEN_IDENT : String = "(" + LEX.LETTER + "+" + "(" + LEX.LETTER + "|" + LEX.DIGIT_DEC + "|" + "_)*)" | ||
149 | const TOKEN_FULL_IDENT : String = TOKEN_IDENT + "{0,1}(\\." + TOKEN_IDENT + ")+" | ||
150 | const TOKEN_BRACKET_ROUND_LEFT : String = "(" + LEX.BRACKET_ROUND_LEFT + ")" | ||
151 | const TOKEN_BRACKET_ROUND_RIGHT : String = "(" + LEX.BRACKET_ROUND_RIGHT + ")" | ||
152 | const TOKEN_BRACKET_CURLY_LEFT : String = "(" + LEX.BRACKET_CURLY_LEFT + ")" | ||
153 | const TOKEN_BRACKET_CURLY_RIGHT : String = "(" + LEX.BRACKET_CURLY_RIGHT + ")" | ||
154 | const TOKEN_BRACKET_SQUARE_LEFT : String = "(" + LEX.BRACKET_SQUARE_LEFT + ")" | ||
155 | const TOKEN_BRACKET_SQUARE_RIGHT : String = "(" + LEX.BRACKET_SQUARE_RIGHT + ")" | ||
156 | const TOKEN_BRACKET_ANGLE_LEFT : String = "(" + LEX.BRACKET_ANGLE_LEFT + ")" | ||
157 | const TOKEN_BRACKET_ANGLE_RIGHT : String = "(" + LEX.BRACKET_ANGLE_RIGHT + ")" | ||
158 | const TOKEN_SEMICOLON : String = "(" + LEX.SEMICOLON + ")" | ||
159 | const TOKEN_EUQAL : String = "(" + LEX.EQUAL + ")" | ||
160 | const TOKEN_SIGN : String = "(" + LEX.SIGN + ")" | ||
161 | const TOKEN_LITERAL_DEC : String = "(([1-9])" + LEX.DIGIT_DEC +"*)" | ||
162 | const TOKEN_LITERAL_OCT : String = "(0" + LEX.DIGIT_OCT +"*)" | ||
163 | const TOKEN_LITERAL_HEX : String = "(0(x|X)(" + LEX.DIGIT_HEX +")+)" | ||
164 | const TOKEN_LITERAL_INT : String = "((\\+|\\-){0,1}" + TOKEN_LITERAL_DEC + "|" + TOKEN_LITERAL_OCT + "|" + TOKEN_LITERAL_HEX + ")" | ||
165 | const TOKEN_LITERAL_FLOAT_DEC : String = "(" + LEX.DIGIT_DEC + "+)" | ||
166 | const TOKEN_LITERAL_FLOAT_EXP : String = "((e|E)(\\+|\\-)?" + TOKEN_LITERAL_FLOAT_DEC + "+)" | ||
167 | const TOKEN_LITERAL_FLOAT : String = "((\\+|\\-){0,1}(" + TOKEN_LITERAL_FLOAT_DEC + "\\." + TOKEN_LITERAL_FLOAT_DEC + "?" + TOKEN_LITERAL_FLOAT_EXP + "?)|(" + TOKEN_LITERAL_FLOAT_DEC + TOKEN_LITERAL_FLOAT_EXP + ")|(\\." + TOKEN_LITERAL_FLOAT_DEC + TOKEN_LITERAL_FLOAT_EXP + "?))" | ||
168 | const TOKEN_SPACE : String = "(" + LEX.SPACE + ")+" | ||
169 | const TOKEN_COMMA : String = "(" + LEX.COMMA + ")" | ||
170 | const TOKEN_CHAR_ESC : String = "[\\\\(a|b|f|n|r|t|v|\\\\|'|\")]" | ||
171 | const TOKEN_OCT_ESC : String = "[\\\\" + LEX.DIGIT_OCT + "{3}]" | ||
172 | const TOKEN_HEX_ESC : String = "[\\\\(x|X)" + LEX.DIGIT_HEX + "{2}]" | ||
173 | const TOKEN_CHAR_EXCLUDE : String = "[^\\0\\n\\\\]" | ||
174 | const TOKEN_CHAR_VALUE : String = "(" + TOKEN_HEX_ESC + "|" + TOKEN_OCT_ESC + "|" + TOKEN_CHAR_ESC + "|" + TOKEN_CHAR_EXCLUDE + ")" | ||
175 | const TOKEN_STRING_SINGLE : String = "('" + TOKEN_CHAR_VALUE + "*?')" | ||
176 | const TOKEN_STRING_DOUBLE : String = "(\"" + TOKEN_CHAR_VALUE + "*?\")" | ||
177 | const TOKEN_COMMENT_SINGLE : String = "((//[^\\n\\r]*[^\\s])|//)" | ||
178 | const TOKEN_COMMENT_MULTI : String = "/\\*(.|[\\n\\r])*?\\*/" | ||
179 | |||
180 | const TOKEN_SECOND_MESSAGE : String = "^message$" | ||
181 | const TOKEN_SECOND_SIMPLE_DATA_TYPE : String = "^(double|float|int32|int64|uint32|uint64|sint32|sint64|fixed32|fixed64|sfixed32|sfixed64|bool|string|bytes)$" | ||
182 | const TOKEN_SECOND_ENUM : String = "^enum$" | ||
183 | const TOKEN_SECOND_MAP : String = "^map$" | ||
184 | const TOKEN_SECOND_ONEOF : String = "^oneof$" | ||
185 | const TOKEN_SECOND_LITERAL_BOOL : String = "^(true|false)$" | ||
186 | const TOKEN_SECOND_SYNTAX : String = "^syntax$" | ||
187 | const TOKEN_SECOND_IMPORT : String = "^import$" | ||
188 | const TOKEN_SECOND_PACKAGE : String = "^package$" | ||
189 | const TOKEN_SECOND_OPTION : String = "^option$" | ||
190 | const TOKEN_SECOND_SERVICE : String = "^service$" | ||
191 | const TOKEN_SECOND_RESERVED : String = "^reserved$" | ||
192 | const TOKEN_SECOND_IMPORT_QUALIFICATION : String = "^(weak|public)$" | ||
193 | const TOKEN_SECOND_FIELD_QUALIFICATION : String = "^(repeated|required|optional)$" | ||
194 | const TOKEN_SECOND_ENUM_OPTION : String = "^allow_alias$" | ||
195 | const TOKEN_SECOND_QUALIFICATION : String = "^(custom_option|extensions)$" | ||
196 | const TOKEN_SECOND_FIELD_OPTION : String = "^packed$" | ||
197 | |||
198 | class TokenEntrance: | ||
199 | func _init(i : int, b : int, e : int, t : String): | ||
200 | position = TokenPosition.new(b, e) | ||
201 | text = t | ||
202 | id = i | ||
203 | var position : TokenPosition | ||
204 | var text : String | ||
205 | var id : int | ||
206 | |||
207 | enum RANGE_STATE { | ||
208 | INCLUDE = 0, | ||
209 | EXCLUDE_LEFT = 1, | ||
210 | EXCLUDE_RIGHT = 2, | ||
211 | OVERLAY = 3, | ||
212 | EQUAL = 4, | ||
213 | ENTERS = 5 | ||
214 | } | ||
215 | |||
216 | class TokenRange: | ||
217 | func _init(b : int, e : int, s): | ||
218 | position = TokenPosition.new(b, e) | ||
219 | state = s | ||
220 | var position : TokenPosition | ||
221 | var state | ||
222 | |||
223 | class Token: | ||
224 | var _regex : RegEx | ||
225 | var _entrance : TokenEntrance = null | ||
226 | var _entrances : Array = [] | ||
227 | var _entrance_index : int = 0 | ||
228 | var _id : int | ||
229 | var _ignore : bool | ||
230 | var _clarification : String | ||
231 | |||
232 | func _init(id : int, clarification : String, regex_str : String, ignore = false): | ||
233 | _id = id | ||
234 | _regex = RegEx.new() | ||
235 | _regex.compile(regex_str) | ||
236 | _clarification = clarification | ||
237 | _ignore = ignore | ||
238 | |||
239 | func find(text : String, start : int) -> TokenEntrance: | ||
240 | _entrance = null | ||
241 | if !_regex.is_valid(): | ||
242 | return null | ||
243 | var match_result : RegExMatch = _regex.search(text, start) | ||
244 | if match_result != null: | ||
245 | var capture | ||
246 | capture = match_result.get_string(0) | ||
247 | if capture.is_empty(): | ||
248 | return null | ||
249 | _entrance = TokenEntrance.new(_id, match_result.get_start(0), capture.length() - 1 + match_result.get_start(0), capture) | ||
250 | return _entrance | ||
251 | |||
252 | func find_all(text : String) -> Array: | ||
253 | var pos : int = 0 | ||
254 | clear() | ||
255 | while find(text, pos) != null: | ||
256 | _entrances.append(_entrance) | ||
257 | pos = _entrance.position.end + 1 | ||
258 | return _entrances | ||
259 | |||
260 | func add_entrance(entrance) -> void: | ||
261 | _entrances.append(entrance) | ||
262 | |||
263 | func clear() -> void: | ||
264 | _entrance = null | ||
265 | _entrances = [] | ||
266 | _entrance_index = 0 | ||
267 | |||
268 | func get_entrances() -> Array: | ||
269 | return _entrances | ||
270 | |||
271 | func remove_entrance(index) -> void: | ||
272 | if index < _entrances.size(): | ||
273 | _entrances.remove_at(index) | ||
274 | |||
275 | func get_index() -> int: | ||
276 | return _entrance_index | ||
277 | |||
278 | func set_index(index : int) -> void: | ||
279 | if index < _entrances.size(): | ||
280 | _entrance_index = index | ||
281 | else: | ||
282 | _entrance_index = 0 | ||
283 | |||
284 | func is_ignore() -> bool: | ||
285 | return _ignore | ||
286 | |||
287 | func get_clarification() -> String: | ||
288 | return _clarification | ||
289 | |||
290 | class TokenResult: | ||
291 | var tokens : Array = [] | ||
292 | var errors : Array = [] | ||
293 | |||
294 | enum TOKEN_ID { | ||
295 | UNDEFINED = -1, | ||
296 | IDENT = 0, | ||
297 | FULL_IDENT = 1, | ||
298 | BRACKET_ROUND_LEFT = 2, | ||
299 | BRACKET_ROUND_RIGHT = 3, | ||
300 | BRACKET_CURLY_LEFT = 4, | ||
301 | BRACKET_CURLY_RIGHT = 5, | ||
302 | BRACKET_SQUARE_LEFT = 6, | ||
303 | BRACKET_SQUARE_RIGHT = 7, | ||
304 | BRACKET_ANGLE_LEFT = 8, | ||
305 | BRACKET_ANGLE_RIGHT = 9, | ||
306 | SEMICOLON = 10, | ||
307 | EUQAL = 11, | ||
308 | SIGN = 12, | ||
309 | INT = 13, | ||
310 | FLOAT = 14, | ||
311 | SPACE = 15, | ||
312 | COMMA = 16, | ||
313 | STRING_SINGLE = 17, | ||
314 | STRING_DOUBLE = 18, | ||
315 | COMMENT_SINGLE = 19, | ||
316 | COMMENT_MULTI = 20, | ||
317 | |||
318 | MESSAGE = 21, | ||
319 | SIMPLE_DATA_TYPE = 22, | ||
320 | ENUM = 23, | ||
321 | MAP = 24, | ||
322 | ONEOF = 25, | ||
323 | LITERAL_BOOL = 26, | ||
324 | SYNTAX = 27, | ||
325 | IMPORT = 28, | ||
326 | PACKAGE = 29, | ||
327 | OPTION = 30, | ||
328 | SERVICE = 31, | ||
329 | RESERVED = 32, | ||
330 | IMPORT_QUALIFICATION = 33, | ||
331 | FIELD_QUALIFICATION = 34, | ||
332 | ENUM_OPTION = 35, | ||
333 | QUALIFICATION = 36, | ||
334 | FIELD_OPTION = 37, | ||
335 | |||
336 | STRING = 38 | ||
337 | } | ||
338 | |||
339 | var TOKEN = { | ||
340 | TOKEN_ID.IDENT: Token.new(TOKEN_ID.IDENT, "Identifier", TOKEN_IDENT), | ||
341 | TOKEN_ID.FULL_IDENT: Token.new(TOKEN_ID.FULL_IDENT, "Full identifier", TOKEN_FULL_IDENT), | ||
342 | TOKEN_ID.BRACKET_ROUND_LEFT: Token.new(TOKEN_ID.BRACKET_ROUND_LEFT, "(", TOKEN_BRACKET_ROUND_LEFT), | ||
343 | TOKEN_ID.BRACKET_ROUND_RIGHT: Token.new(TOKEN_ID.BRACKET_ROUND_RIGHT, ")", TOKEN_BRACKET_ROUND_RIGHT), | ||
344 | TOKEN_ID.BRACKET_CURLY_LEFT: Token.new(TOKEN_ID.BRACKET_CURLY_LEFT, "{", TOKEN_BRACKET_CURLY_LEFT), | ||
345 | TOKEN_ID.BRACKET_CURLY_RIGHT: Token.new(TOKEN_ID.BRACKET_CURLY_RIGHT, "}", TOKEN_BRACKET_CURLY_RIGHT), | ||
346 | TOKEN_ID.BRACKET_SQUARE_LEFT: Token.new(TOKEN_ID.BRACKET_SQUARE_LEFT, "[", TOKEN_BRACKET_SQUARE_LEFT), | ||
347 | TOKEN_ID.BRACKET_SQUARE_RIGHT: Token.new(TOKEN_ID.BRACKET_SQUARE_RIGHT, "]", TOKEN_BRACKET_SQUARE_RIGHT), | ||
348 | TOKEN_ID.BRACKET_ANGLE_LEFT: Token.new(TOKEN_ID.BRACKET_ANGLE_LEFT, "<", TOKEN_BRACKET_ANGLE_LEFT), | ||
349 | TOKEN_ID.BRACKET_ANGLE_RIGHT: Token.new(TOKEN_ID.BRACKET_ANGLE_RIGHT, ">", TOKEN_BRACKET_ANGLE_RIGHT), | ||
350 | TOKEN_ID.SEMICOLON: Token.new(TOKEN_ID.SEMICOLON, ";", TOKEN_SEMICOLON), | ||
351 | TOKEN_ID.EUQAL: Token.new(TOKEN_ID.EUQAL, "=", TOKEN_EUQAL), | ||
352 | TOKEN_ID.INT: Token.new(TOKEN_ID.INT, "Integer", TOKEN_LITERAL_INT), | ||
353 | TOKEN_ID.FLOAT: Token.new(TOKEN_ID.FLOAT, "Float", TOKEN_LITERAL_FLOAT), | ||
354 | TOKEN_ID.SPACE: Token.new(TOKEN_ID.SPACE, "Space", TOKEN_SPACE), | ||
355 | TOKEN_ID.COMMA: Token.new(TOKEN_ID.COMMA, ",", TOKEN_COMMA), | ||
356 | TOKEN_ID.STRING_SINGLE: Token.new(TOKEN_ID.STRING_SINGLE, "'String'", TOKEN_STRING_SINGLE), | ||
357 | TOKEN_ID.STRING_DOUBLE: Token.new(TOKEN_ID.STRING_DOUBLE, "\"String\"", TOKEN_STRING_DOUBLE), | ||
358 | TOKEN_ID.COMMENT_SINGLE: Token.new(TOKEN_ID.COMMENT_SINGLE, "//Comment", TOKEN_COMMENT_SINGLE), | ||
359 | TOKEN_ID.COMMENT_MULTI: Token.new(TOKEN_ID.COMMENT_MULTI, "/*Comment*/", TOKEN_COMMENT_MULTI), | ||
360 | |||
361 | TOKEN_ID.MESSAGE: Token.new(TOKEN_ID.MESSAGE, "Message", TOKEN_SECOND_MESSAGE, true), | ||
362 | TOKEN_ID.SIMPLE_DATA_TYPE: Token.new(TOKEN_ID.SIMPLE_DATA_TYPE, "Data type", TOKEN_SECOND_SIMPLE_DATA_TYPE, true), | ||
363 | TOKEN_ID.ENUM: Token.new(TOKEN_ID.ENUM, "Enum", TOKEN_SECOND_ENUM, true), | ||
364 | TOKEN_ID.MAP: Token.new(TOKEN_ID.MAP, "Map", TOKEN_SECOND_MAP, true), | ||
365 | TOKEN_ID.ONEOF: Token.new(TOKEN_ID.ONEOF, "OneOf", TOKEN_SECOND_ONEOF, true), | ||
366 | TOKEN_ID.LITERAL_BOOL: Token.new(TOKEN_ID.LITERAL_BOOL, "Bool literal", TOKEN_SECOND_LITERAL_BOOL, true), | ||
367 | TOKEN_ID.SYNTAX: Token.new(TOKEN_ID.SYNTAX, "Syntax", TOKEN_SECOND_SYNTAX, true), | ||
368 | TOKEN_ID.IMPORT: Token.new(TOKEN_ID.IMPORT, "Import", TOKEN_SECOND_IMPORT, true), | ||
369 | TOKEN_ID.PACKAGE: Token.new(TOKEN_ID.PACKAGE, "Package", TOKEN_SECOND_PACKAGE, true), | ||
370 | TOKEN_ID.OPTION: Token.new(TOKEN_ID.OPTION, "Option", TOKEN_SECOND_OPTION, true), | ||
371 | TOKEN_ID.SERVICE: Token.new(TOKEN_ID.SERVICE, "Service", TOKEN_SECOND_SERVICE, true), | ||
372 | TOKEN_ID.RESERVED: Token.new(TOKEN_ID.RESERVED, "Reserved", TOKEN_SECOND_RESERVED, true), | ||
373 | TOKEN_ID.IMPORT_QUALIFICATION: Token.new(TOKEN_ID.IMPORT_QUALIFICATION, "Import qualification", TOKEN_SECOND_IMPORT_QUALIFICATION, true), | ||
374 | TOKEN_ID.FIELD_QUALIFICATION: Token.new(TOKEN_ID.FIELD_QUALIFICATION, "Field qualification", TOKEN_SECOND_FIELD_QUALIFICATION, true), | ||
375 | TOKEN_ID.ENUM_OPTION: Token.new(TOKEN_ID.ENUM_OPTION, "Enum option", TOKEN_SECOND_ENUM_OPTION, true), | ||
376 | TOKEN_ID.QUALIFICATION: Token.new(TOKEN_ID.QUALIFICATION, "Qualification", TOKEN_SECOND_QUALIFICATION, true), | ||
377 | TOKEN_ID.FIELD_OPTION: Token.new(TOKEN_ID.FIELD_OPTION, "Field option", TOKEN_SECOND_FIELD_OPTION, true), | ||
378 | |||
379 | TOKEN_ID.STRING: Token.new(TOKEN_ID.STRING, "String", "", true) | ||
380 | } | ||
381 | |||
382 | static func check_range(main : TokenEntrance, current : TokenEntrance) -> TokenRange: | ||
383 | if main.position.begin > current.position.begin: | ||
384 | if main.position.end > current.position.end: | ||
385 | if main.position.begin >= current.position.end: | ||
386 | return TokenRange.new(current.position.begin, current.position.end, RANGE_STATE.EXCLUDE_LEFT) | ||
387 | else: | ||
388 | return TokenRange.new(main.position.begin, current.position.end, RANGE_STATE.OVERLAY) | ||
389 | else: | ||
390 | return TokenRange.new(current.position.begin, current.position.end, RANGE_STATE.ENTERS) | ||
391 | elif main.position.begin < current.position.begin: | ||
392 | if main.position.end >= current.position.end: | ||
393 | return TokenRange.new(main.position.begin, main.position.end, RANGE_STATE.INCLUDE) | ||
394 | else: | ||
395 | if main.position.end < current.position.begin: | ||
396 | return TokenRange.new(main.position.begin, main.position.end, RANGE_STATE.EXCLUDE_RIGHT) | ||
397 | else: | ||
398 | return TokenRange.new(main.position.begin, current.position.end, RANGE_STATE.OVERLAY) | ||
399 | else: | ||
400 | if main.position.end == current.position.end: | ||
401 | return TokenRange.new(main.position.begin, main.position.end, RANGE_STATE.EQUAL) | ||
402 | elif main.position.end > current.position.end: | ||
403 | return TokenRange.new(main.position.begin, main.position.end, RANGE_STATE.INCLUDE) | ||
404 | else: | ||
405 | return TokenRange.new(current.position.begin, current.position.end, RANGE_STATE.ENTERS) | ||
406 | |||
407 | func tokenizer() -> TokenResult: | ||
408 | for k in TOKEN: | ||
409 | if !TOKEN[k].is_ignore(): | ||
410 | TOKEN[k].find_all(document.text) | ||
411 | var second_tokens : Array = [] | ||
412 | second_tokens.append(TOKEN[TOKEN_ID.MESSAGE]) | ||
413 | second_tokens.append(TOKEN[TOKEN_ID.SIMPLE_DATA_TYPE]) | ||
414 | second_tokens.append(TOKEN[TOKEN_ID.ENUM]) | ||
415 | second_tokens.append(TOKEN[TOKEN_ID.MAP]) | ||
416 | second_tokens.append(TOKEN[TOKEN_ID.ONEOF]) | ||
417 | second_tokens.append(TOKEN[TOKEN_ID.LITERAL_BOOL]) | ||
418 | second_tokens.append(TOKEN[TOKEN_ID.SYNTAX]) | ||
419 | second_tokens.append(TOKEN[TOKEN_ID.IMPORT]) | ||
420 | second_tokens.append(TOKEN[TOKEN_ID.PACKAGE]) | ||
421 | second_tokens.append(TOKEN[TOKEN_ID.OPTION]) | ||
422 | second_tokens.append(TOKEN[TOKEN_ID.SERVICE]) | ||
423 | second_tokens.append(TOKEN[TOKEN_ID.RESERVED]) | ||
424 | second_tokens.append(TOKEN[TOKEN_ID.IMPORT_QUALIFICATION]) | ||
425 | second_tokens.append(TOKEN[TOKEN_ID.FIELD_QUALIFICATION]) | ||
426 | second_tokens.append(TOKEN[TOKEN_ID.ENUM_OPTION]) | ||
427 | second_tokens.append(TOKEN[TOKEN_ID.QUALIFICATION]) | ||
428 | second_tokens.append(TOKEN[TOKEN_ID.FIELD_OPTION]) | ||
429 | |||
430 | var ident_token : Token = TOKEN[TOKEN_ID.IDENT] | ||
431 | for sec_token in second_tokens: | ||
432 | var remove_indexes : Array = [] | ||
433 | for i in range(ident_token.get_entrances().size()): | ||
434 | var entrance : TokenEntrance = sec_token.find(ident_token.get_entrances()[i].text, 0) | ||
435 | if entrance != null: | ||
436 | entrance.position.begin = ident_token.get_entrances()[i].position.begin | ||
437 | entrance.position.end = ident_token.get_entrances()[i].position.end | ||
438 | sec_token.add_entrance(entrance) | ||
439 | remove_indexes.append(i) | ||
440 | for i in range(remove_indexes.size()): | ||
441 | ident_token.remove_entrance(remove_indexes[i] - i) | ||
442 | for v in TOKEN[TOKEN_ID.STRING_DOUBLE].get_entrances(): | ||
443 | v.id = TOKEN_ID.STRING | ||
444 | TOKEN[TOKEN_ID.STRING].add_entrance(v) | ||
445 | TOKEN[TOKEN_ID.STRING_DOUBLE].clear() | ||
446 | for v in TOKEN[TOKEN_ID.STRING_SINGLE].get_entrances(): | ||
447 | v.id = TOKEN_ID.STRING | ||
448 | TOKEN[TOKEN_ID.STRING].add_entrance(v) | ||
449 | TOKEN[TOKEN_ID.STRING_SINGLE].clear() | ||
450 | var main_token : TokenEntrance | ||
451 | var cur_token : TokenEntrance | ||
452 | var main_index : int = -1 | ||
453 | var token_index_flag : bool = false | ||
454 | var result : TokenResult = TokenResult.new() | ||
455 | var check : TokenRange | ||
456 | var end : bool = false | ||
457 | var all : bool = false | ||
458 | var repeat : bool = false | ||
459 | while true: | ||
460 | all = true | ||
461 | for k in TOKEN: | ||
462 | if main_index == k: | ||
463 | continue | ||
464 | repeat = false | ||
465 | while TOKEN[k].get_entrances().size() > 0: | ||
466 | all = false | ||
467 | if !token_index_flag: | ||
468 | main_index = k | ||
469 | main_token = TOKEN[main_index].get_entrances()[0] | ||
470 | token_index_flag = true | ||
471 | break | ||
472 | else: | ||
473 | cur_token = TOKEN[k].get_entrances()[0] | ||
474 | check = check_range(main_token, cur_token) | ||
475 | if check.state == RANGE_STATE.INCLUDE: | ||
476 | TOKEN[k].remove_entrance(0) | ||
477 | end = true | ||
478 | elif check.state == RANGE_STATE.EXCLUDE_LEFT: | ||
479 | main_token = cur_token | ||
480 | main_index = k | ||
481 | end = false | ||
482 | repeat = true | ||
483 | break | ||
484 | elif check.state == RANGE_STATE.EXCLUDE_RIGHT: | ||
485 | end = true | ||
486 | break | ||
487 | elif check.state == RANGE_STATE.OVERLAY || check.state == RANGE_STATE.EQUAL: | ||
488 | result.errors.append(check) | ||
489 | TOKEN[main_index].remove_entrance(0) | ||
490 | TOKEN[k].remove_entrance(0) | ||
491 | token_index_flag = false | ||
492 | end = false | ||
493 | repeat = true | ||
494 | break | ||
495 | elif check.state == RANGE_STATE.ENTERS: | ||
496 | TOKEN[main_index].remove_entrance(0) | ||
497 | main_token = cur_token | ||
498 | main_index = k | ||
499 | end = false | ||
500 | repeat = true | ||
501 | break | ||
502 | if repeat: | ||
503 | break | ||
504 | if end: | ||
505 | if TOKEN[main_index].get_entrances().size() > 0: | ||
506 | result.tokens.append(main_token) | ||
507 | TOKEN[main_index].remove_entrance(0) | ||
508 | token_index_flag = false | ||
509 | if all: | ||
510 | break | ||
511 | return result | ||
512 | |||
513 | static func check_tokens_integrity(tokens : Array, end : int) -> Array: | ||
514 | var cur_index : int = 0 | ||
515 | var result : Array = [] | ||
516 | for v in tokens: | ||
517 | if v.position.begin > cur_index: | ||
518 | result.append(TokenPosition.new(cur_index, v.position.begin)) | ||
519 | cur_index = v.position.end + 1 | ||
520 | if cur_index < end: | ||
521 | result.append(TokenPosition.new(cur_index, end)) | ||
522 | return result | ||
523 | |||
524 | static func comment_space_processing(tokens : Array) -> void: | ||
525 | var remove_indexes : Array = [] | ||
526 | for i in range(tokens.size()): | ||
527 | if tokens[i].id == TOKEN_ID.COMMENT_SINGLE || tokens[i].id == TOKEN_ID.COMMENT_MULTI: | ||
528 | tokens[i].id = TOKEN_ID.SPACE | ||
529 | var space_index : int = -1 | ||
530 | for i in range(tokens.size()): | ||
531 | if tokens[i].id == TOKEN_ID.SPACE: | ||
532 | if space_index >= 0: | ||
533 | tokens[space_index].position.end = tokens[i].position.end | ||
534 | tokens[space_index].text = tokens[space_index].text + tokens[i].text | ||
535 | remove_indexes.append(i) | ||
536 | else: | ||
537 | space_index = i | ||
538 | else: | ||
539 | space_index = -1 | ||
540 | for i in range(remove_indexes.size()): | ||
541 | tokens.remove_at(remove_indexes[i] - i) | ||
542 | |||
543 | #Analysis rule | ||
544 | enum AR { | ||
545 | MAYBE = 1, | ||
546 | MUST_ONE = 2, | ||
547 | ANY = 3, | ||
548 | OR = 4, | ||
549 | MAYBE_BEGIN = 5, | ||
550 | MAYBE_END = 6, | ||
551 | ANY_BEGIN = 7, | ||
552 | ANY_END = 8 | ||
553 | } | ||
554 | |||
555 | #Space rule (space after token) | ||
556 | enum SP { | ||
557 | MAYBE = 1, | ||
558 | MUST = 2, | ||
559 | NO = 3 | ||
560 | } | ||
561 | |||
562 | #Analysis Syntax Description | ||
563 | class ASD: | ||
564 | func _init(t, s : int = SP.MAYBE, r : int = AR.MUST_ONE, i : bool = false): | ||
565 | token = t | ||
566 | space = s | ||
567 | rule = r | ||
568 | importance = i | ||
569 | var token | ||
570 | var space : int | ||
571 | var rule : int | ||
572 | var importance : bool | ||
573 | |||
574 | var TEMPLATE_SYNTAX : Array = [ | ||
575 | Callable(self, "desc_syntax"), | ||
576 | ASD.new(TOKEN_ID.SYNTAX), | ||
577 | ASD.new(TOKEN_ID.EUQAL), | ||
578 | ASD.new(TOKEN_ID.STRING, SP.MAYBE, AR.MUST_ONE, true), | ||
579 | ASD.new(TOKEN_ID.SEMICOLON) | ||
580 | ] | ||
581 | |||
582 | var TEMPLATE_IMPORT : Array = [ | ||
583 | Callable(self, "desc_import"), | ||
584 | ASD.new(TOKEN_ID.IMPORT, SP.MUST), | ||
585 | ASD.new(TOKEN_ID.IMPORT_QUALIFICATION, SP.MUST, AR.MAYBE, true), | ||
586 | ASD.new(TOKEN_ID.STRING, SP.MAYBE, AR.MUST_ONE, true), | ||
587 | ASD.new(TOKEN_ID.SEMICOLON) | ||
588 | ] | ||
589 | |||
590 | var TEMPLATE_PACKAGE : Array = [ | ||
591 | Callable(self, "desc_package"), | ||
592 | ASD.new(TOKEN_ID.PACKAGE, SP.MUST), | ||
593 | ASD.new([TOKEN_ID.IDENT, TOKEN_ID.FULL_IDENT], SP.MAYBE, AR.OR, true), | ||
594 | ASD.new(TOKEN_ID.SEMICOLON) | ||
595 | ] | ||
596 | |||
597 | var TEMPLATE_OPTION : Array = [ | ||
598 | Callable(self, "desc_option"), | ||
599 | ASD.new(TOKEN_ID.OPTION, SP.MUST), | ||
600 | ASD.new([TOKEN_ID.IDENT, TOKEN_ID.FULL_IDENT], SP.MAYBE, AR.OR, true), | ||
601 | ASD.new(TOKEN_ID.EUQAL), | ||
602 | ASD.new([TOKEN_ID.STRING, TOKEN_ID.INT, TOKEN_ID.FLOAT, TOKEN_ID.LITERAL_BOOL], SP.MAYBE, AR.OR, true), | ||
603 | ASD.new(TOKEN_ID.SEMICOLON) | ||
604 | ] | ||
605 | |||
606 | var TEMPLATE_FIELD : Array = [ | ||
607 | Callable(self, "desc_field"), | ||
608 | ASD.new(TOKEN_ID.FIELD_QUALIFICATION, SP.MUST, AR.MAYBE, true), | ||
609 | ASD.new([TOKEN_ID.SIMPLE_DATA_TYPE, TOKEN_ID.IDENT, TOKEN_ID.FULL_IDENT], SP.MAYBE, AR.OR, true), | ||
610 | ASD.new(TOKEN_ID.IDENT, SP.MAYBE, AR.MUST_ONE, true), | ||
611 | ASD.new(TOKEN_ID.EUQAL), | ||
612 | ASD.new(TOKEN_ID.INT, SP.MAYBE, AR.MUST_ONE, true), | ||
613 | ASD.new(TOKEN_ID.BRACKET_SQUARE_LEFT, SP.MAYBE, AR.MAYBE_BEGIN), | ||
614 | ASD.new(TOKEN_ID.FIELD_OPTION, SP.MAYBE, AR.MUST_ONE, true), | ||
615 | ASD.new(TOKEN_ID.EUQAL), | ||
616 | ASD.new(TOKEN_ID.LITERAL_BOOL, SP.MAYBE, AR.MUST_ONE, true), | ||
617 | ASD.new(TOKEN_ID.BRACKET_SQUARE_RIGHT, SP.MAYBE, AR.MAYBE_END), | ||
618 | ASD.new(TOKEN_ID.SEMICOLON) | ||
619 | ] | ||
620 | |||
621 | var TEMPLATE_FIELD_ONEOF : Array = TEMPLATE_FIELD | ||
622 | |||
623 | var TEMPLATE_MAP_FIELD : Array = [ | ||
624 | Callable(self, "desc_map_field"), | ||
625 | ASD.new(TOKEN_ID.MAP), | ||
626 | ASD.new(TOKEN_ID.BRACKET_ANGLE_LEFT), | ||
627 | ASD.new(TOKEN_ID.SIMPLE_DATA_TYPE, SP.MAYBE, AR.MUST_ONE, true), | ||
628 | ASD.new(TOKEN_ID.COMMA), | ||
629 | ASD.new([TOKEN_ID.SIMPLE_DATA_TYPE, TOKEN_ID.IDENT, TOKEN_ID.FULL_IDENT], SP.MAYBE, AR.OR, true), | ||
630 | ASD.new(TOKEN_ID.BRACKET_ANGLE_RIGHT, SP.MUST), | ||
631 | ASD.new(TOKEN_ID.IDENT, SP.MAYBE, AR.MUST_ONE, true), | ||
632 | ASD.new(TOKEN_ID.EUQAL), | ||
633 | ASD.new(TOKEN_ID.INT, SP.MAYBE, AR.MUST_ONE, true), | ||
634 | ASD.new(TOKEN_ID.BRACKET_SQUARE_LEFT, SP.MAYBE, AR.MAYBE_BEGIN), | ||
635 | ASD.new(TOKEN_ID.FIELD_OPTION, SP.MAYBE, AR.MUST_ONE, true), | ||
636 | ASD.new(TOKEN_ID.EUQAL), | ||
637 | ASD.new(TOKEN_ID.LITERAL_BOOL, SP.MAYBE, AR.MUST_ONE, true), | ||
638 | ASD.new(TOKEN_ID.BRACKET_SQUARE_RIGHT, SP.MAYBE, AR.MAYBE_END), | ||
639 | ASD.new(TOKEN_ID.SEMICOLON) | ||
640 | ] | ||
641 | |||
642 | var TEMPLATE_MAP_FIELD_ONEOF : Array = TEMPLATE_MAP_FIELD | ||
643 | |||
644 | var TEMPLATE_ENUM : Array = [ | ||
645 | Callable(self, "desc_enum"), | ||
646 | ASD.new(TOKEN_ID.ENUM, SP.MUST), | ||
647 | ASD.new(TOKEN_ID.IDENT, SP.MAYBE, AR.MUST_ONE, true), | ||
648 | ASD.new(TOKEN_ID.BRACKET_CURLY_LEFT), | ||
649 | ASD.new(TOKEN_ID.OPTION, SP.MUST, AR.MAYBE_BEGIN), | ||
650 | ASD.new(TOKEN_ID.ENUM_OPTION, SP.MAYBE, AR.MUST_ONE, true), | ||
651 | ASD.new(TOKEN_ID.EUQAL), | ||
652 | ASD.new(TOKEN_ID.LITERAL_BOOL, SP.MAYBE, AR.MUST_ONE, true), | ||
653 | ASD.new(TOKEN_ID.SEMICOLON, SP.MAYBE, AR.MAYBE_END), | ||
654 | ASD.new(TOKEN_ID.IDENT, SP.MAYBE, AR.ANY_BEGIN, true), | ||
655 | ASD.new(TOKEN_ID.EUQAL), | ||
656 | ASD.new(TOKEN_ID.INT, SP.MAYBE, AR.MUST_ONE, true), | ||
657 | ASD.new(TOKEN_ID.SEMICOLON, SP.MAYBE, AR.ANY_END), | ||
658 | ASD.new(TOKEN_ID.BRACKET_CURLY_RIGHT) | ||
659 | ] | ||
660 | |||
661 | var TEMPLATE_MESSAGE_HEAD : Array = [ | ||
662 | Callable(self, "desc_message_head"), | ||
663 | ASD.new(TOKEN_ID.MESSAGE, SP.MUST), | ||
664 | ASD.new(TOKEN_ID.IDENT, SP.MAYBE, AR.MUST_ONE, true), | ||
665 | ASD.new(TOKEN_ID.BRACKET_CURLY_LEFT) | ||
666 | ] | ||
667 | |||
668 | var TEMPLATE_MESSAGE_TAIL : Array = [ | ||
669 | Callable(self, "desc_message_tail"), | ||
670 | ASD.new(TOKEN_ID.BRACKET_CURLY_RIGHT) | ||
671 | ] | ||
672 | |||
673 | var TEMPLATE_ONEOF_HEAD : Array = [ | ||
674 | Callable(self, "desc_oneof_head"), | ||
675 | ASD.new(TOKEN_ID.ONEOF, SP.MUST), | ||
676 | ASD.new(TOKEN_ID.IDENT, SP.MAYBE, AR.MUST_ONE, true), | ||
677 | ASD.new(TOKEN_ID.BRACKET_CURLY_LEFT), | ||
678 | ] | ||
679 | |||
680 | var TEMPLATE_ONEOF_TAIL : Array = [ | ||
681 | Callable(self, "desc_oneof_tail"), | ||
682 | ASD.new(TOKEN_ID.BRACKET_CURLY_RIGHT) | ||
683 | ] | ||
684 | |||
685 | var TEMPLATE_BEGIN : Array = [ | ||
686 | null, | ||
687 | ASD.new(TOKEN_ID.SPACE, SP.NO, AR.MAYBE) | ||
688 | ] | ||
689 | |||
690 | var TEMPLATE_END : Array = [ | ||
691 | null | ||
692 | ] | ||
693 | |||
694 | func get_token_id(tokens : Array, index : int) -> int: | ||
695 | if index < tokens.size(): | ||
696 | return tokens[index].id | ||
697 | return TOKEN_ID.UNDEFINED | ||
698 | |||
699 | enum COMPARE_STATE { | ||
700 | DONE = 0, | ||
701 | MISMATCH = 1, | ||
702 | INCOMPLETE = 2, | ||
703 | ERROR_VALUE = 3 | ||
704 | } | ||
705 | |||
706 | class TokenCompare: | ||
707 | func _init(s : int, i : int, d : String = ""): | ||
708 | state = s | ||
709 | index = i | ||
710 | description = d | ||
711 | var state : int | ||
712 | var index : int | ||
713 | var description : String | ||
714 | |||
715 | func check_space(tokens : Array, index : int, space) -> int: | ||
716 | if get_token_id(tokens, index) == TOKEN_ID.SPACE: | ||
717 | if space == SP.MAYBE: | ||
718 | return 1 | ||
719 | elif space == SP.MUST: | ||
720 | return 1 | ||
721 | elif space == SP.NO: | ||
722 | return -1 | ||
723 | else: | ||
724 | if space == SP.MUST: | ||
725 | return -2 | ||
726 | return 0 | ||
727 | |||
728 | class IndexedToken: | ||
729 | func _init(t : TokenEntrance, i : int): | ||
730 | token = t | ||
731 | index = i | ||
732 | var token : TokenEntrance | ||
733 | var index : int | ||
734 | |||
735 | func token_importance_checkadd(template : ASD, token : TokenEntrance, index : int, importance : Array) -> void: | ||
736 | if template.importance: | ||
737 | importance.append(IndexedToken.new(token, index)) | ||
738 | |||
739 | class CompareSettings: | ||
740 | func _init(ci : int, n : int, pi : int, pn : String = ""): | ||
741 | construction_index = ci | ||
742 | nesting = n | ||
743 | parent_index = pi | ||
744 | parent_name = pn | ||
745 | |||
746 | var construction_index : int | ||
747 | var nesting : int | ||
748 | var parent_index : int | ||
749 | var parent_name : String | ||
750 | |||
751 | func description_compare(template : Array, tokens : Array, index : int, settings : CompareSettings) -> TokenCompare: | ||
752 | var j : int = index | ||
753 | var space : int | ||
754 | var rule : int | ||
755 | var rule_flag : bool | ||
756 | var cont : bool | ||
757 | var check : int | ||
758 | var maybe_group_skip : bool = false | ||
759 | var any_group_index : int = -1 | ||
760 | var any_end_group_index : int = -1 | ||
761 | var i : int = 0 | ||
762 | var importance : Array = [] | ||
763 | while true: | ||
764 | i += 1 | ||
765 | if i >= template.size(): | ||
766 | break | ||
767 | rule_flag = false | ||
768 | cont = false | ||
769 | rule = template[i].rule | ||
770 | space = template[i].space | ||
771 | if rule == AR.MAYBE_END && maybe_group_skip: | ||
772 | maybe_group_skip = false | ||
773 | continue | ||
774 | if maybe_group_skip: | ||
775 | continue | ||
776 | if rule == AR.MAYBE: | ||
777 | if template[i].token == get_token_id(tokens, j): | ||
778 | token_importance_checkadd(template[i], tokens[j], j, importance) | ||
779 | rule_flag = true | ||
780 | else: | ||
781 | continue | ||
782 | elif rule == AR.MUST_ONE || rule == AR.MAYBE_END || rule == AR.ANY_END: | ||
783 | if template[i].token == get_token_id(tokens, j): | ||
784 | token_importance_checkadd(template[i], tokens[j], j, importance) | ||
785 | rule_flag = true | ||
786 | elif rule == AR.ANY: | ||
787 | var find_any : bool = false | ||
788 | while true: | ||
789 | if template[i].token == get_token_id(tokens, j): | ||
790 | token_importance_checkadd(template[i], tokens[j], j, importance) | ||
791 | find_any = true | ||
792 | j += 1 | ||
793 | check = check_space(tokens, j, space) | ||
794 | if check < 0: | ||
795 | return TokenCompare.new(COMPARE_STATE.INCOMPLETE, j) | ||
796 | else: | ||
797 | j += check | ||
798 | else: | ||
799 | if find_any: | ||
800 | cont = true | ||
801 | break | ||
802 | elif rule == AR.OR: | ||
803 | var or_tokens = template[i].token | ||
804 | for v in or_tokens: | ||
805 | if v == get_token_id(tokens, j): | ||
806 | token_importance_checkadd(template[i], tokens[j], j, importance) | ||
807 | j += 1 | ||
808 | check = check_space(tokens, j, space) | ||
809 | if check < 0: | ||
810 | return TokenCompare.new(COMPARE_STATE.INCOMPLETE, j) | ||
811 | else: | ||
812 | j += check | ||
813 | cont = true | ||
814 | break | ||
815 | elif rule == AR.MAYBE_BEGIN: | ||
816 | if template[i].token == get_token_id(tokens, j): | ||
817 | token_importance_checkadd(template[i], tokens[j], j, importance) | ||
818 | rule_flag = true | ||
819 | else: | ||
820 | maybe_group_skip = true | ||
821 | continue | ||
822 | elif rule == AR.ANY_BEGIN: | ||
823 | if template[i].token == get_token_id(tokens, j): | ||
824 | token_importance_checkadd(template[i], tokens[j], j, importance) | ||
825 | rule_flag = true | ||
826 | any_group_index = i | ||
827 | else: | ||
828 | if any_end_group_index > 0: | ||
829 | any_group_index = -1 | ||
830 | i = any_end_group_index | ||
831 | any_end_group_index = -1 | ||
832 | continue | ||
833 | if cont: | ||
834 | continue | ||
835 | if rule_flag: | ||
836 | j += 1 | ||
837 | check = check_space(tokens, j, space) | ||
838 | if check < 0: | ||
839 | return TokenCompare.new(COMPARE_STATE.INCOMPLETE, j) | ||
840 | else: | ||
841 | j += check | ||
842 | else: | ||
843 | if j > index: | ||
844 | return TokenCompare.new(COMPARE_STATE.INCOMPLETE, j) | ||
845 | else: | ||
846 | return TokenCompare.new(COMPARE_STATE.MISMATCH, j) | ||
847 | if any_group_index >= 0 && rule == AR.ANY_END: | ||
848 | any_end_group_index = i | ||
849 | i = any_group_index - 1 | ||
850 | if template[0] != null: | ||
851 | var result : DescriptionResult = template[0].call(importance, settings) | ||
852 | if !result.success: | ||
853 | return TokenCompare.new(COMPARE_STATE.ERROR_VALUE, result.error, result.description) | ||
854 | return TokenCompare.new(COMPARE_STATE.DONE, j) | ||
855 | |||
856 | var DESCRIPTION : Array = [ | ||
857 | TEMPLATE_BEGIN, #0 | ||
858 | TEMPLATE_SYNTAX, #1 | ||
859 | TEMPLATE_IMPORT, #2 | ||
860 | TEMPLATE_PACKAGE, #3 | ||
861 | TEMPLATE_OPTION, #4 | ||
862 | TEMPLATE_FIELD, #5 | ||
863 | TEMPLATE_FIELD_ONEOF, #6 | ||
864 | TEMPLATE_MAP_FIELD, #7 | ||
865 | TEMPLATE_MAP_FIELD_ONEOF, #8 | ||
866 | TEMPLATE_ENUM, #9 | ||
867 | TEMPLATE_MESSAGE_HEAD, #10 | ||
868 | TEMPLATE_MESSAGE_TAIL, #11 | ||
869 | TEMPLATE_ONEOF_HEAD, #12 | ||
870 | TEMPLATE_ONEOF_TAIL, #13 | ||
871 | TEMPLATE_END #14 | ||
872 | ] | ||
873 | |||
874 | enum JUMP { | ||
875 | NOTHING = 0, #nothing | ||
876 | SIMPLE = 1, #simple jump | ||
877 | NESTED_INCREMENT = 2, #nested increment | ||
878 | NESTED_DECREMENT = 3, #nested decrement | ||
879 | MUST_NESTED_SIMPLE = 4, #check: must be nested > 0 | ||
880 | MUST_NESTED_INCREMENT = 5, #check: must be nested > 0, then nested increment | ||
881 | MUST_NESTED_DECREMENT = 6, #nested decrement, then check: must be nested > 0 | ||
882 | } | ||
883 | |||
884 | var TRANSLATION_TABLE : Array = [ | ||
885 | # BEGIN SYNTAX IMPORT PACKAGE OPTION FIELD FIELD_O MAP_F MAP_F_O ENUM MES_H MES_T ONEOF_H ONEOF_T END | ||
886 | [ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], #BEGIN | ||
887 | [ 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1], #SYNTAX | ||
888 | [ 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1], #IMPORT | ||
889 | [ 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1], #PACKAGE | ||
890 | [ 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1], #OPTION | ||
891 | [ 0, 0, 0, 0, 0, 4, 0, 4, 0, 1, 2, 3, 5, 0, 0], #FIELD | ||
892 | [ 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 6, 0], #FIELD_ONEOF | ||
893 | [ 0, 0, 0, 0, 0, 4, 0, 4, 0, 1, 2, 3, 5, 0, 0], #MAP_F | ||
894 | [ 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 6, 0], #MAP_F_ONEOF | ||
895 | [ 0, 0, 0, 0, 0, 4, 0, 4, 0, 1, 2, 3, 5, 0, 1], #ENUM | ||
896 | [ 0, 0, 0, 0, 0, 4, 0, 4, 0, 1, 2, 3, 5, 0, 0], #MES_H | ||
897 | [ 0, 0, 0, 0, 0, 4, 0, 4, 0, 1, 2, 3, 5, 0, 1], #MES_T | ||
898 | [ 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0], #ONEOF_H | ||
899 | [ 0, 0, 0, 0, 0, 4, 0, 4, 0, 1, 2, 3, 5, 0, 1], #ONEOF_T | ||
900 | [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] #END | ||
901 | ] | ||
902 | |||
903 | class Construction: | ||
904 | func _init(b : int, e : int, d : int): | ||
905 | begin_token_index = b | ||
906 | end_token_index = e | ||
907 | description = d | ||
908 | var begin_token_index : int | ||
909 | var end_token_index : int | ||
910 | var description : int | ||
911 | |||
912 | class TranslationResult: | ||
913 | var constructions : Array = [] | ||
914 | var done : bool = false | ||
915 | var error_description_id : int = -1 | ||
916 | var error_description_text : String = "" | ||
917 | var parse_token_index : int = 0 | ||
918 | var error_token_index : int = 0 | ||
919 | |||
920 | func analyze_tokens(tokens : Array) -> TranslationResult: | ||
921 | var i : int = 0 | ||
922 | var result : TranslationResult = TranslationResult.new() | ||
923 | var comp : TokenCompare | ||
924 | var cur_template_id : int = 0 | ||
925 | var error : bool = false | ||
926 | var template_index : int | ||
927 | var comp_set : CompareSettings = CompareSettings.new(result.constructions.size(), 0, -1) | ||
928 | comp = description_compare(DESCRIPTION[cur_template_id], tokens, i, comp_set) | ||
929 | if comp.state == COMPARE_STATE.DONE: | ||
930 | i = comp.index | ||
931 | while true: | ||
932 | var end : bool = true | ||
933 | var find : bool = false | ||
934 | for j in range(TRANSLATION_TABLE[cur_template_id].size()): | ||
935 | template_index = j | ||
936 | if j == DESCRIPTION.size() - 1 && i < tokens.size(): | ||
937 | end = false | ||
938 | if result.error_description_id < 0: | ||
939 | error = true | ||
940 | break | ||
941 | if TRANSLATION_TABLE[cur_template_id][j] > 0: | ||
942 | end = false | ||
943 | comp_set.construction_index = result.constructions.size() | ||
944 | comp = description_compare(DESCRIPTION[j], tokens, i, comp_set) | ||
945 | if comp.state == COMPARE_STATE.DONE: | ||
946 | if TRANSLATION_TABLE[cur_template_id][j] == JUMP.NESTED_INCREMENT: | ||
947 | comp_set.nesting += 1 | ||
948 | elif TRANSLATION_TABLE[cur_template_id][j] == JUMP.NESTED_DECREMENT: | ||
949 | comp_set.nesting -= 1 | ||
950 | if comp_set.nesting < 0: | ||
951 | error = true | ||
952 | break | ||
953 | elif TRANSLATION_TABLE[cur_template_id][j] == JUMP.MUST_NESTED_SIMPLE: | ||
954 | if comp_set.nesting <= 0: | ||
955 | error = true | ||
956 | break | ||
957 | elif TRANSLATION_TABLE[cur_template_id][j] == JUMP.MUST_NESTED_INCREMENT: | ||
958 | if comp_set.nesting <= 0: | ||
959 | error = true | ||
960 | break | ||
961 | comp_set.nesting += 1 | ||
962 | elif TRANSLATION_TABLE[cur_template_id][j] == JUMP.MUST_NESTED_DECREMENT: | ||
963 | comp_set.nesting -= 1 | ||
964 | if comp_set.nesting <= 0: | ||
965 | error = true | ||
966 | break | ||
967 | result.constructions.append(Construction.new(i, comp.index, j)) | ||
968 | find = true | ||
969 | i = comp.index | ||
970 | cur_template_id = j | ||
971 | if i == tokens.size(): | ||
972 | if TRANSLATION_TABLE[cur_template_id][DESCRIPTION.size() - 1] == JUMP.SIMPLE: | ||
973 | if comp_set.nesting == 0: | ||
974 | end = true | ||
975 | else: | ||
976 | error = true | ||
977 | else: | ||
978 | error = true | ||
979 | elif i > tokens.size(): | ||
980 | error = true | ||
981 | break | ||
982 | elif comp.state == COMPARE_STATE.INCOMPLETE: | ||
983 | error = true | ||
984 | break | ||
985 | elif comp.state == COMPARE_STATE.ERROR_VALUE: | ||
986 | error = true | ||
987 | break | ||
988 | if error: | ||
989 | result.error_description_text = comp.description | ||
990 | result.error_description_id = template_index | ||
991 | result.parse_token_index = i | ||
992 | if comp.index >= tokens.size(): | ||
993 | result.error_token_index = tokens.size() - 1 | ||
994 | else: | ||
995 | result.error_token_index = comp.index | ||
996 | if end: | ||
997 | result.done = true | ||
998 | result.error_description_id = -1 | ||
999 | break | ||
1000 | if !find: | ||
1001 | break | ||
1002 | return result | ||
1003 | |||
1004 | enum CLASS_TYPE { | ||
1005 | ENUM = 0, | ||
1006 | MESSAGE = 1, | ||
1007 | MAP = 2 | ||
1008 | } | ||
1009 | |||
1010 | enum FIELD_TYPE { | ||
1011 | UNDEFINED = -1, | ||
1012 | INT32 = 0, | ||
1013 | SINT32 = 1, | ||
1014 | UINT32 = 2, | ||
1015 | INT64 = 3, | ||
1016 | SINT64 = 4, | ||
1017 | UINT64 = 5, | ||
1018 | BOOL = 6, | ||
1019 | ENUM = 7, | ||
1020 | FIXED32 = 8, | ||
1021 | SFIXED32 = 9, | ||
1022 | FLOAT = 10, | ||
1023 | FIXED64 = 11, | ||
1024 | SFIXED64 = 12, | ||
1025 | DOUBLE = 13, | ||
1026 | STRING = 14, | ||
1027 | BYTES = 15, | ||
1028 | MESSAGE = 16, | ||
1029 | MAP = 17 | ||
1030 | } | ||
1031 | |||
1032 | enum FIELD_QUALIFICATOR { | ||
1033 | OPTIONAL = 0, | ||
1034 | REQUIRED = 1, | ||
1035 | REPEATED = 2, | ||
1036 | RESERVED = 3 | ||
1037 | } | ||
1038 | |||
1039 | enum FIELD_OPTION { | ||
1040 | PACKED = 0, | ||
1041 | NOT_PACKED = 1 | ||
1042 | } | ||
1043 | |||
1044 | class ASTClass: | ||
1045 | func _init(n : String, t : int, p : int, pn : String, o : String, ci : int): | ||
1046 | name = n | ||
1047 | type = t | ||
1048 | parent_index = p | ||
1049 | parent_name = pn | ||
1050 | option = o | ||
1051 | construction_index = ci | ||
1052 | values = [] | ||
1053 | |||
1054 | var name : String | ||
1055 | var type : int | ||
1056 | var parent_index : int | ||
1057 | var parent_name : String | ||
1058 | var option : String | ||
1059 | var construction_index | ||
1060 | var values : Array | ||
1061 | |||
1062 | func copy() -> ASTClass: | ||
1063 | var res : ASTClass = ASTClass.new(name, type, parent_index, parent_name, option, construction_index) | ||
1064 | for v in values: | ||
1065 | res.values.append(v.copy()) | ||
1066 | return res | ||
1067 | |||
1068 | class ASTEnumValue: | ||
1069 | func _init(n : String, v : String): | ||
1070 | name = n | ||
1071 | value = v | ||
1072 | |||
1073 | var name : String | ||
1074 | var value : String | ||
1075 | |||
1076 | func copy() -> ASTEnumValue: | ||
1077 | return ASTEnumValue.new(name, value) | ||
1078 | |||
1079 | class ASTField: | ||
1080 | func _init(t, n : String, tn : String, p : int, q : int, o : int, ci : int, mf : bool): | ||
1081 | tag = t | ||
1082 | name = n | ||
1083 | type_name = tn | ||
1084 | parent_class_id = p | ||
1085 | qualificator = q | ||
1086 | option = o | ||
1087 | construction_index = ci | ||
1088 | is_map_field = mf | ||
1089 | |||
1090 | var tag | ||
1091 | var name : String | ||
1092 | var type_name : String | ||
1093 | var parent_class_id : int | ||
1094 | var qualificator : int | ||
1095 | var option : int | ||
1096 | var construction_index : int | ||
1097 | var is_map_field : bool | ||
1098 | var field_type : int = FIELD_TYPE.UNDEFINED | ||
1099 | var type_class_id : int = -1 | ||
1100 | |||
1101 | func copy() -> ASTField: | ||
1102 | var res : ASTField = ASTField.new(tag, name, type_name, parent_class_id, qualificator, option, construction_index, is_map_field) | ||
1103 | res.field_type = field_type | ||
1104 | res.type_class_id = type_class_id | ||
1105 | return res | ||
1106 | |||
1107 | enum AST_GROUP_RULE { | ||
1108 | ONEOF = 0, | ||
1109 | ALL = 1 | ||
1110 | } | ||
1111 | |||
1112 | class ASTFieldGroup: | ||
1113 | func _init(n : String, pi : int, r : int): | ||
1114 | name = n | ||
1115 | parent_class_id = pi | ||
1116 | rule = r | ||
1117 | opened = true | ||
1118 | |||
1119 | var name : String | ||
1120 | var parent_class_id : int | ||
1121 | var rule : int | ||
1122 | var field_indexes : Array = [] | ||
1123 | var opened : bool | ||
1124 | |||
1125 | func copy() -> ASTFieldGroup: | ||
1126 | var res : ASTFieldGroup = ASTFieldGroup.new(name, parent_class_id, rule) | ||
1127 | res.opened = opened | ||
1128 | for fi in field_indexes: | ||
1129 | res.field_indexes.append(fi) | ||
1130 | return res | ||
1131 | |||
1132 | class ASTImport: | ||
1133 | func _init(a_path : String, a_public : bool, sha : String): | ||
1134 | path = a_path | ||
1135 | public = a_public | ||
1136 | sha256 = sha | ||
1137 | |||
1138 | var path : String | ||
1139 | var public : bool | ||
1140 | var sha256 : String | ||
1141 | |||
1142 | var class_table : Array = [] | ||
1143 | var field_table : Array = [] | ||
1144 | var group_table : Array = [] | ||
1145 | var import_table : Array = [] | ||
1146 | var proto_version : int = 0 | ||
1147 | |||
1148 | class DescriptionResult: | ||
1149 | func _init(s : bool = true, e = null, d : String = ""): | ||
1150 | success = s | ||
1151 | error = e | ||
1152 | description = d | ||
1153 | var success : bool | ||
1154 | var error | ||
1155 | var description : String | ||
1156 | |||
1157 | static func get_text_from_token(string_token : TokenEntrance) -> String: | ||
1158 | return string_token.text.substr(1, string_token.text.length() - 2) | ||
1159 | |||
1160 | func desc_syntax(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1161 | var result : DescriptionResult = DescriptionResult.new() | ||
1162 | var s : String = get_text_from_token(indexed_tokens[0].token) | ||
1163 | if s == "proto2": | ||
1164 | proto_version = 2 | ||
1165 | elif s == "proto3": | ||
1166 | proto_version = 3 | ||
1167 | else: | ||
1168 | result.success = false | ||
1169 | result.error = indexed_tokens[0].index | ||
1170 | result.description = "Unspecified version of the protocol. Use \"proto2\" or \"proto3\" syntax string." | ||
1171 | return result | ||
1172 | |||
1173 | func desc_import(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1174 | var result : DescriptionResult = DescriptionResult.new() | ||
1175 | var offset : int = 0 | ||
1176 | var public : bool = false | ||
1177 | if indexed_tokens[offset].token.id == TOKEN_ID.IMPORT_QUALIFICATION: | ||
1178 | if indexed_tokens[offset].token.text == "public": | ||
1179 | public = true | ||
1180 | offset += 1 | ||
1181 | var f_name : String = path_dir + get_text_from_token(indexed_tokens[offset].token) | ||
1182 | var sha : String = FileAccess.get_sha256(f_name) | ||
1183 | if FileAccess.file_exists(f_name): | ||
1184 | for i in import_table: | ||
1185 | if i.path == f_name: | ||
1186 | result.success = false | ||
1187 | result.error = indexed_tokens[offset].index | ||
1188 | result.description = "File '" + f_name + "' already imported." | ||
1189 | return result | ||
1190 | if i.sha256 == sha: | ||
1191 | result.success = false | ||
1192 | result.error = indexed_tokens[offset].index | ||
1193 | result.description = "File '" + f_name + "' with matching SHA256 already imported." | ||
1194 | return result | ||
1195 | import_table.append(ASTImport.new(f_name, public, sha)) | ||
1196 | else: | ||
1197 | result.success = false | ||
1198 | result.error = indexed_tokens[offset].index | ||
1199 | result.description = "Import file '" + f_name + "' not found." | ||
1200 | return result | ||
1201 | |||
1202 | func desc_package(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1203 | printerr("UNRELEASED desc_package: ", indexed_tokens.size(), ", nesting: ", settings.nesting) | ||
1204 | var result : DescriptionResult = DescriptionResult.new() | ||
1205 | return result | ||
1206 | |||
1207 | func desc_option(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1208 | printerr("UNRELEASED desc_option: ", indexed_tokens.size(), ", nesting: ", settings.nesting) | ||
1209 | var result : DescriptionResult = DescriptionResult.new() | ||
1210 | return result | ||
1211 | |||
1212 | func desc_field(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1213 | var result : DescriptionResult = DescriptionResult.new() | ||
1214 | var qualifcator : int = FIELD_QUALIFICATOR.OPTIONAL | ||
1215 | var option : int | ||
1216 | var offset : int = 0 | ||
1217 | |||
1218 | if proto_version == 3: | ||
1219 | option = FIELD_OPTION.PACKED | ||
1220 | if indexed_tokens[offset].token.id == TOKEN_ID.FIELD_QUALIFICATION: | ||
1221 | if indexed_tokens[offset].token.text == "repeated": | ||
1222 | qualifcator = FIELD_QUALIFICATOR.REPEATED | ||
1223 | elif indexed_tokens[offset].token.text == "required" || indexed_tokens[offset].token.text == "optional": | ||
1224 | result.success = false | ||
1225 | result.error = indexed_tokens[offset].index | ||
1226 | result.description = "Using the 'required' or 'optional' qualificator is unacceptable in Protobuf v3." | ||
1227 | return result | ||
1228 | offset += 1 | ||
1229 | if proto_version == 2: | ||
1230 | option = FIELD_OPTION.NOT_PACKED | ||
1231 | if !(group_table.size() > 0 && group_table[group_table.size() - 1].opened): | ||
1232 | if indexed_tokens[offset].token.id == TOKEN_ID.FIELD_QUALIFICATION: | ||
1233 | if indexed_tokens[offset].token.text == "repeated": | ||
1234 | qualifcator = FIELD_QUALIFICATOR.REPEATED | ||
1235 | elif indexed_tokens[offset].token.text == "required": | ||
1236 | qualifcator = FIELD_QUALIFICATOR.REQUIRED | ||
1237 | elif indexed_tokens[offset].token.text == "optional": | ||
1238 | qualifcator = FIELD_QUALIFICATOR.OPTIONAL | ||
1239 | offset += 1 | ||
1240 | else: | ||
1241 | if class_table[settings.parent_index].type == CLASS_TYPE.MESSAGE: | ||
1242 | result.success = false | ||
1243 | result.error = indexed_tokens[offset].index | ||
1244 | result.description = "Using the 'required', 'optional' or 'repeated' qualificator necessarily in Protobuf v2." | ||
1245 | return result | ||
1246 | var type_name : String = indexed_tokens[offset].token.text; offset += 1 | ||
1247 | var field_name : String = indexed_tokens[offset].token.text; offset += 1 | ||
1248 | var tag : String = indexed_tokens[offset].token.text; offset += 1 | ||
1249 | |||
1250 | if indexed_tokens.size() == offset + 2: | ||
1251 | if indexed_tokens[offset].token.text == "packed": | ||
1252 | offset += 1 | ||
1253 | if indexed_tokens[offset].token.text == "true": | ||
1254 | option = FIELD_OPTION.PACKED | ||
1255 | else: | ||
1256 | option = FIELD_OPTION.NOT_PACKED | ||
1257 | else: | ||
1258 | result.success = false | ||
1259 | result.error = indexed_tokens[offset].index | ||
1260 | result.description = "Undefined field option." | ||
1261 | return result | ||
1262 | |||
1263 | if group_table.size() > 0: | ||
1264 | if group_table[group_table.size() - 1].opened: | ||
1265 | if indexed_tokens[0].token.id == TOKEN_ID.FIELD_QUALIFICATION: | ||
1266 | result.success = false | ||
1267 | result.error = indexed_tokens[0].index | ||
1268 | result.description = "Using the 'required', 'optional' or 'repeated' qualificator is unacceptable in 'OneOf' field." | ||
1269 | return result | ||
1270 | group_table[group_table.size() - 1].field_indexes.append(field_table.size()) | ||
1271 | field_table.append(ASTField.new(tag, field_name, type_name, settings.parent_index, qualifcator, option, settings.construction_index, false)) | ||
1272 | return result | ||
1273 | |||
1274 | func desc_map_field(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1275 | var result : DescriptionResult = DescriptionResult.new() | ||
1276 | var qualifcator : int = FIELD_QUALIFICATOR.REPEATED | ||
1277 | var option : int | ||
1278 | var offset : int = 0 | ||
1279 | |||
1280 | if proto_version == 3: | ||
1281 | option = FIELD_OPTION.PACKED | ||
1282 | if proto_version == 2: | ||
1283 | option = FIELD_OPTION.NOT_PACKED | ||
1284 | |||
1285 | var key_type_name : String = indexed_tokens[offset].token.text; offset += 1 | ||
1286 | if key_type_name == "float" || key_type_name == "double" || key_type_name == "bytes": | ||
1287 | result.success = false | ||
1288 | result.error = indexed_tokens[offset - 1].index | ||
1289 | result.description = "Map 'key_type' can't be floating point types and bytes." | ||
1290 | var type_name : String = indexed_tokens[offset].token.text; offset += 1 | ||
1291 | var field_name : String = indexed_tokens[offset].token.text; offset += 1 | ||
1292 | var tag : String = indexed_tokens[offset].token.text; offset += 1 | ||
1293 | |||
1294 | if indexed_tokens.size() == offset + 2: | ||
1295 | if indexed_tokens[offset].token.text == "packed": | ||
1296 | offset += 1 | ||
1297 | if indexed_tokens[offset] == "true": | ||
1298 | option = FIELD_OPTION.PACKED | ||
1299 | else: | ||
1300 | option = FIELD_OPTION.NOT_PACKED | ||
1301 | else: | ||
1302 | result.success = false | ||
1303 | result.error = indexed_tokens[offset].index | ||
1304 | result.description = "Undefined field option." | ||
1305 | |||
1306 | if group_table.size() > 0: | ||
1307 | if group_table[group_table.size() - 1].opened: | ||
1308 | group_table[group_table.size() - 1].field_indexes.append(field_table.size()) | ||
1309 | |||
1310 | class_table.append(ASTClass.new("map_type_" + field_name, CLASS_TYPE.MAP, settings.parent_index, settings.parent_name, "", settings.construction_index)) | ||
1311 | field_table.append(ASTField.new(tag, field_name, "map_type_" + field_name, settings.parent_index, qualifcator, option, settings.construction_index, false)) | ||
1312 | |||
1313 | field_table.append(ASTField.new(1, "key", key_type_name, class_table.size() - 1, FIELD_QUALIFICATOR.OPTIONAL, option, settings.construction_index, true)) | ||
1314 | field_table.append(ASTField.new(2, "value", type_name, class_table.size() - 1, FIELD_QUALIFICATOR.OPTIONAL, option, settings.construction_index, true)) | ||
1315 | |||
1316 | return result | ||
1317 | |||
1318 | func desc_enum(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1319 | var result : DescriptionResult = DescriptionResult.new() | ||
1320 | var option : String = "" | ||
1321 | var offset : int = 0 | ||
1322 | var type_name : String = indexed_tokens[offset].token.text; offset += 1 | ||
1323 | if indexed_tokens[offset].token.id == TOKEN_ID.ENUM_OPTION: | ||
1324 | if indexed_tokens[offset].token.text == "allow_alias" && indexed_tokens[offset + 1].token.text == "true": | ||
1325 | option = "allow_alias" | ||
1326 | offset += 2 | ||
1327 | var value : ASTEnumValue | ||
1328 | var enum_class : ASTClass = ASTClass.new(type_name, CLASS_TYPE.ENUM, settings.parent_index, settings.parent_name, option, settings.construction_index) | ||
1329 | var first_value : bool = true | ||
1330 | while offset < indexed_tokens.size(): | ||
1331 | if first_value: | ||
1332 | if indexed_tokens[offset + 1].token.text != "0": | ||
1333 | result.success = false | ||
1334 | result.error = indexed_tokens[offset + 1].index | ||
1335 | result.description = "For Enums, the default value is the first defined enum value, which must be 0." | ||
1336 | break | ||
1337 | first_value = false | ||
1338 | #if indexed_tokens[offset + 1].token.text[0] == "+" || indexed_tokens[offset + 1].token.text[0] == "-": | ||
1339 | # result.success = false | ||
1340 | # result.error = indexed_tokens[offset + 1].index | ||
1341 | # result.description = "For Enums, signed values are not allowed." | ||
1342 | # break | ||
1343 | value = ASTEnumValue.new(indexed_tokens[offset].token.text, indexed_tokens[offset + 1].token.text) | ||
1344 | enum_class.values.append(value) | ||
1345 | offset += 2 | ||
1346 | |||
1347 | class_table.append(enum_class) | ||
1348 | return result | ||
1349 | |||
1350 | func desc_message_head(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1351 | var result : DescriptionResult = DescriptionResult.new() | ||
1352 | class_table.append(ASTClass.new(indexed_tokens[0].token.text, CLASS_TYPE.MESSAGE, settings.parent_index, settings.parent_name, "", settings.construction_index)) | ||
1353 | settings.parent_index = class_table.size() - 1 | ||
1354 | settings.parent_name = settings.parent_name + "." + indexed_tokens[0].token.text | ||
1355 | return result | ||
1356 | |||
1357 | func desc_message_tail(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1358 | settings.parent_index = class_table[settings.parent_index].parent_index | ||
1359 | settings.parent_name = class_table[settings.parent_index + 1].parent_name | ||
1360 | var result : DescriptionResult = DescriptionResult.new() | ||
1361 | return result | ||
1362 | |||
1363 | func desc_oneof_head(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1364 | var result : DescriptionResult = DescriptionResult.new() | ||
1365 | for g in group_table: | ||
1366 | if g.parent_class_id == settings.parent_index && g.name == indexed_tokens[0].token.text: | ||
1367 | result.success = false | ||
1368 | result.error = indexed_tokens[0].index | ||
1369 | result.description = "OneOf name must be unique." | ||
1370 | return result | ||
1371 | group_table.append(ASTFieldGroup.new(indexed_tokens[0].token.text, settings.parent_index, AST_GROUP_RULE.ONEOF)) | ||
1372 | return result | ||
1373 | |||
1374 | func desc_oneof_tail(indexed_tokens : Array, settings : CompareSettings) -> DescriptionResult: | ||
1375 | group_table[group_table.size() - 1].opened = false | ||
1376 | var result : DescriptionResult = DescriptionResult.new() | ||
1377 | return result | ||
1378 | |||
1379 | func analyze() -> AnalyzeResult: | ||
1380 | var analyze_result : AnalyzeResult = AnalyzeResult.new() | ||
1381 | analyze_result.doc = document | ||
1382 | analyze_result.classes = class_table | ||
1383 | analyze_result.fields = field_table | ||
1384 | analyze_result.groups = group_table | ||
1385 | analyze_result.state = false | ||
1386 | var result : TokenResult = tokenizer() | ||
1387 | if result.errors.size() > 0: | ||
1388 | for v in result.errors: | ||
1389 | var spos : Helper.StringPosition = Helper.str_pos(document.text, v.position) | ||
1390 | var err_text : String = "Unexpected token intersection " + "'" + document.text.substr(v.position.begin, spos.length) + "'" | ||
1391 | printerr(Helper.error_string(document.name, spos.str_num, spos.column, err_text)) | ||
1392 | else: | ||
1393 | var integrity = check_tokens_integrity(result.tokens, document.text.length() - 1) | ||
1394 | if integrity.size() > 0: | ||
1395 | for v in integrity: | ||
1396 | var spos: Helper.StringPosition = Helper.str_pos(document.text, TokenPosition.new(v.begin, v.end)) | ||
1397 | var err_text : String = "Unexpected token " + "'" + document.text.substr(v.begin, spos.length) + "'" | ||
1398 | printerr(Helper.error_string(document.name, spos.str_num, spos.column, err_text)) | ||
1399 | else: | ||
1400 | analyze_result.tokens = result.tokens | ||
1401 | comment_space_processing(result.tokens) | ||
1402 | var syntax : TranslationResult = analyze_tokens(result.tokens) | ||
1403 | if !syntax.done: | ||
1404 | var pos_main : TokenPosition = Helper.text_pos(result.tokens, syntax.parse_token_index) | ||
1405 | var pos_inner : TokenPosition = Helper.text_pos(result.tokens, syntax.error_token_index) | ||
1406 | var spos_main : Helper.StringPosition = Helper.str_pos(document.text, pos_main) | ||
1407 | var spos_inner : Helper.StringPosition = Helper.str_pos(document.text, pos_inner) | ||
1408 | var err_text : String = "Syntax error in construction '" + result.tokens[syntax.parse_token_index].text + "'. " | ||
1409 | err_text += "Unacceptable use '" + result.tokens[syntax.error_token_index].text + "' at:" + str(spos_inner.str_num) + ":" + str(spos_inner.column) | ||
1410 | err_text += "\n" + syntax.error_description_text | ||
1411 | printerr(Helper.error_string(document.name, spos_main.str_num, spos_main.column, err_text)) | ||
1412 | else: | ||
1413 | analyze_result.version = proto_version | ||
1414 | analyze_result.imports = import_table | ||
1415 | analyze_result.syntax = syntax | ||
1416 | analyze_result.state = true | ||
1417 | return analyze_result | ||
1418 | |||
1419 | class Semantic: | ||
1420 | |||
1421 | var class_table : Array | ||
1422 | var field_table : Array | ||
1423 | var group_table : Array | ||
1424 | var syntax : Analysis.TranslationResult | ||
1425 | var tokens : Array | ||
1426 | var document : Document | ||
1427 | |||
1428 | func _init(analyze_result : AnalyzeResult): | ||
1429 | class_table = analyze_result.classes | ||
1430 | field_table = analyze_result.fields | ||
1431 | group_table = analyze_result.groups | ||
1432 | syntax = analyze_result.syntax | ||
1433 | tokens = analyze_result.tokens | ||
1434 | document = analyze_result.doc | ||
1435 | |||
1436 | |||
1437 | enum CHECK_SUBJECT { | ||
1438 | CLASS_NAME = 0, | ||
1439 | FIELD_NAME = 1, | ||
1440 | FIELD_TAG_NUMBER = 2, | ||
1441 | FIELD_TYPE = 3 | ||
1442 | } | ||
1443 | |||
1444 | var STRING_FIELD_TYPE = { | ||
1445 | "int32": Analysis.FIELD_TYPE.INT32, | ||
1446 | "sint32": Analysis.FIELD_TYPE.SINT32, | ||
1447 | "uint32": Analysis.FIELD_TYPE.UINT32, | ||
1448 | "int64": Analysis.FIELD_TYPE.INT64, | ||
1449 | "sint64": Analysis.FIELD_TYPE.SINT64, | ||
1450 | "uint64": Analysis.FIELD_TYPE.UINT64, | ||
1451 | "bool": Analysis.FIELD_TYPE.BOOL, | ||
1452 | "fixed32": Analysis.FIELD_TYPE.FIXED32, | ||
1453 | "sfixed32": Analysis.FIELD_TYPE.SFIXED32, | ||
1454 | "float": Analysis.FIELD_TYPE.FLOAT, | ||
1455 | "fixed64": Analysis.FIELD_TYPE.FIXED64, | ||
1456 | "sfixed64": Analysis.FIELD_TYPE.SFIXED64, | ||
1457 | "double": Analysis.FIELD_TYPE.DOUBLE, | ||
1458 | "string": Analysis.FIELD_TYPE.STRING, | ||
1459 | "bytes": Analysis.FIELD_TYPE.BYTES, | ||
1460 | "map": Analysis.FIELD_TYPE.MAP | ||
1461 | } | ||
1462 | |||
1463 | class CheckResult: | ||
1464 | func _init(mci : int, aci : int, ti : int, s : int): | ||
1465 | main_construction_index = mci | ||
1466 | associated_construction_index = aci | ||
1467 | table_index = ti | ||
1468 | subject = s | ||
1469 | |||
1470 | var main_construction_index: int = -1 | ||
1471 | var associated_construction_index: int = -1 | ||
1472 | var table_index: int = -1 | ||
1473 | var subject : int | ||
1474 | |||
1475 | func check_class_names() -> Array: | ||
1476 | var result : Array = [] | ||
1477 | for i in range(class_table.size()): | ||
1478 | var the_class_name : String = class_table[i].parent_name + "." + class_table[i].name | ||
1479 | for j in range(i + 1, class_table.size(), 1): | ||
1480 | var inner_name : String = class_table[j].parent_name + "." + class_table[j].name | ||
1481 | if inner_name == the_class_name: | ||
1482 | var check : CheckResult = CheckResult.new(class_table[j].construction_index, class_table[i].construction_index, j, CHECK_SUBJECT.CLASS_NAME) | ||
1483 | result.append(check) | ||
1484 | break | ||
1485 | return result | ||
1486 | |||
1487 | func check_field_names() -> Array: | ||
1488 | var result : Array = [] | ||
1489 | for i in range(field_table.size()): | ||
1490 | var the_class_name : String = class_table[field_table[i].parent_class_id].parent_name + "." + class_table[field_table[i].parent_class_id].name | ||
1491 | for j in range(i + 1, field_table.size(), 1): | ||
1492 | var inner_name : String = class_table[field_table[j].parent_class_id].parent_name + "." + class_table[field_table[j].parent_class_id].name | ||
1493 | if inner_name == the_class_name: | ||
1494 | if field_table[i].name == field_table[j].name: | ||
1495 | var check : CheckResult = CheckResult.new(field_table[j].construction_index, field_table[i].construction_index, j, CHECK_SUBJECT.FIELD_NAME) | ||
1496 | result.append(check) | ||
1497 | break | ||
1498 | if field_table[i].tag == field_table[j].tag: | ||
1499 | var check : CheckResult = CheckResult.new(field_table[j].construction_index, field_table[i].construction_index, j, CHECK_SUBJECT.FIELD_TAG_NUMBER) | ||
1500 | result.append(check) | ||
1501 | break | ||
1502 | return result | ||
1503 | |||
1504 | func find_full_class_name(the_class_name : String) -> int: | ||
1505 | for i in range(class_table.size()): | ||
1506 | if the_class_name == class_table[i].parent_name + "." + class_table[i].name: | ||
1507 | return i | ||
1508 | return -1 | ||
1509 | |||
1510 | func find_class_name(the_class_name : String) -> int: | ||
1511 | for i in range(class_table.size()): | ||
1512 | if the_class_name == class_table[i].name: | ||
1513 | return i | ||
1514 | return -1 | ||
1515 | |||
1516 | func get_class_childs(class_index : int) -> Array: | ||
1517 | var result : Array = [] | ||
1518 | for i in range(class_table.size()): | ||
1519 | if class_table[i].parent_index == class_index: | ||
1520 | result.append(i) | ||
1521 | return result | ||
1522 | |||
1523 | func find_in_childs(the_class_name : String, child_indexes : Array) -> int: | ||
1524 | for c in child_indexes: | ||
1525 | if the_class_name == class_table[c].name: | ||
1526 | return c | ||
1527 | return -1 | ||
1528 | |||
1529 | func determine_field_types() -> Array: | ||
1530 | var result : Array = [] | ||
1531 | for f in field_table: | ||
1532 | if STRING_FIELD_TYPE.has(f.type_name): | ||
1533 | f.field_type = STRING_FIELD_TYPE[f.type_name] | ||
1534 | else: | ||
1535 | if f.type_name[0] == ".": | ||
1536 | f.type_class_id = find_full_class_name(f.type_name) | ||
1537 | else: | ||
1538 | # Reset result from previous assignment, that can be incorrect because of merging of imports | ||
1539 | f.type_class_id = -1 | ||
1540 | var splited_name : Array = f.type_name.split(".", false) | ||
1541 | var cur_class_index : int = f.parent_class_id | ||
1542 | var exit : bool = false | ||
1543 | while(true): | ||
1544 | var find : bool = false | ||
1545 | if cur_class_index == -1: | ||
1546 | break | ||
1547 | for n in splited_name: | ||
1548 | var childs_and_parent : Array = get_class_childs(cur_class_index) | ||
1549 | var res_index : int = find_in_childs(n, childs_and_parent) | ||
1550 | if res_index >= 0: | ||
1551 | find = true | ||
1552 | cur_class_index = res_index | ||
1553 | else: | ||
1554 | if find: | ||
1555 | exit = true | ||
1556 | else: | ||
1557 | cur_class_index = class_table[cur_class_index].parent_index | ||
1558 | break | ||
1559 | if exit: | ||
1560 | break | ||
1561 | if find: | ||
1562 | f.type_class_id = cur_class_index | ||
1563 | break | ||
1564 | if f.type_class_id == -1: | ||
1565 | f.type_class_id = find_full_class_name("." + f.type_name) | ||
1566 | for i in range(field_table.size()): | ||
1567 | if field_table[i].field_type == Analysis.FIELD_TYPE.UNDEFINED: | ||
1568 | if field_table[i].type_class_id == -1: | ||
1569 | result.append(CheckResult.new(field_table[i].construction_index, field_table[i].construction_index, i, CHECK_SUBJECT.FIELD_TYPE)) | ||
1570 | else: | ||
1571 | if class_table[field_table[i].type_class_id].type == Analysis.CLASS_TYPE.ENUM: | ||
1572 | field_table[i].field_type = Analysis.FIELD_TYPE.ENUM | ||
1573 | elif class_table[field_table[i].type_class_id].type == Analysis.CLASS_TYPE.MESSAGE: | ||
1574 | field_table[i].field_type = Analysis.FIELD_TYPE.MESSAGE | ||
1575 | elif class_table[field_table[i].type_class_id].type == Analysis.CLASS_TYPE.MAP: | ||
1576 | field_table[i].field_type = Analysis.FIELD_TYPE.MAP | ||
1577 | else: | ||
1578 | result.append(CheckResult.new(field_table[i].construction_index, field_table[i].construction_index, i, CHECK_SUBJECT.FIELD_TYPE)) | ||
1579 | return result | ||
1580 | |||
1581 | func check_constructions() -> Array: | ||
1582 | var cl : Array = check_class_names() | ||
1583 | var fl : Array = check_field_names() | ||
1584 | var ft : Array = determine_field_types() | ||
1585 | return cl + fl + ft | ||
1586 | |||
1587 | func check() -> bool: | ||
1588 | var check_result : Array = check_constructions() | ||
1589 | if check_result.size() == 0: | ||
1590 | return true | ||
1591 | else: | ||
1592 | for v in check_result: | ||
1593 | var main_tok : int = syntax.constructions[v.main_construction_index].begin_token_index | ||
1594 | var assoc_tok : int = syntax.constructions[v.associated_construction_index].begin_token_index | ||
1595 | var main_err_pos : Helper.StringPosition = Helper.str_pos(document.text, Helper.text_pos(tokens, main_tok)) | ||
1596 | var assoc_err_pos : Helper.StringPosition = Helper.str_pos(document.text, Helper.text_pos(tokens, assoc_tok)) | ||
1597 | var err_text : String | ||
1598 | if v.subject == CHECK_SUBJECT.CLASS_NAME: | ||
1599 | var class_type = "Undefined" | ||
1600 | if class_table[v.table_index].type == Analysis.CLASS_TYPE.ENUM: | ||
1601 | class_type = "Enum" | ||
1602 | elif class_table[v.table_index].type == Analysis.CLASS_TYPE.MESSAGE: | ||
1603 | class_type = "Message" | ||
1604 | elif class_table[v.table_index].type == Analysis.CLASS_TYPE.MAP: | ||
1605 | class_type = "Map" | ||
1606 | err_text = class_type + " name '" + class_table[v.table_index].name + "' is already defined at:" + str(assoc_err_pos.str_num) + ":" + str(assoc_err_pos.column) | ||
1607 | elif v.subject == CHECK_SUBJECT.FIELD_NAME: | ||
1608 | err_text = "Field name '" + field_table[v.table_index].name + "' is already defined at:" + str(assoc_err_pos.str_num) + ":" + str(assoc_err_pos.column) | ||
1609 | elif v.subject == CHECK_SUBJECT.FIELD_TAG_NUMBER: | ||
1610 | err_text = "Tag number '" + field_table[v.table_index].tag + "' is already defined at:" + str(assoc_err_pos.str_num) + ":" + str(assoc_err_pos.column) | ||
1611 | elif v.subject == CHECK_SUBJECT.FIELD_TYPE: | ||
1612 | err_text = "Type '" + field_table[v.table_index].type_name + "' of the '" + field_table[v.table_index].name + "' field undefined" | ||
1613 | else: | ||
1614 | err_text = "Undefined error" | ||
1615 | printerr(Helper.error_string(document.name, main_err_pos.str_num, main_err_pos.column, err_text)) | ||
1616 | return false | ||
1617 | |||
1618 | class Translator: | ||
1619 | |||
1620 | var class_table : Array | ||
1621 | var field_table : Array | ||
1622 | var group_table : Array | ||
1623 | var proto_version : int | ||
1624 | |||
1625 | func _init(analyzer_result : AnalyzeResult): | ||
1626 | class_table = analyzer_result.classes | ||
1627 | field_table = analyzer_result.fields | ||
1628 | group_table = analyzer_result.groups | ||
1629 | proto_version = analyzer_result.version | ||
1630 | |||
1631 | func tabulate(text : String, nesting : int) -> String: | ||
1632 | var tab : String = "" | ||
1633 | for i in range(nesting): | ||
1634 | tab += "\t" | ||
1635 | return tab + text | ||
1636 | |||
1637 | func default_dict_text() -> String: | ||
1638 | if proto_version == 2: | ||
1639 | return "DEFAULT_VALUES_2" | ||
1640 | elif proto_version == 3: | ||
1641 | return "DEFAULT_VALUES_3" | ||
1642 | return "TRANSLATION_ERROR" | ||
1643 | |||
1644 | func generate_field_type(field : Analysis.ASTField) -> String: | ||
1645 | var text : String = "PB_DATA_TYPE." | ||
1646 | if field.field_type == Analysis.FIELD_TYPE.INT32: | ||
1647 | return text + "INT32" | ||
1648 | elif field.field_type == Analysis.FIELD_TYPE.SINT32: | ||
1649 | return text + "SINT32" | ||
1650 | elif field.field_type == Analysis.FIELD_TYPE.UINT32: | ||
1651 | return text + "UINT32" | ||
1652 | elif field.field_type == Analysis.FIELD_TYPE.INT64: | ||
1653 | return text + "INT64" | ||
1654 | elif field.field_type == Analysis.FIELD_TYPE.SINT64: | ||
1655 | return text + "SINT64" | ||
1656 | elif field.field_type == Analysis.FIELD_TYPE.UINT64: | ||
1657 | return text + "UINT64" | ||
1658 | elif field.field_type == Analysis.FIELD_TYPE.BOOL: | ||
1659 | return text + "BOOL" | ||
1660 | elif field.field_type == Analysis.FIELD_TYPE.ENUM: | ||
1661 | return text + "ENUM" | ||
1662 | elif field.field_type == Analysis.FIELD_TYPE.FIXED32: | ||
1663 | return text + "FIXED32" | ||
1664 | elif field.field_type == Analysis.FIELD_TYPE.SFIXED32: | ||
1665 | return text + "SFIXED32" | ||
1666 | elif field.field_type == Analysis.FIELD_TYPE.FLOAT: | ||
1667 | return text + "FLOAT" | ||
1668 | elif field.field_type == Analysis.FIELD_TYPE.FIXED64: | ||
1669 | return text + "FIXED64" | ||
1670 | elif field.field_type == Analysis.FIELD_TYPE.SFIXED64: | ||
1671 | return text + "SFIXED64" | ||
1672 | elif field.field_type == Analysis.FIELD_TYPE.DOUBLE: | ||
1673 | return text + "DOUBLE" | ||
1674 | elif field.field_type == Analysis.FIELD_TYPE.STRING: | ||
1675 | return text + "STRING" | ||
1676 | elif field.field_type == Analysis.FIELD_TYPE.BYTES: | ||
1677 | return text + "BYTES" | ||
1678 | elif field.field_type == Analysis.FIELD_TYPE.MESSAGE: | ||
1679 | return text + "MESSAGE" | ||
1680 | elif field.field_type == Analysis.FIELD_TYPE.MAP: | ||
1681 | return text + "MAP" | ||
1682 | return text | ||
1683 | |||
1684 | func generate_field_rule(field : Analysis.ASTField) -> String: | ||
1685 | var text : String = "PB_RULE." | ||
1686 | if field.qualificator == Analysis.FIELD_QUALIFICATOR.OPTIONAL: | ||
1687 | return text + "OPTIONAL" | ||
1688 | elif field.qualificator == Analysis.FIELD_QUALIFICATOR.REQUIRED: | ||
1689 | return text + "REQUIRED" | ||
1690 | elif field.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1691 | return text + "REPEATED" | ||
1692 | elif field.qualificator == Analysis.FIELD_QUALIFICATOR.RESERVED: | ||
1693 | return text + "RESERVED" | ||
1694 | return text | ||
1695 | |||
1696 | func generate_gdscript_type(field : Analysis.ASTField) -> String: | ||
1697 | if field.field_type == Analysis.FIELD_TYPE.MESSAGE: | ||
1698 | var type_name : String = class_table[field.type_class_id].parent_name + "." + class_table[field.type_class_id].name | ||
1699 | return type_name.substr(1, type_name.length() - 1) | ||
1700 | return generate_gdscript_simple_type(field) | ||
1701 | |||
1702 | func generate_gdscript_simple_type(field : Analysis.ASTField) -> String: | ||
1703 | if field.field_type == Analysis.FIELD_TYPE.INT32: | ||
1704 | return "int" | ||
1705 | elif field.field_type == Analysis.FIELD_TYPE.SINT32: | ||
1706 | return "int" | ||
1707 | elif field.field_type == Analysis.FIELD_TYPE.UINT32: | ||
1708 | return "int" | ||
1709 | elif field.field_type == Analysis.FIELD_TYPE.INT64: | ||
1710 | return "int" | ||
1711 | elif field.field_type == Analysis.FIELD_TYPE.SINT64: | ||
1712 | return "int" | ||
1713 | elif field.field_type == Analysis.FIELD_TYPE.UINT64: | ||
1714 | return "int" | ||
1715 | elif field.field_type == Analysis.FIELD_TYPE.BOOL: | ||
1716 | return "bool" | ||
1717 | elif field.field_type == Analysis.FIELD_TYPE.ENUM: | ||
1718 | return "" | ||
1719 | elif field.field_type == Analysis.FIELD_TYPE.FIXED32: | ||
1720 | return "int" | ||
1721 | elif field.field_type == Analysis.FIELD_TYPE.SFIXED32: | ||
1722 | return "int" | ||
1723 | elif field.field_type == Analysis.FIELD_TYPE.FLOAT: | ||
1724 | return "float" | ||
1725 | elif field.field_type == Analysis.FIELD_TYPE.FIXED64: | ||
1726 | return "int" | ||
1727 | elif field.field_type == Analysis.FIELD_TYPE.SFIXED64: | ||
1728 | return "int" | ||
1729 | elif field.field_type == Analysis.FIELD_TYPE.DOUBLE: | ||
1730 | return "float" | ||
1731 | elif field.field_type == Analysis.FIELD_TYPE.STRING: | ||
1732 | return "String" | ||
1733 | elif field.field_type == Analysis.FIELD_TYPE.BYTES: | ||
1734 | return "PackedByteArray" | ||
1735 | return "" | ||
1736 | |||
1737 | func generate_field_constructor(field_index : int, nesting : int) -> String: | ||
1738 | var text : String = "" | ||
1739 | var f : Analysis.ASTField = field_table[field_index] | ||
1740 | var field_name : String = "__" + f.name | ||
1741 | var pbfield_text : String | ||
1742 | var default_var_name := field_name + "_default" | ||
1743 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1744 | var type_name := generate_gdscript_type(f) | ||
1745 | if type_name: | ||
1746 | text = tabulate("var %s: Array[%s] = []\n" % [default_var_name, type_name], nesting) | ||
1747 | else: | ||
1748 | text = tabulate("var %s: Array = []\n" % [default_var_name], nesting) | ||
1749 | pbfield_text += field_name + " = PBField.new(" | ||
1750 | pbfield_text += "\"" + f.name + "\", " | ||
1751 | pbfield_text += generate_field_type(f) + ", " | ||
1752 | pbfield_text += generate_field_rule(f) + ", " | ||
1753 | pbfield_text += str(f.tag) + ", " | ||
1754 | if f.option == Analysis.FIELD_OPTION.PACKED: | ||
1755 | pbfield_text += "true" | ||
1756 | elif f.option == Analysis.FIELD_OPTION.NOT_PACKED: | ||
1757 | pbfield_text += "false" | ||
1758 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1759 | pbfield_text += ", " + default_var_name | ||
1760 | else: | ||
1761 | pbfield_text += ", " + default_dict_text() + "[" + generate_field_type(f) + "]" | ||
1762 | pbfield_text += ")\n" | ||
1763 | text += tabulate(pbfield_text, nesting) | ||
1764 | if f.is_map_field: | ||
1765 | text += tabulate(field_name + ".is_map_field = true\n", nesting) | ||
1766 | text += tabulate("service = PBServiceField.new()\n", nesting) | ||
1767 | text += tabulate("service.field = " + field_name + "\n", nesting) | ||
1768 | if f.field_type == Analysis.FIELD_TYPE.MESSAGE: | ||
1769 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1770 | text += tabulate("service.func_ref = Callable(self, \"add_" + f.name + "\")\n", nesting) | ||
1771 | else: | ||
1772 | text += tabulate("service.func_ref = Callable(self, \"new_" + f.name + "\")\n", nesting) | ||
1773 | elif f.field_type == Analysis.FIELD_TYPE.MAP: | ||
1774 | text += tabulate("service.func_ref = Callable(self, \"add_empty_" + f.name + "\")\n", nesting) | ||
1775 | text += tabulate("data[" + field_name + ".tag] = service\n", nesting) | ||
1776 | |||
1777 | return text | ||
1778 | |||
1779 | func generate_group_clear(field_index : int, nesting : int) -> String: | ||
1780 | for g in group_table: | ||
1781 | var text : String = "" | ||
1782 | var find : bool = false | ||
1783 | if g.parent_class_id == field_table[field_index].parent_class_id: | ||
1784 | for i in g.field_indexes: | ||
1785 | if field_index == i: | ||
1786 | find = true | ||
1787 | text += tabulate("data[" + field_table[i].tag + "].state = PB_SERVICE_STATE.FILLED\n", nesting) | ||
1788 | else: | ||
1789 | text += tabulate("__" + field_table[i].name + ".value = " + default_dict_text() + "[" + generate_field_type(field_table[i]) + "]\n", nesting) | ||
1790 | text += tabulate("data[" + field_table[i].tag + "].state = PB_SERVICE_STATE.UNFILLED\n", nesting) | ||
1791 | if find: | ||
1792 | return text | ||
1793 | return "" | ||
1794 | |||
1795 | func generate_has_oneof(field_index : int, nesting : int) -> String: | ||
1796 | for g in group_table: | ||
1797 | var text : String = "" | ||
1798 | if g.parent_class_id == field_table[field_index].parent_class_id: | ||
1799 | for i in g.field_indexes: | ||
1800 | if field_index == i: | ||
1801 | text += tabulate("func has_" + field_table[i].name + "() -> bool:\n", nesting) | ||
1802 | nesting += 1 | ||
1803 | text += tabulate("return data[" + field_table[i].tag + "].state == PB_SERVICE_STATE.FILLED\n", nesting) | ||
1804 | return text | ||
1805 | return "" | ||
1806 | |||
1807 | func generate_field(field_index : int, nesting : int) -> String: | ||
1808 | var text : String = "" | ||
1809 | var f : Analysis.ASTField = field_table[field_index] | ||
1810 | var varname : String = "__" + f.name | ||
1811 | text += tabulate("var " + varname + ": PBField\n", nesting) | ||
1812 | if f.field_type == Analysis.FIELD_TYPE.MESSAGE: | ||
1813 | var the_class_name : String = class_table[f.type_class_id].parent_name + "." + class_table[f.type_class_id].name | ||
1814 | the_class_name = the_class_name.substr(1, the_class_name.length() - 1) | ||
1815 | if f.qualificator != Analysis.FIELD_QUALIFICATOR.OPTIONAL: | ||
1816 | text += generate_has_oneof(field_index, nesting) | ||
1817 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1818 | text += tabulate("func get_" + f.name + "() -> Array[" + the_class_name + "]:\n", nesting) | ||
1819 | else: | ||
1820 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.OPTIONAL: | ||
1821 | text += tabulate("func has_" + f.name + "() -> bool:\n", nesting) | ||
1822 | nesting += 1 | ||
1823 | text += tabulate("if " + varname + ".value != null:\n", nesting) | ||
1824 | nesting += 1 | ||
1825 | text += tabulate("return true\n", nesting) | ||
1826 | nesting -= 1 | ||
1827 | text += tabulate("return false\n", nesting) | ||
1828 | nesting -= 1 | ||
1829 | text += tabulate("func get_" + f.name + "() -> " + the_class_name + ":\n", nesting) | ||
1830 | nesting += 1 | ||
1831 | text += tabulate("return " + varname + ".value\n", nesting) | ||
1832 | nesting -= 1 | ||
1833 | text += tabulate("func clear_" + f.name + "() -> void:\n", nesting) | ||
1834 | nesting += 1 | ||
1835 | text += tabulate("data[" + str(f.tag) + "].state = PB_SERVICE_STATE.UNFILLED\n", nesting) | ||
1836 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1837 | text += tabulate(varname + ".value.clear()\n", nesting) | ||
1838 | nesting -= 1 | ||
1839 | text += tabulate("func add_" + f.name + "() -> " + the_class_name + ":\n", nesting) | ||
1840 | nesting += 1 | ||
1841 | text += tabulate("var element = " + the_class_name + ".new()\n", nesting) | ||
1842 | text += tabulate(varname + ".value.append(element)\n", nesting) | ||
1843 | text += tabulate("return element\n", nesting) | ||
1844 | else: | ||
1845 | text += tabulate(varname + ".value = " + default_dict_text() + "[" + generate_field_type(f) + "]\n", nesting) | ||
1846 | nesting -= 1 | ||
1847 | text += tabulate("func new_" + f.name + "() -> " + the_class_name + ":\n", nesting) | ||
1848 | nesting += 1 | ||
1849 | text += generate_group_clear(field_index, nesting) | ||
1850 | text += tabulate(varname + ".value = " + the_class_name + ".new()\n", nesting) | ||
1851 | text += tabulate("return " + varname + ".value\n", nesting) | ||
1852 | elif f.field_type == Analysis.FIELD_TYPE.MAP: | ||
1853 | var the_parent_class_name : String = class_table[f.type_class_id].parent_name | ||
1854 | the_parent_class_name = the_parent_class_name.substr(1, the_parent_class_name.length() - 1) | ||
1855 | var the_class_name : String = the_parent_class_name + "." + class_table[f.type_class_id].name | ||
1856 | |||
1857 | text += generate_has_oneof(field_index, nesting) | ||
1858 | text += tabulate("func get_raw_" + f.name + "():\n", nesting) | ||
1859 | nesting += 1 | ||
1860 | text += tabulate("return " + varname + ".value\n", nesting) | ||
1861 | nesting -= 1 | ||
1862 | text += tabulate("func get_" + f.name + "():\n", nesting) | ||
1863 | nesting += 1 | ||
1864 | text += tabulate("return PBPacker.construct_map(" + varname + ".value)\n", nesting) | ||
1865 | nesting -= 1 | ||
1866 | text += tabulate("func clear_" + f.name + "():\n", nesting) | ||
1867 | nesting += 1 | ||
1868 | text += tabulate("data[" + str(f.tag) + "].state = PB_SERVICE_STATE.UNFILLED\n", nesting) | ||
1869 | text += tabulate(varname + ".value = " + default_dict_text() + "[" + generate_field_type(f) + "]\n", nesting) | ||
1870 | nesting -= 1 | ||
1871 | for i in range(field_table.size()): | ||
1872 | if field_table[i].parent_class_id == f.type_class_id && field_table[i].name == "value": | ||
1873 | var gd_type : String = generate_gdscript_simple_type(field_table[i]) | ||
1874 | var return_type : String = " -> " + the_class_name | ||
1875 | var value_return_type : String = "" | ||
1876 | if gd_type != "": | ||
1877 | value_return_type = return_type | ||
1878 | elif field_table[i].field_type == Analysis.FIELD_TYPE.MESSAGE: | ||
1879 | value_return_type = " -> " + the_parent_class_name + "." + field_table[i].type_name | ||
1880 | text += tabulate("func add_empty_" + f.name + "()" + return_type + ":\n", nesting) | ||
1881 | nesting += 1 | ||
1882 | text += generate_group_clear(field_index, nesting) | ||
1883 | text += tabulate("var element = " + the_class_name + ".new()\n", nesting) | ||
1884 | text += tabulate(varname + ".value.append(element)\n", nesting) | ||
1885 | text += tabulate("return element\n", nesting) | ||
1886 | nesting -= 1 | ||
1887 | if field_table[i].field_type == Analysis.FIELD_TYPE.MESSAGE: | ||
1888 | text += tabulate("func add_" + f.name + "(a_key)" + value_return_type + ":\n", nesting) | ||
1889 | nesting += 1 | ||
1890 | text += generate_group_clear(field_index, nesting) | ||
1891 | text += tabulate("var idx = -1\n", nesting) | ||
1892 | text += tabulate("for i in range(" + varname + ".value.size()):\n", nesting) | ||
1893 | nesting += 1 | ||
1894 | text += tabulate("if " + varname + ".value[i].get_key() == a_key:\n", nesting) | ||
1895 | nesting += 1 | ||
1896 | text += tabulate("idx = i\n", nesting) | ||
1897 | text += tabulate("break\n", nesting) | ||
1898 | nesting -= 2 | ||
1899 | text += tabulate("var element = " + the_class_name + ".new()\n", nesting) | ||
1900 | text += tabulate("element.set_key(a_key)\n", nesting) | ||
1901 | text += tabulate("if idx != -1:\n", nesting) | ||
1902 | nesting += 1 | ||
1903 | text += tabulate(varname + ".value[idx] = element\n", nesting) | ||
1904 | nesting -= 1 | ||
1905 | text += tabulate("else:\n", nesting) | ||
1906 | nesting += 1 | ||
1907 | text += tabulate(varname + ".value.append(element)\n", nesting) | ||
1908 | nesting -= 1 | ||
1909 | text += tabulate("return element.new_value()\n", nesting) | ||
1910 | else: | ||
1911 | text += tabulate("func add_" + f.name + "(a_key, a_value) -> void:\n", nesting) | ||
1912 | nesting += 1 | ||
1913 | text += generate_group_clear(field_index, nesting) | ||
1914 | text += tabulate("var idx = -1\n", nesting) | ||
1915 | text += tabulate("for i in range(" + varname + ".value.size()):\n", nesting) | ||
1916 | nesting += 1 | ||
1917 | text += tabulate("if " + varname + ".value[i].get_key() == a_key:\n", nesting) | ||
1918 | nesting += 1 | ||
1919 | text += tabulate("idx = i\n", nesting) | ||
1920 | text += tabulate("break\n", nesting) | ||
1921 | nesting -= 2 | ||
1922 | text += tabulate("var element = " + the_class_name + ".new()\n", nesting) | ||
1923 | text += tabulate("element.set_key(a_key)\n", nesting) | ||
1924 | text += tabulate("element.set_value(a_value)\n", nesting) | ||
1925 | text += tabulate("if idx != -1:\n", nesting) | ||
1926 | nesting += 1 | ||
1927 | text += tabulate(varname + ".value[idx] = element\n", nesting) | ||
1928 | nesting -= 1 | ||
1929 | text += tabulate("else:\n", nesting) | ||
1930 | nesting += 1 | ||
1931 | text += tabulate(varname + ".value.append(element)\n", nesting) | ||
1932 | nesting -= 1 | ||
1933 | break | ||
1934 | else: | ||
1935 | var gd_type : String = generate_gdscript_simple_type(f) | ||
1936 | var return_type : String = "" | ||
1937 | var argument_type : String = "" | ||
1938 | if gd_type != "": | ||
1939 | return_type = " -> " + gd_type | ||
1940 | argument_type = " : " + gd_type | ||
1941 | if f.qualificator != Analysis.FIELD_QUALIFICATOR.OPTIONAL: | ||
1942 | text += generate_has_oneof(field_index, nesting) | ||
1943 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1944 | var array_type := "[" + gd_type + "]" if gd_type else "" | ||
1945 | text += tabulate("func get_" + f.name + "() -> Array" + array_type + ":\n", nesting) | ||
1946 | else: | ||
1947 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.OPTIONAL: | ||
1948 | text += tabulate("func has_" + f.name + "() -> bool:\n", nesting) | ||
1949 | nesting += 1 | ||
1950 | text += tabulate("if " + varname + ".value != null:\n", nesting) | ||
1951 | nesting += 1 | ||
1952 | text += tabulate("return true\n", nesting) | ||
1953 | nesting -= 1 | ||
1954 | text += tabulate("return false\n", nesting) | ||
1955 | nesting -= 1 | ||
1956 | text += tabulate("func get_" + f.name + "()" + return_type + ":\n", nesting) | ||
1957 | nesting += 1 | ||
1958 | text += tabulate("return " + varname + ".value\n", nesting) | ||
1959 | nesting -= 1 | ||
1960 | text += tabulate("func clear_" + f.name + "() -> void:\n", nesting) | ||
1961 | nesting += 1 | ||
1962 | text += tabulate("data[" + str(f.tag) + "].state = PB_SERVICE_STATE.UNFILLED\n", nesting) | ||
1963 | if f.qualificator == Analysis.FIELD_QUALIFICATOR.REPEATED: | ||
1964 | text += tabulate(varname + ".value.clear()\n", nesting) | ||
1965 | nesting -= 1 | ||
1966 | text += tabulate("func add_" + f.name + "(value" + argument_type + ") -> void:\n", nesting) | ||
1967 | nesting += 1 | ||
1968 | text += tabulate(varname + ".value.append(value)\n", nesting) | ||
1969 | else: | ||
1970 | text += tabulate(varname + ".value = " + default_dict_text() + "[" + generate_field_type(f) + "]\n", nesting) | ||
1971 | nesting -= 1 | ||
1972 | text += tabulate("func set_" + f.name + "(value" + argument_type + ") -> void:\n", nesting) | ||
1973 | nesting += 1 | ||
1974 | text += generate_group_clear(field_index, nesting) | ||
1975 | text += tabulate(varname + ".value = value\n", nesting) | ||
1976 | return text | ||
1977 | |||
1978 | func generate_class(class_index : int, nesting : int) -> String: | ||
1979 | var text : String = "" | ||
1980 | if class_table[class_index].type == Analysis.CLASS_TYPE.MESSAGE || class_table[class_index].type == Analysis.CLASS_TYPE.MAP: | ||
1981 | var cls_pref : String = "" | ||
1982 | cls_pref += tabulate("class " + class_table[class_index].name + ":\n", nesting) | ||
1983 | nesting += 1 | ||
1984 | cls_pref += tabulate("func _init():\n", nesting) | ||
1985 | text += cls_pref | ||
1986 | nesting += 1 | ||
1987 | text += tabulate("var service\n", nesting) | ||
1988 | text += tabulate("\n", nesting) | ||
1989 | var field_text : String = "" | ||
1990 | for i in range(field_table.size()): | ||
1991 | if field_table[i].parent_class_id == class_index: | ||
1992 | text += generate_field_constructor(i, nesting) | ||
1993 | text += tabulate("\n", nesting) | ||
1994 | field_text += generate_field(i, nesting - 1) | ||
1995 | field_text += tabulate("\n", nesting - 1) | ||
1996 | nesting -= 1 | ||
1997 | text += tabulate("var data = {}\n", nesting) | ||
1998 | text += tabulate("\n", nesting) | ||
1999 | text += field_text | ||
2000 | for j in range(class_table.size()): | ||
2001 | if class_table[j].parent_index == class_index: | ||
2002 | var cl_text = generate_class(j, nesting) | ||
2003 | text += cl_text | ||
2004 | if class_table[j].type == Analysis.CLASS_TYPE.MESSAGE || class_table[j].type == Analysis.CLASS_TYPE.MAP: | ||
2005 | text += generate_class_services(nesting + 1) | ||
2006 | text += tabulate("\n", nesting + 1) | ||
2007 | elif class_table[class_index].type == Analysis.CLASS_TYPE.ENUM: | ||
2008 | text += tabulate("enum " + class_table[class_index].name + " {\n", nesting) | ||
2009 | nesting += 1 | ||
2010 | |||
2011 | var expected_prefix = class_table[class_index].name.to_snake_case().to_upper() + "_" | ||
2012 | var all_have_prefix = true | ||
2013 | for en in range(class_table[class_index].values.size()): | ||
2014 | var value_name = class_table[class_index].values[en].name | ||
2015 | all_have_prefix = all_have_prefix and value_name.begins_with(expected_prefix) and value_name != expected_prefix | ||
2016 | |||
2017 | for en in range(class_table[class_index].values.size()): | ||
2018 | var value_name = class_table[class_index].values[en].name | ||
2019 | if all_have_prefix: | ||
2020 | value_name = value_name.substr(expected_prefix.length()) | ||
2021 | var enum_val = value_name + " = " + class_table[class_index].values[en].value | ||
2022 | if en == class_table[class_index].values.size() - 1: | ||
2023 | text += tabulate(enum_val + "\n", nesting) | ||
2024 | else: | ||
2025 | text += tabulate(enum_val + ",\n", nesting) | ||
2026 | nesting -= 1 | ||
2027 | text += tabulate("}\n", nesting) | ||
2028 | text += tabulate("\n", nesting) | ||
2029 | |||
2030 | return text | ||
2031 | |||
2032 | func generate_class_services(nesting : int) -> String: | ||
2033 | var text : String = "" | ||
2034 | text += tabulate("func _to_string() -> String:\n", nesting) | ||
2035 | nesting += 1 | ||
2036 | text += tabulate("return PBPacker.message_to_string(data)\n", nesting) | ||
2037 | text += tabulate("\n", nesting) | ||
2038 | nesting -= 1 | ||
2039 | text += tabulate("func to_bytes() -> PackedByteArray:\n", nesting) | ||
2040 | nesting += 1 | ||
2041 | text += tabulate("return PBPacker.pack_message(data)\n", nesting) | ||
2042 | text += tabulate("\n", nesting) | ||
2043 | nesting -= 1 | ||
2044 | text += tabulate("func from_bytes(bytes : PackedByteArray, offset : int = 0, limit : int = -1) -> int:\n", nesting) | ||
2045 | nesting += 1 | ||
2046 | text += tabulate("var cur_limit = bytes.size()\n", nesting) | ||
2047 | text += tabulate("if limit != -1:\n", nesting) | ||
2048 | nesting += 1 | ||
2049 | text += tabulate("cur_limit = limit\n", nesting) | ||
2050 | nesting -= 1 | ||
2051 | text += tabulate("var result = PBPacker.unpack_message(data, bytes, offset, cur_limit)\n", nesting) | ||
2052 | text += tabulate("if result == cur_limit:\n", nesting) | ||
2053 | nesting += 1 | ||
2054 | text += tabulate("if PBPacker.check_required(data):\n", nesting) | ||
2055 | nesting += 1 | ||
2056 | text += tabulate("if limit == -1:\n", nesting) | ||
2057 | nesting += 1 | ||
2058 | text += tabulate("return PB_ERR.NO_ERRORS\n", nesting) | ||
2059 | nesting -= 2 | ||
2060 | text += tabulate("else:\n", nesting) | ||
2061 | nesting += 1 | ||
2062 | text += tabulate("return PB_ERR.REQUIRED_FIELDS\n", nesting) | ||
2063 | nesting -= 2 | ||
2064 | text += tabulate("elif limit == -1 && result > 0:\n", nesting) | ||
2065 | nesting += 1 | ||
2066 | text += tabulate("return PB_ERR.PARSE_INCOMPLETE\n", nesting) | ||
2067 | nesting -= 1 | ||
2068 | text += tabulate("return result\n", nesting) | ||
2069 | return text | ||
2070 | |||
2071 | func translate(file_name : String, core_file_name : String) -> bool: | ||
2072 | |||
2073 | var file : FileAccess = FileAccess.open(file_name, FileAccess.WRITE) | ||
2074 | if file == null: | ||
2075 | printerr("File: '", file_name, "' save error.") | ||
2076 | return false | ||
2077 | |||
2078 | if !FileAccess.file_exists(core_file_name): | ||
2079 | printerr("File: '", core_file_name, "' not found.") | ||
2080 | return false | ||
2081 | |||
2082 | var core_file : FileAccess = FileAccess.open(core_file_name, FileAccess.READ) | ||
2083 | if core_file == null: | ||
2084 | printerr("File: '", core_file_name, "' read error.") | ||
2085 | return false | ||
2086 | var core_text : String = core_file.get_as_text() | ||
2087 | core_file.close() | ||
2088 | |||
2089 | var text : String = "" | ||
2090 | var nesting : int = 0 | ||
2091 | core_text = core_text.replace(PROTO_VERSION_DEFAULT, PROTO_VERSION_CONST + str(proto_version)) | ||
2092 | text += core_text + "\n\n\n" | ||
2093 | text += "############### USER DATA BEGIN ################\n" | ||
2094 | var cls_user : String = "" | ||
2095 | for i in range(class_table.size()): | ||
2096 | if class_table[i].parent_index == -1: | ||
2097 | var cls_text = generate_class(i, nesting) | ||
2098 | cls_user += cls_text | ||
2099 | if class_table[i].type == Analysis.CLASS_TYPE.MESSAGE: | ||
2100 | nesting += 1 | ||
2101 | cls_user += generate_class_services(nesting) | ||
2102 | cls_user += tabulate("\n", nesting) | ||
2103 | nesting -= 1 | ||
2104 | text += "\n\n" | ||
2105 | text += cls_user | ||
2106 | text += "################ USER DATA END #################\n" | ||
2107 | file.store_string(text) | ||
2108 | file.close() | ||
2109 | if !FileAccess.file_exists(file_name): | ||
2110 | printerr("File: '", file_name, "' save error.") | ||
2111 | return false | ||
2112 | return true | ||
2113 | |||
2114 | |||
2115 | class ImportFile: | ||
2116 | func _init(sha : String, a_path : String, a_parent : int): | ||
2117 | sha256 = sha | ||
2118 | path = a_path | ||
2119 | parent_index = a_parent | ||
2120 | |||
2121 | var sha256 : String | ||
2122 | var path : String | ||
2123 | var parent_index : int | ||
2124 | |||
2125 | func parse_all(analyzes : Dictionary, imports : Array, path : String, full_name : String, parent_index : int) -> bool: | ||
2126 | |||
2127 | if !FileAccess.file_exists(full_name): | ||
2128 | printerr(full_name, ": not found.") | ||
2129 | return false | ||
2130 | |||
2131 | var file : FileAccess = FileAccess.open(full_name, FileAccess.READ) | ||
2132 | if file == null: | ||
2133 | printerr(full_name, ": read error.") | ||
2134 | return false | ||
2135 | var doc : Document = Document.new(full_name, file.get_as_text()) | ||
2136 | var sha : String = file.get_sha256(full_name) | ||
2137 | file.close() | ||
2138 | |||
2139 | if !analyzes.has(sha): | ||
2140 | print(full_name, ": parsing.") | ||
2141 | var analysis : Analysis = Analysis.new(path, doc) | ||
2142 | var an_result : AnalyzeResult = analysis.analyze() | ||
2143 | if an_result.state: | ||
2144 | analyzes[sha] = an_result | ||
2145 | var parent : int = imports.size() | ||
2146 | imports.append(ImportFile.new(sha, doc.name, parent_index)) | ||
2147 | for im in an_result.imports: | ||
2148 | if !parse_all(analyzes, imports, path, im.path, parent): | ||
2149 | return false | ||
2150 | else: | ||
2151 | printerr(doc.name + ": parsing error.") | ||
2152 | return false | ||
2153 | else: | ||
2154 | print(full_name, ": retrieving data from cache.") | ||
2155 | imports.append(ImportFile.new(sha, doc.name, parent_index)) | ||
2156 | return true | ||
2157 | |||
2158 | func union_analyses(a1 : AnalyzeResult, a2 : AnalyzeResult, only_classes : bool = true) -> void: | ||
2159 | var class_offset : int = a1.classes.size() | ||
2160 | var field_offset = a1.fields.size() | ||
2161 | for cl in a2.classes: | ||
2162 | var cur_class : Analysis.ASTClass = cl.copy() | ||
2163 | if cur_class.parent_index != -1: | ||
2164 | cur_class.parent_index += class_offset | ||
2165 | a1.classes.append(cur_class) | ||
2166 | if only_classes: | ||
2167 | return | ||
2168 | for fl in a2.fields: | ||
2169 | var cur_field : Analysis.ASTField = fl.copy() | ||
2170 | cur_field.parent_class_id += class_offset | ||
2171 | cur_field.type_class_id = -1 | ||
2172 | a1.fields.append(cur_field) | ||
2173 | for gr in a2.groups: | ||
2174 | var cur_group : Analysis.ASTFieldGroup = gr.copy() | ||
2175 | cur_group.parent_class_id += class_offset | ||
2176 | var indexes : Array = [] | ||
2177 | for i in cur_group.field_indexes: | ||
2178 | indexes.append(i + field_offset) | ||
2179 | cur_group.field_indexes = indexes | ||
2180 | a1.groups.append(cur_group) | ||
2181 | |||
2182 | func union_imports(analyzes : Dictionary, key : String, result : AnalyzeResult, keys : Array, nesting : int, use_public : bool = true, only_classes : bool = true) -> void: | ||
2183 | nesting += 1 | ||
2184 | for im in analyzes[key].imports: | ||
2185 | var find : bool = false | ||
2186 | for k in keys: | ||
2187 | if im.sha256 == k: | ||
2188 | find = true | ||
2189 | break | ||
2190 | if find: | ||
2191 | continue | ||
2192 | if (!use_public) || (use_public && ((im.public && nesting > 1) || nesting < 2)): | ||
2193 | keys.append(im.sha256) | ||
2194 | union_analyses(result, analyzes[im.sha256], only_classes) | ||
2195 | union_imports(analyzes, im.sha256, result, keys, nesting, use_public, only_classes) | ||
2196 | |||
2197 | func semantic_all(analyzes : Dictionary, imports : Array)-> bool: | ||
2198 | for k in analyzes.keys(): | ||
2199 | print(analyzes[k].doc.name, ": analysis.") | ||
2200 | var keys : Array = [] | ||
2201 | var analyze : AnalyzeResult = analyzes[k].soft_copy() | ||
2202 | keys.append(k) | ||
2203 | analyze.classes = [] | ||
2204 | for cl in analyzes[k].classes: | ||
2205 | analyze.classes.append(cl.copy()) | ||
2206 | union_imports(analyzes, k, analyze, keys, 0) | ||
2207 | var semantic : Semantic = Semantic.new(analyze) | ||
2208 | if !semantic.check(): | ||
2209 | printerr(analyzes[k].doc.name, ": analysis error.") | ||
2210 | return false | ||
2211 | return true | ||
2212 | |||
2213 | func translate_all(analyzes : Dictionary, file_name : String, core_file_name : String) -> bool: | ||
2214 | var first_key : String = analyzes.keys()[0] | ||
2215 | var analyze : AnalyzeResult = analyzes[first_key] | ||
2216 | var keys : Array = [] | ||
2217 | keys.append(first_key) | ||
2218 | union_imports(analyzes, first_key, analyze, keys, 0, false, false) | ||
2219 | print("Performing full semantic analysis.") | ||
2220 | var semantic : Semantic = Semantic.new(analyze) | ||
2221 | if !semantic.check(): | ||
2222 | return false | ||
2223 | print("Performing translation.") | ||
2224 | var translator : Translator = Translator.new(analyze) | ||
2225 | if !translator.translate(file_name, core_file_name): | ||
2226 | return false | ||
2227 | var first : bool = true | ||
2228 | return true | ||
2229 | |||
2230 | func work(path : String, in_file : String, out_file : String, core_file : String) -> bool: | ||
2231 | var in_full_name : String = path + in_file | ||
2232 | var imports : Array = [] | ||
2233 | var analyzes : Dictionary = {} | ||
2234 | |||
2235 | print("Compiling source: '", in_full_name, "', output: '", out_file, "'.") | ||
2236 | print("\n1. Parsing:") | ||
2237 | if parse_all(analyzes, imports, path, in_full_name, -1): | ||
2238 | print("* Parsing completed successfully. *") | ||
2239 | else: | ||
2240 | return false | ||
2241 | print("\n2. Perfoming semantic analysis:") | ||
2242 | if semantic_all(analyzes, imports): | ||
2243 | print("* Semantic analysis completed successfully. *") | ||
2244 | else: | ||
2245 | return false | ||
2246 | print("\n3. Output file creating:") | ||
2247 | if translate_all(analyzes, out_file, core_file): | ||
2248 | print("* Output file was created successfully. *") | ||
2249 | else: | ||
2250 | return false | ||
2251 | return true | ||
2252 | |||
2253 | func _ready(): | ||
2254 | pass | ||
diff --git a/vendor/godobuf/addons/protobuf/plugin.cfg b/vendor/godobuf/addons/protobuf/plugin.cfg new file mode 100644 index 0000000..6456a11 --- /dev/null +++ b/vendor/godobuf/addons/protobuf/plugin.cfg | |||
@@ -0,0 +1,7 @@ | |||
1 | [plugin] | ||
2 | |||
3 | name="Godobuf" | ||
4 | description="Google Protobuf implementation for Godot/GDScript" | ||
5 | author="oniksan" | ||
6 | version="0.6.1 for Godot 4.x.y" | ||
7 | script="protobuf_ui.gd" | ||
diff --git a/vendor/godobuf/addons/protobuf/protobuf_cmdln.gd b/vendor/godobuf/addons/protobuf/protobuf_cmdln.gd new file mode 100644 index 0000000..97d7ba4 --- /dev/null +++ b/vendor/godobuf/addons/protobuf/protobuf_cmdln.gd | |||
@@ -0,0 +1,66 @@ | |||
1 | # | ||
2 | # BSD 3-Clause License | ||
3 | # | ||
4 | # Copyright (c) 2018, Oleg Malyavkin | ||
5 | # All rights reserved. | ||
6 | # | ||
7 | # Redistribution and use in source and binary forms, with or without | ||
8 | # modification, are permitted provided that the following conditions are met: | ||
9 | # | ||
10 | # * Redistributions of source code must retain the above copyright notice, this | ||
11 | # list of conditions and the following disclaimer. | ||
12 | # | ||
13 | # * Redistributions in binary form must reproduce the above copyright notice, | ||
14 | # this list of conditions and the following disclaimer in the documentation | ||
15 | # and/or other materials provided with the distribution. | ||
16 | # | ||
17 | # * Neither the name of the copyright holder nor the names of its | ||
18 | # contributors may be used to endorse or promote products derived from | ||
19 | # this software without specific prior written permission. | ||
20 | # | ||
21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
29 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | extends SceneTree | ||
33 | |||
34 | var Parser = preload("res://addons/protobuf/parser.gd") | ||
35 | var Util = preload("res://addons/protobuf/protobuf_util.gd") | ||
36 | |||
37 | func error(msg : String): | ||
38 | push_error(msg) | ||
39 | quit() | ||
40 | |||
41 | func _init(): | ||
42 | var arguments = {} | ||
43 | for argument in OS.get_cmdline_args(): | ||
44 | if argument.find("=") > -1: | ||
45 | var key_value = argument.split("=") | ||
46 | arguments[key_value[0].lstrip("--")] = key_value[1] | ||
47 | |||
48 | if !arguments.has("input") || !arguments.has("output"): | ||
49 | error("Expected 2 Parameters: input and output") | ||
50 | |||
51 | var input_file_name = arguments["input"] | ||
52 | var output_file_name = arguments["output"] | ||
53 | |||
54 | var file = FileAccess.open(input_file_name, FileAccess.READ) | ||
55 | if file == null: | ||
56 | error("File: '" + input_file_name + "' not found.") | ||
57 | |||
58 | var parser = Parser.new() | ||
59 | |||
60 | if parser.work(Util.extract_dir(input_file_name), Util.extract_filename(input_file_name), \ | ||
61 | output_file_name, "res://addons/protobuf/protobuf_core.gd"): | ||
62 | print("Compiled '", input_file_name, "' to '", output_file_name, "'.") | ||
63 | else: | ||
64 | error("Compilation failed.") | ||
65 | |||
66 | quit() | ||
diff --git a/vendor/godobuf/addons/protobuf/protobuf_core.gd b/vendor/godobuf/addons/protobuf/protobuf_core.gd new file mode 100644 index 0000000..7098413 --- /dev/null +++ b/vendor/godobuf/addons/protobuf/protobuf_core.gd | |||
@@ -0,0 +1,668 @@ | |||
1 | # | ||
2 | # BSD 3-Clause License | ||
3 | # | ||
4 | # Copyright (c) 2018 - 2023, Oleg Malyavkin | ||
5 | # All rights reserved. | ||
6 | # | ||
7 | # Redistribution and use in source and binary forms, with or without | ||
8 | # modification, are permitted provided that the following conditions are met: | ||
9 | # | ||
10 | # * Redistributions of source code must retain the above copyright notice, this | ||
11 | # list of conditions and the following disclaimer. | ||
12 | # | ||
13 | # * Redistributions in binary form must reproduce the above copyright notice, | ||
14 | # this list of conditions and the following disclaimer in the documentation | ||
15 | # and/or other materials provided with the distribution. | ||
16 | # | ||
17 | # * Neither the name of the copyright holder nor the names of its | ||
18 | # contributors may be used to endorse or promote products derived from | ||
19 | # this software without specific prior written permission. | ||
20 | # | ||
21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
29 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | # DEBUG_TAB redefine this " " if you need, example: const DEBUG_TAB = "\t" | ||
33 | |||
34 | const PROTO_VERSION = 0 | ||
35 | |||
36 | const DEBUG_TAB : String = " " | ||
37 | |||
38 | enum PB_ERR { | ||
39 | NO_ERRORS = 0, | ||
40 | VARINT_NOT_FOUND = -1, | ||
41 | REPEATED_COUNT_NOT_FOUND = -2, | ||
42 | REPEATED_COUNT_MISMATCH = -3, | ||
43 | LENGTHDEL_SIZE_NOT_FOUND = -4, | ||
44 | LENGTHDEL_SIZE_MISMATCH = -5, | ||
45 | PACKAGE_SIZE_MISMATCH = -6, | ||
46 | UNDEFINED_STATE = -7, | ||
47 | PARSE_INCOMPLETE = -8, | ||
48 | REQUIRED_FIELDS = -9 | ||
49 | } | ||
50 | |||
51 | enum PB_DATA_TYPE { | ||
52 | INT32 = 0, | ||
53 | SINT32 = 1, | ||
54 | UINT32 = 2, | ||
55 | INT64 = 3, | ||
56 | SINT64 = 4, | ||
57 | UINT64 = 5, | ||
58 | BOOL = 6, | ||
59 | ENUM = 7, | ||
60 | FIXED32 = 8, | ||
61 | SFIXED32 = 9, | ||
62 | FLOAT = 10, | ||
63 | FIXED64 = 11, | ||
64 | SFIXED64 = 12, | ||
65 | DOUBLE = 13, | ||
66 | STRING = 14, | ||
67 | BYTES = 15, | ||
68 | MESSAGE = 16, | ||
69 | MAP = 17 | ||
70 | } | ||
71 | |||
72 | const DEFAULT_VALUES_2 = { | ||
73 | PB_DATA_TYPE.INT32: null, | ||
74 | PB_DATA_TYPE.SINT32: null, | ||
75 | PB_DATA_TYPE.UINT32: null, | ||
76 | PB_DATA_TYPE.INT64: null, | ||
77 | PB_DATA_TYPE.SINT64: null, | ||
78 | PB_DATA_TYPE.UINT64: null, | ||
79 | PB_DATA_TYPE.BOOL: null, | ||
80 | PB_DATA_TYPE.ENUM: null, | ||
81 | PB_DATA_TYPE.FIXED32: null, | ||
82 | PB_DATA_TYPE.SFIXED32: null, | ||
83 | PB_DATA_TYPE.FLOAT: null, | ||
84 | PB_DATA_TYPE.FIXED64: null, | ||
85 | PB_DATA_TYPE.SFIXED64: null, | ||
86 | PB_DATA_TYPE.DOUBLE: null, | ||
87 | PB_DATA_TYPE.STRING: null, | ||
88 | PB_DATA_TYPE.BYTES: null, | ||
89 | PB_DATA_TYPE.MESSAGE: null, | ||
90 | PB_DATA_TYPE.MAP: null | ||
91 | } | ||
92 | |||
93 | const DEFAULT_VALUES_3 = { | ||
94 | PB_DATA_TYPE.INT32: 0, | ||
95 | PB_DATA_TYPE.SINT32: 0, | ||
96 | PB_DATA_TYPE.UINT32: 0, | ||
97 | PB_DATA_TYPE.INT64: 0, | ||
98 | PB_DATA_TYPE.SINT64: 0, | ||
99 | PB_DATA_TYPE.UINT64: 0, | ||
100 | PB_DATA_TYPE.BOOL: false, | ||
101 | PB_DATA_TYPE.ENUM: 0, | ||
102 | PB_DATA_TYPE.FIXED32: 0, | ||
103 | PB_DATA_TYPE.SFIXED32: 0, | ||
104 | PB_DATA_TYPE.FLOAT: 0.0, | ||
105 | PB_DATA_TYPE.FIXED64: 0, | ||
106 | PB_DATA_TYPE.SFIXED64: 0, | ||
107 | PB_DATA_TYPE.DOUBLE: 0.0, | ||
108 | PB_DATA_TYPE.STRING: "", | ||
109 | PB_DATA_TYPE.BYTES: [], | ||
110 | PB_DATA_TYPE.MESSAGE: null, | ||
111 | PB_DATA_TYPE.MAP: [] | ||
112 | } | ||
113 | |||
114 | enum PB_TYPE { | ||
115 | VARINT = 0, | ||
116 | FIX64 = 1, | ||
117 | LENGTHDEL = 2, | ||
118 | STARTGROUP = 3, | ||
119 | ENDGROUP = 4, | ||
120 | FIX32 = 5, | ||
121 | UNDEFINED = 8 | ||
122 | } | ||
123 | |||
124 | enum PB_RULE { | ||
125 | OPTIONAL = 0, | ||
126 | REQUIRED = 1, | ||
127 | REPEATED = 2, | ||
128 | RESERVED = 3 | ||
129 | } | ||
130 | |||
131 | enum PB_SERVICE_STATE { | ||
132 | FILLED = 0, | ||
133 | UNFILLED = 1 | ||
134 | } | ||
135 | |||
136 | class PBField: | ||
137 | func _init(a_name : String, a_type : int, a_rule : int, a_tag : int, packed : bool, a_value = null): | ||
138 | name = a_name | ||
139 | type = a_type | ||
140 | rule = a_rule | ||
141 | tag = a_tag | ||
142 | option_packed = packed | ||
143 | value = a_value | ||
144 | |||
145 | var name : String | ||
146 | var type : int | ||
147 | var rule : int | ||
148 | var tag : int | ||
149 | var option_packed : bool | ||
150 | var value | ||
151 | var is_map_field : bool = false | ||
152 | var option_default : bool = false | ||
153 | |||
154 | class PBTypeTag: | ||
155 | var ok : bool = false | ||
156 | var type : int | ||
157 | var tag : int | ||
158 | var offset : int | ||
159 | |||
160 | class PBServiceField: | ||
161 | var field : PBField | ||
162 | var func_ref = null | ||
163 | var state : int = PB_SERVICE_STATE.UNFILLED | ||
164 | |||
165 | class PBPacker: | ||
166 | static func convert_signed(n : int) -> int: | ||
167 | if n < -2147483648: | ||
168 | return (n << 1) ^ (n >> 63) | ||
169 | else: | ||
170 | return (n << 1) ^ (n >> 31) | ||
171 | |||
172 | static func deconvert_signed(n : int) -> int: | ||
173 | if n & 0x01: | ||
174 | return ~(n >> 1) | ||
175 | else: | ||
176 | return (n >> 1) | ||
177 | |||
178 | static func pack_varint(value) -> PackedByteArray: | ||
179 | var varint : PackedByteArray = PackedByteArray() | ||
180 | if typeof(value) == TYPE_BOOL: | ||
181 | if value: | ||
182 | value = 1 | ||
183 | else: | ||
184 | value = 0 | ||
185 | for _i in range(9): | ||
186 | var b = value & 0x7F | ||
187 | value >>= 7 | ||
188 | if value: | ||
189 | varint.append(b | 0x80) | ||
190 | else: | ||
191 | varint.append(b) | ||
192 | break | ||
193 | if varint.size() == 9 && (varint[8] & 0x80 != 0): | ||
194 | varint.append(0x01) | ||
195 | return varint | ||
196 | |||
197 | static func pack_bytes(value, count : int, data_type : int) -> PackedByteArray: | ||
198 | var bytes : PackedByteArray = PackedByteArray() | ||
199 | if data_type == PB_DATA_TYPE.FLOAT: | ||
200 | var spb : StreamPeerBuffer = StreamPeerBuffer.new() | ||
201 | spb.put_float(value) | ||
202 | bytes = spb.get_data_array() | ||
203 | elif data_type == PB_DATA_TYPE.DOUBLE: | ||
204 | var spb : StreamPeerBuffer = StreamPeerBuffer.new() | ||
205 | spb.put_double(value) | ||
206 | bytes = spb.get_data_array() | ||
207 | else: | ||
208 | for _i in range(count): | ||
209 | bytes.append(value & 0xFF) | ||
210 | value >>= 8 | ||
211 | return bytes | ||
212 | |||
213 | static func unpack_bytes(bytes : PackedByteArray, index : int, count : int, data_type : int): | ||
214 | if data_type == PB_DATA_TYPE.FLOAT: | ||
215 | return bytes.decode_float(index) | ||
216 | elif data_type == PB_DATA_TYPE.DOUBLE: | ||
217 | return bytes.decode_double(index) | ||
218 | else: | ||
219 | # Convert to big endian | ||
220 | var slice: PackedByteArray = bytes.slice(index, index + count) | ||
221 | slice.reverse() | ||
222 | return slice | ||
223 | |||
224 | static func unpack_varint(varint_bytes) -> int: | ||
225 | var value : int = 0 | ||
226 | var i: int = varint_bytes.size() - 1 | ||
227 | while i > -1: | ||
228 | value = (value << 7) | (varint_bytes[i] & 0x7F) | ||
229 | i -= 1 | ||
230 | return value | ||
231 | |||
232 | static func pack_type_tag(type : int, tag : int) -> PackedByteArray: | ||
233 | return pack_varint((tag << 3) | type) | ||
234 | |||
235 | static func isolate_varint(bytes : PackedByteArray, index : int) -> PackedByteArray: | ||
236 | var i: int = index | ||
237 | while i <= index + 10: # Protobuf varint max size is 10 bytes | ||
238 | if !(bytes[i] & 0x80): | ||
239 | return bytes.slice(index, i + 1) | ||
240 | i += 1 | ||
241 | return [] # Unreachable | ||
242 | |||
243 | static func unpack_type_tag(bytes : PackedByteArray, index : int) -> PBTypeTag: | ||
244 | var varint_bytes : PackedByteArray = isolate_varint(bytes, index) | ||
245 | var result : PBTypeTag = PBTypeTag.new() | ||
246 | if varint_bytes.size() != 0: | ||
247 | result.ok = true | ||
248 | result.offset = varint_bytes.size() | ||
249 | var unpacked : int = unpack_varint(varint_bytes) | ||
250 | result.type = unpacked & 0x07 | ||
251 | result.tag = unpacked >> 3 | ||
252 | return result | ||
253 | |||
254 | static func pack_length_delimeted(type : int, tag : int, bytes : PackedByteArray) -> PackedByteArray: | ||
255 | var result : PackedByteArray = pack_type_tag(type, tag) | ||
256 | result.append_array(pack_varint(bytes.size())) | ||
257 | result.append_array(bytes) | ||
258 | return result | ||
259 | |||
260 | static func pb_type_from_data_type(data_type : int) -> int: | ||
261 | if data_type == PB_DATA_TYPE.INT32 || data_type == PB_DATA_TYPE.SINT32 || data_type == PB_DATA_TYPE.UINT32 || data_type == PB_DATA_TYPE.INT64 || data_type == PB_DATA_TYPE.SINT64 || data_type == PB_DATA_TYPE.UINT64 || data_type == PB_DATA_TYPE.BOOL || data_type == PB_DATA_TYPE.ENUM: | ||
262 | return PB_TYPE.VARINT | ||
263 | elif data_type == PB_DATA_TYPE.FIXED32 || data_type == PB_DATA_TYPE.SFIXED32 || data_type == PB_DATA_TYPE.FLOAT: | ||
264 | return PB_TYPE.FIX32 | ||
265 | elif data_type == PB_DATA_TYPE.FIXED64 || data_type == PB_DATA_TYPE.SFIXED64 || data_type == PB_DATA_TYPE.DOUBLE: | ||
266 | return PB_TYPE.FIX64 | ||
267 | elif data_type == PB_DATA_TYPE.STRING || data_type == PB_DATA_TYPE.BYTES || data_type == PB_DATA_TYPE.MESSAGE || data_type == PB_DATA_TYPE.MAP: | ||
268 | return PB_TYPE.LENGTHDEL | ||
269 | else: | ||
270 | return PB_TYPE.UNDEFINED | ||
271 | |||
272 | static func pack_field(field : PBField) -> PackedByteArray: | ||
273 | var type : int = pb_type_from_data_type(field.type) | ||
274 | var type_copy : int = type | ||
275 | if field.rule == PB_RULE.REPEATED && field.option_packed: | ||
276 | type = PB_TYPE.LENGTHDEL | ||
277 | var head : PackedByteArray = pack_type_tag(type, field.tag) | ||
278 | var data : PackedByteArray = PackedByteArray() | ||
279 | if type == PB_TYPE.VARINT: | ||
280 | var value | ||
281 | if field.rule == PB_RULE.REPEATED: | ||
282 | for v in field.value: | ||
283 | data.append_array(head) | ||
284 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
285 | value = convert_signed(v) | ||
286 | else: | ||
287 | value = v | ||
288 | data.append_array(pack_varint(value)) | ||
289 | return data | ||
290 | else: | ||
291 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
292 | value = convert_signed(field.value) | ||
293 | else: | ||
294 | value = field.value | ||
295 | data = pack_varint(value) | ||
296 | elif type == PB_TYPE.FIX32: | ||
297 | if field.rule == PB_RULE.REPEATED: | ||
298 | for v in field.value: | ||
299 | data.append_array(head) | ||
300 | data.append_array(pack_bytes(v, 4, field.type)) | ||
301 | return data | ||
302 | else: | ||
303 | data.append_array(pack_bytes(field.value, 4, field.type)) | ||
304 | elif type == PB_TYPE.FIX64: | ||
305 | if field.rule == PB_RULE.REPEATED: | ||
306 | for v in field.value: | ||
307 | data.append_array(head) | ||
308 | data.append_array(pack_bytes(v, 8, field.type)) | ||
309 | return data | ||
310 | else: | ||
311 | data.append_array(pack_bytes(field.value, 8, field.type)) | ||
312 | elif type == PB_TYPE.LENGTHDEL: | ||
313 | if field.rule == PB_RULE.REPEATED: | ||
314 | if type_copy == PB_TYPE.VARINT: | ||
315 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
316 | var signed_value : int | ||
317 | for v in field.value: | ||
318 | signed_value = convert_signed(v) | ||
319 | data.append_array(pack_varint(signed_value)) | ||
320 | else: | ||
321 | for v in field.value: | ||
322 | data.append_array(pack_varint(v)) | ||
323 | return pack_length_delimeted(type, field.tag, data) | ||
324 | elif type_copy == PB_TYPE.FIX32: | ||
325 | for v in field.value: | ||
326 | data.append_array(pack_bytes(v, 4, field.type)) | ||
327 | return pack_length_delimeted(type, field.tag, data) | ||
328 | elif type_copy == PB_TYPE.FIX64: | ||
329 | for v in field.value: | ||
330 | data.append_array(pack_bytes(v, 8, field.type)) | ||
331 | return pack_length_delimeted(type, field.tag, data) | ||
332 | elif field.type == PB_DATA_TYPE.STRING: | ||
333 | for v in field.value: | ||
334 | var obj = v.to_utf8_buffer() | ||
335 | data.append_array(pack_length_delimeted(type, field.tag, obj)) | ||
336 | return data | ||
337 | elif field.type == PB_DATA_TYPE.BYTES: | ||
338 | for v in field.value: | ||
339 | data.append_array(pack_length_delimeted(type, field.tag, v)) | ||
340 | return data | ||
341 | elif typeof(field.value[0]) == TYPE_OBJECT: | ||
342 | for v in field.value: | ||
343 | var obj : PackedByteArray = v.to_bytes() | ||
344 | data.append_array(pack_length_delimeted(type, field.tag, obj)) | ||
345 | return data | ||
346 | else: | ||
347 | if field.type == PB_DATA_TYPE.STRING: | ||
348 | var str_bytes : PackedByteArray = field.value.to_utf8_buffer() | ||
349 | if PROTO_VERSION == 2 || (PROTO_VERSION == 3 && str_bytes.size() > 0): | ||
350 | data.append_array(str_bytes) | ||
351 | return pack_length_delimeted(type, field.tag, data) | ||
352 | if field.type == PB_DATA_TYPE.BYTES: | ||
353 | if PROTO_VERSION == 2 || (PROTO_VERSION == 3 && field.value.size() > 0): | ||
354 | data.append_array(field.value) | ||
355 | return pack_length_delimeted(type, field.tag, data) | ||
356 | elif typeof(field.value) == TYPE_OBJECT: | ||
357 | var obj : PackedByteArray = field.value.to_bytes() | ||
358 | if obj.size() > 0: | ||
359 | data.append_array(obj) | ||
360 | return pack_length_delimeted(type, field.tag, data) | ||
361 | else: | ||
362 | pass | ||
363 | if data.size() > 0: | ||
364 | head.append_array(data) | ||
365 | return head | ||
366 | else: | ||
367 | return data | ||
368 | |||
369 | static func skip_unknown_field(bytes : PackedByteArray, offset : int, type : int) -> int: | ||
370 | if type == PB_TYPE.VARINT: | ||
371 | return offset + isolate_varint(bytes, offset).size() | ||
372 | if type == PB_TYPE.FIX64: | ||
373 | return offset + 8 | ||
374 | if type == PB_TYPE.LENGTHDEL: | ||
375 | var length_bytes : PackedByteArray = isolate_varint(bytes, offset) | ||
376 | var length : int = unpack_varint(length_bytes) | ||
377 | return offset + length_bytes.size() + length | ||
378 | if type == PB_TYPE.FIX32: | ||
379 | return offset + 4 | ||
380 | return PB_ERR.UNDEFINED_STATE | ||
381 | |||
382 | static func unpack_field(bytes : PackedByteArray, offset : int, field : PBField, type : int, message_func_ref) -> int: | ||
383 | if field.rule == PB_RULE.REPEATED && type != PB_TYPE.LENGTHDEL && field.option_packed: | ||
384 | var count = isolate_varint(bytes, offset) | ||
385 | if count.size() > 0: | ||
386 | offset += count.size() | ||
387 | count = unpack_varint(count) | ||
388 | if type == PB_TYPE.VARINT: | ||
389 | var val | ||
390 | var counter = offset + count | ||
391 | while offset < counter: | ||
392 | val = isolate_varint(bytes, offset) | ||
393 | if val.size() > 0: | ||
394 | offset += val.size() | ||
395 | val = unpack_varint(val) | ||
396 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
397 | val = deconvert_signed(val) | ||
398 | elif field.type == PB_DATA_TYPE.BOOL: | ||
399 | if val: | ||
400 | val = true | ||
401 | else: | ||
402 | val = false | ||
403 | field.value.append(val) | ||
404 | else: | ||
405 | return PB_ERR.REPEATED_COUNT_MISMATCH | ||
406 | return offset | ||
407 | elif type == PB_TYPE.FIX32 || type == PB_TYPE.FIX64: | ||
408 | var type_size | ||
409 | if type == PB_TYPE.FIX32: | ||
410 | type_size = 4 | ||
411 | else: | ||
412 | type_size = 8 | ||
413 | var val | ||
414 | var counter = offset + count | ||
415 | while offset < counter: | ||
416 | if (offset + type_size) > bytes.size(): | ||
417 | return PB_ERR.REPEATED_COUNT_MISMATCH | ||
418 | val = unpack_bytes(bytes, offset, type_size, field.type) | ||
419 | offset += type_size | ||
420 | field.value.append(val) | ||
421 | return offset | ||
422 | else: | ||
423 | return PB_ERR.REPEATED_COUNT_NOT_FOUND | ||
424 | else: | ||
425 | if type == PB_TYPE.VARINT: | ||
426 | var val = isolate_varint(bytes, offset) | ||
427 | if val.size() > 0: | ||
428 | offset += val.size() | ||
429 | val = unpack_varint(val) | ||
430 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
431 | val = deconvert_signed(val) | ||
432 | elif field.type == PB_DATA_TYPE.BOOL: | ||
433 | if val: | ||
434 | val = true | ||
435 | else: | ||
436 | val = false | ||
437 | if field.rule == PB_RULE.REPEATED: | ||
438 | field.value.append(val) | ||
439 | else: | ||
440 | field.value = val | ||
441 | else: | ||
442 | return PB_ERR.VARINT_NOT_FOUND | ||
443 | return offset | ||
444 | elif type == PB_TYPE.FIX32 || type == PB_TYPE.FIX64: | ||
445 | var type_size | ||
446 | if type == PB_TYPE.FIX32: | ||
447 | type_size = 4 | ||
448 | else: | ||
449 | type_size = 8 | ||
450 | var val | ||
451 | if (offset + type_size) > bytes.size(): | ||
452 | return PB_ERR.REPEATED_COUNT_MISMATCH | ||
453 | val = unpack_bytes(bytes, offset, type_size, field.type) | ||
454 | offset += type_size | ||
455 | if field.rule == PB_RULE.REPEATED: | ||
456 | field.value.append(val) | ||
457 | else: | ||
458 | field.value = val | ||
459 | return offset | ||
460 | elif type == PB_TYPE.LENGTHDEL: | ||
461 | var inner_size = isolate_varint(bytes, offset) | ||
462 | if inner_size.size() > 0: | ||
463 | offset += inner_size.size() | ||
464 | inner_size = unpack_varint(inner_size) | ||
465 | if inner_size >= 0: | ||
466 | if inner_size + offset > bytes.size(): | ||
467 | return PB_ERR.LENGTHDEL_SIZE_MISMATCH | ||
468 | if message_func_ref != null: | ||
469 | var message = message_func_ref.call() | ||
470 | if inner_size > 0: | ||
471 | var sub_offset = message.from_bytes(bytes, offset, inner_size + offset) | ||
472 | if sub_offset > 0: | ||
473 | if sub_offset - offset >= inner_size: | ||
474 | offset = sub_offset | ||
475 | return offset | ||
476 | else: | ||
477 | return PB_ERR.LENGTHDEL_SIZE_MISMATCH | ||
478 | return sub_offset | ||
479 | else: | ||
480 | return offset | ||
481 | elif field.type == PB_DATA_TYPE.STRING: | ||
482 | var str_bytes : PackedByteArray = bytes.slice(offset, inner_size + offset) | ||
483 | if field.rule == PB_RULE.REPEATED: | ||
484 | field.value.append(str_bytes.get_string_from_utf8()) | ||
485 | else: | ||
486 | field.value = str_bytes.get_string_from_utf8() | ||
487 | return offset + inner_size | ||
488 | elif field.type == PB_DATA_TYPE.BYTES: | ||
489 | var val_bytes : PackedByteArray = bytes.slice(offset, inner_size + offset) | ||
490 | if field.rule == PB_RULE.REPEATED: | ||
491 | field.value.append(val_bytes) | ||
492 | else: | ||
493 | field.value = val_bytes | ||
494 | return offset + inner_size | ||
495 | else: | ||
496 | return PB_ERR.LENGTHDEL_SIZE_NOT_FOUND | ||
497 | else: | ||
498 | return PB_ERR.LENGTHDEL_SIZE_NOT_FOUND | ||
499 | return PB_ERR.UNDEFINED_STATE | ||
500 | |||
501 | static func unpack_message(data, bytes : PackedByteArray, offset : int, limit : int) -> int: | ||
502 | while true: | ||
503 | var tt : PBTypeTag = unpack_type_tag(bytes, offset) | ||
504 | if tt.ok: | ||
505 | offset += tt.offset | ||
506 | if data.has(tt.tag): | ||
507 | var service : PBServiceField = data[tt.tag] | ||
508 | var type : int = pb_type_from_data_type(service.field.type) | ||
509 | if type == tt.type || (tt.type == PB_TYPE.LENGTHDEL && service.field.rule == PB_RULE.REPEATED && service.field.option_packed): | ||
510 | var res : int = unpack_field(bytes, offset, service.field, type, service.func_ref) | ||
511 | if res > 0: | ||
512 | service.state = PB_SERVICE_STATE.FILLED | ||
513 | offset = res | ||
514 | if offset == limit: | ||
515 | return offset | ||
516 | elif offset > limit: | ||
517 | return PB_ERR.PACKAGE_SIZE_MISMATCH | ||
518 | elif res < 0: | ||
519 | return res | ||
520 | else: | ||
521 | break | ||
522 | else: | ||
523 | var res : int = skip_unknown_field(bytes, offset, tt.type) | ||
524 | if res > 0: | ||
525 | offset = res | ||
526 | if offset == limit: | ||
527 | return offset | ||
528 | elif offset > limit: | ||
529 | return PB_ERR.PACKAGE_SIZE_MISMATCH | ||
530 | elif res < 0: | ||
531 | return res | ||
532 | else: | ||
533 | break | ||
534 | else: | ||
535 | return offset | ||
536 | return PB_ERR.UNDEFINED_STATE | ||
537 | |||
538 | static func pack_message(data) -> PackedByteArray: | ||
539 | var DEFAULT_VALUES | ||
540 | if PROTO_VERSION == 2: | ||
541 | DEFAULT_VALUES = DEFAULT_VALUES_2 | ||
542 | elif PROTO_VERSION == 3: | ||
543 | DEFAULT_VALUES = DEFAULT_VALUES_3 | ||
544 | var result : PackedByteArray = PackedByteArray() | ||
545 | var keys : Array = data.keys() | ||
546 | keys.sort() | ||
547 | for i in keys: | ||
548 | if data[i].field.value != null: | ||
549 | if data[i].state == PB_SERVICE_STATE.UNFILLED \ | ||
550 | && !data[i].field.is_map_field \ | ||
551 | && typeof(data[i].field.value) == typeof(DEFAULT_VALUES[data[i].field.type]) \ | ||
552 | && data[i].field.value == DEFAULT_VALUES[data[i].field.type]: | ||
553 | continue | ||
554 | elif data[i].field.rule == PB_RULE.REPEATED && data[i].field.value.size() == 0: | ||
555 | continue | ||
556 | result.append_array(pack_field(data[i].field)) | ||
557 | elif data[i].field.rule == PB_RULE.REQUIRED: | ||
558 | print("Error: required field is not filled: Tag:", data[i].field.tag) | ||
559 | return PackedByteArray() | ||
560 | return result | ||
561 | |||
562 | static func check_required(data) -> bool: | ||
563 | var keys : Array = data.keys() | ||
564 | for i in keys: | ||
565 | if data[i].field.rule == PB_RULE.REQUIRED && data[i].state == PB_SERVICE_STATE.UNFILLED: | ||
566 | return false | ||
567 | return true | ||
568 | |||
569 | static func construct_map(key_values): | ||
570 | var result = {} | ||
571 | for kv in key_values: | ||
572 | result[kv.get_key()] = kv.get_value() | ||
573 | return result | ||
574 | |||
575 | static func tabulate(text : String, nesting : int) -> String: | ||
576 | var tab : String = "" | ||
577 | for _i in range(nesting): | ||
578 | tab += DEBUG_TAB | ||
579 | return tab + text | ||
580 | |||
581 | static func value_to_string(value, field : PBField, nesting : int) -> String: | ||
582 | var result : String = "" | ||
583 | var text : String | ||
584 | if field.type == PB_DATA_TYPE.MESSAGE: | ||
585 | result += "{" | ||
586 | nesting += 1 | ||
587 | text = message_to_string(value.data, nesting) | ||
588 | if text != "": | ||
589 | result += "\n" + text | ||
590 | nesting -= 1 | ||
591 | result += tabulate("}", nesting) | ||
592 | else: | ||
593 | nesting -= 1 | ||
594 | result += "}" | ||
595 | elif field.type == PB_DATA_TYPE.BYTES: | ||
596 | result += "<" | ||
597 | for i in range(value.size()): | ||
598 | result += str(value[i]) | ||
599 | if i != (value.size() - 1): | ||
600 | result += ", " | ||
601 | result += ">" | ||
602 | elif field.type == PB_DATA_TYPE.STRING: | ||
603 | result += "\"" + value + "\"" | ||
604 | elif field.type == PB_DATA_TYPE.ENUM: | ||
605 | result += "ENUM::" + str(value) | ||
606 | else: | ||
607 | result += str(value) | ||
608 | return result | ||
609 | |||
610 | static func field_to_string(field : PBField, nesting : int) -> String: | ||
611 | var result : String = tabulate(field.name + ": ", nesting) | ||
612 | if field.type == PB_DATA_TYPE.MAP: | ||
613 | if field.value.size() > 0: | ||
614 | result += "(\n" | ||
615 | nesting += 1 | ||
616 | for i in range(field.value.size()): | ||
617 | var local_key_value = field.value[i].data[1].field | ||
618 | result += tabulate(value_to_string(local_key_value.value, local_key_value, nesting), nesting) + ": " | ||
619 | local_key_value = field.value[i].data[2].field | ||
620 | result += value_to_string(local_key_value.value, local_key_value, nesting) | ||
621 | if i != (field.value.size() - 1): | ||
622 | result += "," | ||
623 | result += "\n" | ||
624 | nesting -= 1 | ||
625 | result += tabulate(")", nesting) | ||
626 | else: | ||
627 | result += "()" | ||
628 | elif field.rule == PB_RULE.REPEATED: | ||
629 | if field.value.size() > 0: | ||
630 | result += "[\n" | ||
631 | nesting += 1 | ||
632 | for i in range(field.value.size()): | ||
633 | result += tabulate(str(i) + ": ", nesting) | ||
634 | result += value_to_string(field.value[i], field, nesting) | ||
635 | if i != (field.value.size() - 1): | ||
636 | result += "," | ||
637 | result += "\n" | ||
638 | nesting -= 1 | ||
639 | result += tabulate("]", nesting) | ||
640 | else: | ||
641 | result += "[]" | ||
642 | else: | ||
643 | result += value_to_string(field.value, field, nesting) | ||
644 | result += ";\n" | ||
645 | return result | ||
646 | |||
647 | static func message_to_string(data, nesting : int = 0) -> String: | ||
648 | var DEFAULT_VALUES | ||
649 | if PROTO_VERSION == 2: | ||
650 | DEFAULT_VALUES = DEFAULT_VALUES_2 | ||
651 | elif PROTO_VERSION == 3: | ||
652 | DEFAULT_VALUES = DEFAULT_VALUES_3 | ||
653 | var result : String = "" | ||
654 | var keys : Array = data.keys() | ||
655 | keys.sort() | ||
656 | for i in keys: | ||
657 | if data[i].field.value != null: | ||
658 | if data[i].state == PB_SERVICE_STATE.UNFILLED \ | ||
659 | && !data[i].field.is_map_field \ | ||
660 | && typeof(data[i].field.value) == typeof(DEFAULT_VALUES[data[i].field.type]) \ | ||
661 | && data[i].field.value == DEFAULT_VALUES[data[i].field.type]: | ||
662 | continue | ||
663 | elif data[i].field.rule == PB_RULE.REPEATED && data[i].field.value.size() == 0: | ||
664 | continue | ||
665 | result += field_to_string(data[i].field, nesting) | ||
666 | elif data[i].field.rule == PB_RULE.REQUIRED: | ||
667 | result += data[i].field.name + ": " + "error" | ||
668 | return result | ||
diff --git a/vendor/godobuf/addons/protobuf/protobuf_util.gd b/vendor/godobuf/addons/protobuf/protobuf_util.gd new file mode 100644 index 0000000..5941cb8 --- /dev/null +++ b/vendor/godobuf/addons/protobuf/protobuf_util.gd | |||
@@ -0,0 +1,46 @@ | |||
1 | # | ||
2 | # BSD 3-Clause License | ||
3 | # | ||
4 | # Copyright (c) 2018, Oleg Malyavkin | ||
5 | # All rights reserved. | ||
6 | # | ||
7 | # Redistribution and use in source and binary forms, with or without | ||
8 | # modification, are permitted provided that the following conditions are met: | ||
9 | # | ||
10 | # * Redistributions of source code must retain the above copyright notice, this | ||
11 | # list of conditions and the following disclaimer. | ||
12 | # | ||
13 | # * Redistributions in binary form must reproduce the above copyright notice, | ||
14 | # this list of conditions and the following disclaimer in the documentation | ||
15 | # and/or other materials provided with the distribution. | ||
16 | # | ||
17 | # * Neither the name of the copyright holder nor the names of its | ||
18 | # contributors may be used to endorse or promote products derived from | ||
19 | # this software without specific prior written permission. | ||
20 | # | ||
21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
29 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | static func extract_dir(file_path): | ||
33 | var parts = file_path.split("/", false) | ||
34 | parts.remove_at(parts.size() - 1) | ||
35 | var path | ||
36 | if file_path.begins_with("/"): | ||
37 | path = "/" | ||
38 | else: | ||
39 | path = "" | ||
40 | for part in parts: | ||
41 | path += part + "/" | ||
42 | return path | ||
43 | |||
44 | static func extract_filename(file_path): | ||
45 | var parts = file_path.split("/", false) | ||
46 | return parts[parts.size() - 1] | ||
diff --git a/vendor/godobuf/default_env.tres b/vendor/godobuf/default_env.tres new file mode 100644 index 0000000..20207a4 --- /dev/null +++ b/vendor/godobuf/default_env.tres | |||
@@ -0,0 +1,7 @@ | |||
1 | [gd_resource type="Environment" load_steps=2 format=2] | ||
2 | |||
3 | [sub_resource type="ProceduralSky" id=1] | ||
4 | |||
5 | [resource] | ||
6 | background_mode = 2 | ||
7 | background_sky = SubResource( 1 ) | ||
diff --git a/vendor/godobuf/logo.png b/vendor/godobuf/logo.png new file mode 100644 index 0000000..4ff9029 --- /dev/null +++ b/vendor/godobuf/logo.png | |||
Binary files differ | |||
diff --git a/vendor/godobuf/logo.png.import b/vendor/godobuf/logo.png.import new file mode 100644 index 0000000..43df7a6 --- /dev/null +++ b/vendor/godobuf/logo.png.import | |||
@@ -0,0 +1,35 @@ | |||
1 | [remap] | ||
2 | |||
3 | importer="texture" | ||
4 | type="StreamTexture" | ||
5 | path="res://.import/logo.png-cca8726399059c8d4f806e28e356b14d.stex" | ||
6 | metadata={ | ||
7 | "vram_texture": false | ||
8 | } | ||
9 | |||
10 | [deps] | ||
11 | |||
12 | source_file="res://logo.png" | ||
13 | dest_files=[ "res://.import/logo.png-cca8726399059c8d4f806e28e356b14d.stex" ] | ||
14 | |||
15 | [params] | ||
16 | |||
17 | compress/mode=0 | ||
18 | compress/lossy_quality=0.7 | ||
19 | compress/hdr_mode=0 | ||
20 | compress/bptc_ldr=0 | ||
21 | compress/normal_map=0 | ||
22 | flags/repeat=0 | ||
23 | flags/filter=true | ||
24 | flags/mipmaps=false | ||
25 | flags/anisotropic=false | ||
26 | flags/srgb=2 | ||
27 | process/fix_alpha_border=true | ||
28 | process/premult_alpha=false | ||
29 | process/HDR_as_SRGB=false | ||
30 | process/invert_color=false | ||
31 | process/normal_map_invert_y=false | ||
32 | stream=false | ||
33 | size_limit=0 | ||
34 | detect_3d=true | ||
35 | svg/scale=1.0 | ||
diff --git a/vendor/godobuf/project.godot b/vendor/godobuf/project.godot new file mode 100644 index 0000000..8cef0a4 --- /dev/null +++ b/vendor/godobuf/project.godot | |||
@@ -0,0 +1,26 @@ | |||
1 | ; Engine configuration file. | ||
2 | ; It's best edited using the editor UI and not directly, | ||
3 | ; since the parameters that go here are not all obvious. | ||
4 | ; | ||
5 | ; Format: | ||
6 | ; [section] ; section goes between [] | ||
7 | ; param=value ; assign values to parameters | ||
8 | |||
9 | config_version=4 | ||
10 | |||
11 | _global_script_classes=[ ] | ||
12 | _global_script_class_icons={ | ||
13 | } | ||
14 | |||
15 | [application] | ||
16 | |||
17 | config/name="Protobuf Plugin" | ||
18 | config/icon="res://logo.png" | ||
19 | |||
20 | [editor_plugins] | ||
21 | |||
22 | enabled=PoolStringArray( "res://addons/protobuf/plugin.cfg" ) | ||
23 | |||
24 | [rendering] | ||
25 | |||
26 | environment/default_environment="res://default_env.tres" | ||