#include "object.h" #include #include #include #include "world.h" static std::map allObjects; static bool objsInit = false; const std::map& MapObject::getAllObjects() { if (!objsInit) { try { xmlDocPtr doc = xmlParseFile("res/entities.xml"); if (doc == nullptr) { throw MapObjectLoadException("can't open file"); } xmlNodePtr top = xmlDocGetRootElement(doc); if (top == nullptr) { throw MapObjectLoadException("missing root element"); } if (xmlStrcmp(top->name, (const xmlChar*) "entities")) { throw MapObjectLoadException("root element is not entities"); } for (xmlNodePtr node = top->xmlChildrenNode; node != NULL; node = node->next) { if (!xmlStrcmp(node->name, (const xmlChar*) "entity")) { xmlChar* idKey = xmlGetProp(node, (xmlChar*) "id"); if (idKey == 0) throw MapObjectLoadException("entity missing id"); std::string theID = (char*) idKey; xmlFree(idKey); allObjects.emplace(theID, theID); MapObject& mapObject = allObjects.at(theID); xmlChar* nameKey = xmlGetProp(node, (xmlChar*) "name"); if (nameKey == 0) throw MapObjectLoadException("entity missing name"); mapObject.name = (char*) nameKey; xmlFree(nameKey); xmlChar* spriteKey = xmlGetProp(node, (xmlChar*) "sprite"); if (spriteKey == 0) throw MapObjectLoadException("entity missing sprite"); mapObject.sprite = wxImage((char*) spriteKey); xmlFree(spriteKey); xmlChar* widthKey = xmlGetProp(node, (xmlChar*) "width"); if (widthKey == 0) throw MapObjectLoadException("entity missing width"); mapObject.width = atoi((char*) widthKey); xmlFree(widthKey); xmlChar* heightKey = xmlGetProp(node, (xmlChar*) "height"); if (heightKey == 0) throw MapObjectLoadException("entity missing height"); mapObject.height = atoi((char*) heightKey); xmlFree(heightKey); for (xmlNodePtr entityNode = node->xmlChildrenNode; entityNode != NULL; entityNode = entityNode->next) { if (!xmlStrcmp(entityNode->name, (const xmlChar*) "input")) { xmlChar* key = xmlGetProp(entityNode, (xmlChar*) "id"); if (key == 0) throw MapObjectLoadException("input missing id"); std::string inputID = (char*) key; xmlFree(key); Input& input = mapObject.inputs[inputID]; key = xmlGetProp(entityNode, (xmlChar*) "name"); if (key == 0) throw MapObjectLoadException("input missing name"); input.name = (char*) key; xmlFree(key); key = xmlGetProp(entityNode, (xmlChar*) "type"); if (key == 0) throw MapObjectLoadException("input missing type"); std::string inputType = (char*) key; xmlFree(key); if (inputType == "choice") { input.type = Input::Type::Choice; for (xmlNodePtr choiceNode = entityNode->xmlChildrenNode; choiceNode != NULL; choiceNode = choiceNode->next) { if (!xmlStrcmp(choiceNode->name, (xmlChar*) "value")) { key = xmlGetProp(choiceNode, (xmlChar*) "id"); if (key == 0) throw MapObjectLoadException("input value missing id"); int valueId = atoi((char*) key); xmlFree(key); key = xmlNodeGetContent(choiceNode); if (key == 0) throw MapObjectLoadException("input value missing content"); std::string choiceText = (char*) key; xmlFree(key); input.choices[valueId] = choiceText; } } } else if (inputType == "slider") { input.type = Input::Type::Slider; key = xmlGetProp(entityNode, (xmlChar*) "minvalue"); if (key == 0) throw MapObjectLoadException("integer input missing minvalue"); input.minvalue = atoi((char*) key); xmlFree(key); key = xmlGetProp(entityNode, (xmlChar*) "maxvalue"); if (key == 0) throw MapObjectLoadException("integer input missing maxvalue"); input.maxvalue = atoi((char*) key); xmlFree(key); } } } } } } catch (std::exception& ex) { wxMessageBox(ex.what(), "Error loading objects", wxOK | wxCENTRE | wxICON_ERROR); exit(3); } objsInit = true; } return allObjects; } MapObject::MapObject(std::string id) : id(id) { } std::string MapObject::getID() const { return id; } std::string MapObject::getName() const { return name; } wxBitmap MapObject::getSprite() const { return sprite; } int MapObject::getWidth() const { return width; } int MapObject::getHeight() const { return height; } const std::map& MapObject::getInputs() const { return inputs; } const MapObject::Input& MapObject::getInput(std::string id) const { return inputs.at(id); } bool MapObject::operator==(const MapObject& other) const { return id == other.id; } bool MapObject::operator!=(const MapObject& other) const { return id != other.id; } MapObjectEntry::MapObjectEntry( const MapObject& object, int posx, int posy, size_t index) : object(object), position(std::make_pair(posx, posy)), index(index) { } const MapObject& MapObjectEntry::getObject() const { return object; } std::pair MapObjectEntry::getPosition() const { return position; } MapObjectEntry::Item& MapObjectEntry::getItem(std::string str) { return items[str]; } const std::map& MapObjectEntry::getItems() const { return items; } size_t MapObjectEntry::getIndex() const { return index; } void MapObjectEntry::addItem(std::string id, Item& item) { items[id] = item; } void MapObjectEntry::setPosition(int x, int y) { position = std::make_pair(x, y); } bool MapObjectEntry::operator==(const MapObjectEntry& other) const { return (object == other.object) && (position == other.position); } bool MapObjectEntry::operator!=(const MapObjectEntry& other) const { return (object != other.object) && (position != other.position); } VariableChoiceValidator::VariableChoiceValidator(World& world, MapObjectEntry::Item& item) : world(world), item(item) { } wxObject* VariableChoiceValidator::Clone() const { return new VariableChoiceValidator(world, item); } bool VariableChoiceValidator::TransferFromWindow() { wxChoice* choice = (wxChoice*) GetWindow(); int sel = choice->GetSelection(); int val = (intptr_t) choice->GetClientData(sel); item.intvalue = val; world.setDirty(true); return true; } bool VariableChoiceValidator::TransferToWindow() { wxChoice* choice = (wxChoice*) GetWindow(); for (size_t i=0; iGetCount(); i++) { if ((intptr_t) choice->GetClientData(i) == item.intvalue) { choice->SetSelection(i); return true; } } return false; } bool VariableChoiceValidator::Validate(wxWindow*) { return true; } SliderItemValidator::SliderItemValidator(World& world, MapObjectEntry::Item& item) : world(world), item(item) { } wxObject* SliderItemValidator::Clone() const { return new SliderItemValidator(world, item); } bool SliderItemValidator::TransferFromWindow() { wxSlider* slider = (wxSlider*) GetWindow(); item.intvalue = slider->GetValue(); world.setDirty(true); return true; } bool SliderItemValidator::TransferToWindow() { wxSlider* slider = (wxSlider*) GetWindow(); slider->SetValue(item.intvalue); return true; } bool SliderItemValidator::Validate(wxWindow*) { return true; } > 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
connections {
  from_room: "Main Area"
  to_room: "East Landscape"
}
connections {
  from_room: "Main Area"
  to_room: "West Side"
  door { name: "West/East Divider" }
}
connections {
  from_room: "West Side"
  to_room: "Main Area"
  door { name: "East/West Divider" }
}
connections {
  from_room: "East Landscape"
  to_room: "Purple Room"
  door { name: "Control Center Purple Door" }
}
connections {
  from_room: "Main Area"
  to_room: "Salmon Room"
  door { name: "Between Entrance" }
}
connections {
  from_room: "Main Area"
  to_room: "Daedalus Entrance"
  door { name: "Control Center Gray Door" }
}
connections {
  from_room: "West Side"
  to_room: "Jubilant Entrance"
  door { name: "Control Center Red Door" }
}
connections {
  from_room: "West Side"
  to_room: "Magnet Room"
  door { name: "Magnet Room Entrance" }
}
connections {
  from_room: "Hive Entrance"
  to_room: "West Side"
  door { name: "Hive Entrance" }
}
connections {
  from_room: "West Side"
  to_room: "Pillar Room"
  door { name: "Pillar Room Entrance" }
}
connections {
  from_room: "Pillar Room"
  to_room: "Colorful Entrance"
  door { name: "Colorful Entrance" }
  oneway: true
}
connections {
  from_room: "Colorful Entrance"
  to_room: "Pillar Room"
  oneway: true
}
connections {
  from_room: "West Side"
  to_room: "Outside Jail"
  door { name: "Jail Entrance" }
}
connections {
  from_room: "Outside Jail"
  to_room: "Jail Part 1"
  door { name: "Jail Mouth" }
  oneway: true
}
connections {
  from_room: "Jail Part 1"
  to_room: "Jail Part 2"
  door { name: "Jail First Bowels" }
}
connections {
  from_room: "Main Area"
  to_room: "Back Area"
  door { name: "Back Area Entrance" }
}
connections {
  from_room: "Outside Jail"
  to_room: "Back Area"
  oneway: true
}
connections {
  from_room: "Back Area"
  to_room: "West Side"
  oneway: true
}
connections {
  from_room: "Main Area"
  to_room: "Maze Start"
  door { name: "Courtyard Entrance" }
}
connections {
  from_room: "Maze Start"
  to_room: "Maze South Area"
  door { name: "Maze Out/South Door" }
}
connections {
  from_room: "Maze Start"
  to_room: "Maze Empty Vestibule"
  door { name: "Maze Out/Vestibule Door" }
}
connections {
  from_room: "Maze South Area"
  to_room: "Maze Up Area"
  door { name: "Maze South/Up Door" }
}
connections {
  from_room: "Maze Empty Vestibule"
  to_room: "Maze In Area"
  door { name: "Maze Vestibule/In Door" }
}
connections {
  from_room: "Maze Empty Vestibule"
  to_room: "Maze Off Area"
  door { name: "Maze Vestibule/Off Door" }
}
connections {
  from_room: "Maze In Area"
  to_room: "Maze Slice Area"
  door { name: "Maze In/Slice Door" }
}
connections {
  from_room: "Maze Slice Area"
  to_room: "Maze Smooth Area"
  door { name: "Maze Slice/Smooth Door" }
}
connections {
  from_room: "Maze Slice Area"
  to_room: "Maze Wreck Area"
  door { name: "Maze Slice/Wreck Door" }
}
connections {
  from_room: "Maze Wreck Area"
  to_room: "G Room"
  door { name: "G Door" }
}
connections {
  from_room: "Maze Slice Area"
  to_room: "Maze Cold Area"
  door { name: "Maze Slice/Cold Door" }
}
connections {
  from_room: "Maze Cold Area"
  to_room: "Maze Moon Area"
  door { name: "Maze Cold/Moon Door" }
}
connections {
  from_room: "Maze Cold Area"
  to_room: "Maze Off Area"
  door { name: "Maze Cold/Off Door" }
}
connections {
  from_room: "Maze Off Area"
  to_room: "Maze Center"
  door { name: "Maze Off/Center Door" }
}
connections {
  from_room: "Maze Off Area"
  to_room: "Maze Tower"
  door { name: "Maze Off/Tower Door" }
}
connections {
  from_room: "Maze Slice Area"
  to_room: "West Side"
  door { name: "Courtyard Side Door" }
}
connections {
  from_room: "West Side"
  to_room: "Question Room What"
  oneway: true
}
connections {
  from_room: "Question Room What"
  to_room: "Main Area"
  oneway: true
}
connections {
  from_room: "Question Room What"
  to_room: "Question Room How"
  door { name: "Question First Door" }
}
connections {
  from {
    painting {
      room: "Question Room How"
      name: "WHY"
    }
  }
  to {
    painting {
      room: "Question Room When"
      name: "WHY"
    }
  }
  oneway: true
}
connections {
  from_room: "Question Room When"
  to_room: "West Side"
  oneway: true
}
connections {
  from_room: "Question Room How"
  to_room: "Question Room Who"
  door { name: "Question Who Door" }
}
connections {
  from_room: "Question Room How"
  to_room: "Y Room"
  door { name: "Question Why Door" }
}
connections {
  from_room: "Y Room"
  to_room: "Under Question Room"
  door { name: "Big Y" }
  oneway: true
  # This is because the wall in the middle only opens if you grab Y1 from the
  # other side.
}
connections {
  from_room: "Under Question Room"
  to_room: "Talented Entrance"
  door { name: "Talented Entrance" }
}
connections {
  from_room: "Main Area"
  to_room: "Behind Question Area"
  door { name: "Near UC Painting Door" }
}
connections {
  from_room: "Behind Question Area"
  to_room: "Under Question Room"
  door { name: "Question Room Back Door" }
}
connections {
  from_room: "Main Area"
  to_room: "North Landscape"
  door { name: "North Landscape Entrance" }
}
connections {
  from_room: "North Landscape"
  to_room: "Nature Room"
  door { name: "Nature Room Door" }
}
connections {
  from_room: "North Landscape"
  to_room: "Whole Room"
}
connections {
  from_room: "Main Area"
  to_room: "Zero Room"
  door { name: "Lavender Cube" }
}