extends "res://scripts/load.gd"
func _load():
global._print("Hooked Load Start")
var apclient = global.get_node("Archipelago")
# Override the YOU panel with the AP slot name.
if self.get_node_or_null("Panels/Color Arrow Room/Panel_you") != null:
self.get_node("Panels/Color Arrow Room/Panel_you").answer = apclient.ap_user
for node in get_tree().get_nodes_in_group("text_you"):
if "text" in node:
node.text = apclient.ap_user
elif "value" in node:
node.value = apclient.ap_user
for node in get_tree().get_nodes_in_group("answer_you"):
if "answer" in node:
node.answer = apclient.ap_user
# This is the best time to create the location nodes, since the map is now
# loaded but the panels haven't been solved from the save file yet.
var panels_parent = self.get_node("Panels")
var location_script = ResourceLoader.load("user://maps/Archipelago/location.gd")
for location_id in apclient._panel_ids_by_location.keys():
var location = location_script.new()
location.ap_id = int(location_id)
location.name = "AP_location_" + location.ap_id
self.add_child(location)
var panels = apclient._panel_ids_by_location[String(location.ap_id)]
location.total = panels.size()
for panel in panels:
var that_panel
if panel.begins_with("EndPanel"):
that_panel = self.get_node("Decorations").get_node(panel)
else:
that_panel = panels_parent.get_node(panel)
that_panel.get_node("Viewport/GUI/Panel/TextEdit").connect(
"answer_correct", location, "handle_correct"
)
# Randomize the panels, if necessary.
var rng = RandomNumberGenerator.new()
rng.seed = apclient._slot_seed
var gamedata = apclient.get_node("Gamedata")
if apclient._panel_shuffle == apclient.kREARRANGE_PANELS:
# Do the actual shuffling.
var panel_pools = {}
for panel in gamedata.panels:
if not panel_pools.has(panel["tag"]):
panel_pools[panel["tag"]] = {}
var .highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */#include "game_data.h"
#include <hkutil/string.h>
#include <yaml-cpp/yaml.h>
#include <iostream>
#include <sstream>
#include "logger.h"
namespace {
LingoColor GetColorForString(const std::string &str) {
if (str == "black") {
return LingoColor::kBlack;
} else if (str == "red") {
return LingoColor::kRed;
} else if (str == "blue") {
return LingoColor::kBlue;
} else if (str == "yellow") {
return LingoColor::kYellow;
} else if (str == "orange") {
return LingoColor::kOrange;
} else if (str == "green") {
return LingoColor::kGreen;
} else if (str == "gray") {
return LingoColor::kGray;
} else if (str == "brown") {
return LingoColor::kBrown;
} else if (str == "purple") {
return LingoColor::kPurple;
} else {
std::ostringstream errmsg;
errmsg << "Invalid color: " << str;
TrackerLog(errmsg.str());
return LingoColor::kNone;
}
}
struct GameData {
std::vector<Room> rooms_;
std::vector<Door> doors_;
std::vector<Panel> panels_;
std::vector<MapArea> map_areas_;
std::map<std::string, int> room_by_id_;
std::map<std::string, int> door_by_id_;
std::map<std::string, int> panel_by_id_;
std::map<std::string, int> area_by_id_;
std::vector<int> door_definition_order_;
std::map<std::string, int> room_by_painting_;
std::vector<int> achievement_panels_;
std::map<LingoColor, int> ap_id_by_color_;
bool loaded_area_data_ = false;
std::set<std::string> malconfigured_areas_;
GameData() {
YAML::Node lingo_config = YAML::LoadFile("assets/LL1.yaml");
YAML::Node areas_config = YAML::LoadFile("assets/areas.yaml");
YAML::Node pilgrimage_config = YAML::LoadFile("assets/pilgrimage.yaml");
YAML::Node ids_config = YAML::LoadFile("assets/ids.yaml");
auto init_color_id = [this, &ids_config](const std::string &color_name) {
if (ids_config["special_items"] &&
ids_config["special_items"][color_name]) {
std::string input_name = color_name;
input_name[0] = std::tolower(input_name[0]);
ap_id_by_color_[GetColorForString(input_name)] =
ids_config["special_items"][color_name].as<int>();
} else {
std::ostringstream errmsg;
errmsg << "Missing AP item ID for color " << color_name;
TrackerLog(errmsg.str());
}
};
init_color_id("Black");
init_color_id("Red");
init_color_id("Blue");
init_color_id("Yellow");
init_color_id("Green");
init_color_id("Orange");
init_color_id("Purple");
init_color_id("Brown");
init_color_id("Gray");
rooms_.reserve(lingo_config.size() * 2);
for (const auto &room_it : lingo_config) {
int room_id = AddOrGetRoom(room_it.first.as<std::string>());
Room &room_obj = rooms_[room_id];
for (const auto &entrance_it : room_it.second["entrances"]) {
int from_room_id = AddOrGetRoom(entrance_it.first.as<std::string>());
Room &from_room_obj = rooms_[from_room_id];
switch (entrance_it.second.Type()) {
case YAML::NodeType::Scalar: {
// This is just "true".
from_room_obj.exits.push_back({.destination_room = room_id});
break;
}
case YAML::NodeType::Map: {
Exit exit_obj;
exit_obj.destination_room = room_id;
if (entrance_it.second["door"]) {
std::string door_room = room_obj.name;
if (entrance_it.second["room"]) {
door_room = entrance_it.second["room"].as<std::string>();
}
exit_obj.door = AddOrGetDoor(
door_room, entrance_it.second["door"].as<std::string>());
}
if (entrance_it.second["painting"]) {
exit_obj.painting = entrance_it.second["painting"].as<bool>();
}
from_room_obj.exits.push_back(exit_obj);
break;
}
case YAML::NodeType::Sequence: {
for (const auto &option : entrance_it.second) {
Exit exit_obj;
exit_obj.destination_room = room_id;
std::string door_room = room_obj.name;
if (option["room"]) {
door_room = option["room"].as<std::string>();
}
exit_obj.door =
AddOrGetDoor(door_room, option["door"].as<std::string>());
if (option["painting"]) {
exit_obj.painting = option["painting"].as<bool>();
}
from_room_obj.exits.push_back(exit_obj);
}
break;
}
default: {
// This shouldn't happen.
std::cout << "Error reading game data: " << entrance_it
<< std::endl;
break;
}
}
}
if (room_it.second["panels"]) {
for (const auto &panel_it : room_it.second["panels"]) {
int panel_id =
AddOrGetPanel(room_obj.name, panel_it.first.as<std::string>());
Panel &panel_obj = panels_[panel_id];
room_obj.panels.push_back(panel_id);
if (panel_it.second["colors"]) {
if (panel_it.second["colors"].IsScalar()) {
panel_obj.colors.push_back(GetColorForString(
panel_it.second["colors"].as<std::string>()));
} else {
for (const auto &color_node : panel_it.second["colors"]) {
panel_obj.colors.push_back(
GetColorForString(color_node.as<std::string>()));
}
}
}
if (panel_it.second["required_room"]) {
if (panel_it.second["required_room"].IsScalar()) {
panel_obj.required_rooms.push_back(AddOrGetRoom(
panel_it.second["required_room"].as<std::string>()));
} else {
for (const auto &