#include "events.h" #include "eventframes.h" #include "project.h" #include "config.h" QMap<Event::Group, const QPixmap*> Event::icons; Event::~Event() { if (this->eventFrame) this->eventFrame->deleteLater(); } EventFrame *Event::getEventFrame() { if (!this->eventFrame) createEventFrame(); return this->eventFrame; } void Event::destroyEventFrame() { if (this->eventFrame) delete this->eventFrame; this->eventFrame = nullptr; } void Event::setPixmapItem(DraggablePixmapItem *item) { this->pixmapItem = item; if (this->eventFrame) { this->eventFrame->invalidateConnections(); } } int Event::getEventIndex() { return this->map->events.value(this->getEventGroup()).indexOf(this); } void Event::setDefaultValues(Project *) { this->setX(0); this->setY(0); this->setElevation(projectConfig.defaultElevation); } void Event::readCustomValues(QJsonObject values) { this->customValues.clear(); QSet<QString> expectedFields = this->getExpectedFields(); for (QString key : values.keys()) { if (!expectedFields.contains(key)) { this->customValues[key] = values[key]; } } } void Event::addCustomValuesTo(OrderedJson::object *obj) { for (QString key : this->customValues.keys()) { if (!obj->contains(key)) { (*obj)[key] = OrderedJson::fromQJsonValue(this->customValues[key]); } } } void Event::modify() { this->map->modify(); } QString Event::eventGroupToString(Event::Group group) { switch (group) { case Event::Group::Object: return "Object"; case Event::Group::Warp: return "Warp"; case Event::Group::Coord: return "Trigger"; case Event::Group::Bg: return "BG"; case Event::Group::Heal: return "Healspot"; default: return ""; } } QString Event::eventTypeToString(Event::Type type) { switch (type) { case Event::Type::Object: return "event_object"; case Event::Type::CloneObject: return "event_clone_object"; case Event::Type::Warp: return "event_warp"; case Event::Type::Trigger: return "event_trigger"; case Event::Type::WeatherTrigger: return "event_weather_trigger"; case Event::Type::Sign: return "event_sign"; case Event::Type::HiddenItem: return "event_hidden_item"; case Event::Type::SecretBase: return "event_secret_base"; case Event::Type::HealLocation: return "event_healspot"; default: return ""; } } Event::Type Event::eventTypeFromString(QString type) { if (type == "event_object") { return Event::Type::Object; } else if (type == "event_clone_object") { return Event::Type::CloneObject; } else if (type == "event_warp") { return Event::Type::Warp; } else if (type == "event_trigger") { return Event::Type::Trigger; } else if (type == "event_weather_trigger") { return Event::Type::WeatherTrigger; } else if (type == "event_sign") { return Event::Type::Sign; } else if (type == "event_hidden_item") { return Event::Type::HiddenItem; } else if (type == "event_secret_base") { return Event::Type::SecretBase; } else if (type == "event_healspot") { return Event::Type::HealLocation; } else { return Event::Type::None; } } void Event::loadPixmap(Project *) { const QPixmap * pixmap = Event::icons.value(this->getEventGroup()); this->pixmap = pixmap ? *pixmap : QPixmap(); } void Event::setIcons() { qDeleteAll(icons); icons.clear(); const int w = 16; const int h = 16; static const QPixmap defaultIcons = QPixmap(":/images/Entities_16x16.png"); // Custom event icons may be provided by the user. const int numIcons = qMin(defaultIcons.width() / w, static_cast<int>(Event::Group::None)); for (int i = 0; i < numIcons; i++) { Event::Group group = static_cast<Event::Group>(i); QString customIconPath = projectConfig.getEventIconPath(group); if (customIconPath.isEmpty()) { // No custom icon specified, use the default icon. icons[group] = new QPixmap(defaultIcons.copy(i * w, 0, w, h)); continue; } // Try to load custom icon QString validPath = Project::getExistingFilepath(customIconPath); if (!validPath.isEmpty()) customIconPath = validPath; // Otherwise allow it to fail with the original path const QPixmap customIcon = QPixmap(customIconPath); if (customIcon.isNull()) { // Custom icon failed to load, use the default icon. icons[group] = new QPixmap(defaultIcons.copy(i * w, 0, w, h)); logWarn(QString("Failed to load custom event icon '%1', using default icon.").arg(customIconPath)); } else { icons[group] = new QPixmap(customIcon.scaled(w, h)); } } } Event *ObjectEvent::duplicate() { ObjectEvent *copy = new ObjectEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setGfx(this->getGfx()); copy->setMovement(this->getMovement()); copy->setRadiusX(this->getRadiusX()); copy->setRadiusY(this->getRadiusY()); copy->setTrainerType(this->getTrainerType()); copy->setSightRadiusBerryTreeID(this->getSightRadiusBerryTreeID()); copy->setScript(this->getScript()); copy->setFlag(this->getFlag()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *ObjectEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new ObjectFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object ObjectEvent::buildEventJson(Project *) { OrderedJson::object objectJson; if (projectConfig.eventCloneObjectEnabled) { objectJson["type"] = "object"; } objectJson["graphics_id"] = this->getGfx(); objectJson["x"] = this->getX(); objectJson["y"] = this->getY(); objectJson["elevation"] = this->getElevation(); objectJson["movement_type"] = this->getMovement(); objectJson["movement_range_x"] = this->getRadiusX(); objectJson["movement_range_y"] = this->getRadiusY(); objectJson["trainer_type"] = this->getTrainerType(); objectJson["trainer_sight_or_berry_tree_id"] = this->getSightRadiusBerryTreeID(); objectJson["script"] = this->getScript(); objectJson["flag"] = this->getFlag(); this->addCustomValuesTo(&objectJson); return objectJson; } bool ObjectEvent::loadFromJson(QJsonObject json, Project *) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setElevation(ParseUtil::jsonToInt(json["elevation"])); this->setGfx(ParseUtil::jsonToQString(json["graphics_id"])); this->setMovement(ParseUtil::jsonToQString(json["movement_type"])); this->setRadiusX(ParseUtil::jsonToInt(json["movement_range_x"])); this->setRadiusY(ParseUtil::jsonToInt(json["movement_range_y"])); this->setTrainerType(ParseUtil::jsonToQString(json["trainer_type"])); this->setSightRadiusBerryTreeID(ParseUtil::jsonToQString(json["trainer_sight_or_berry_tree_id"])); this->setScript(ParseUtil::jsonToQString(json["script"])); this->setFlag(ParseUtil::jsonToQString(json["flag"])); this->readCustomValues(json); return true; } void ObjectEvent::setDefaultValues(Project *project) { this->setGfx(project->gfxDefines.keys().value(0, "0")); this->setMovement(project->movementTypes.value(0, "0")); this->setScript("NULL"); this->setTrainerType(project->trainerTypes.value(0, "0")); this->setFlag("0"); this->setRadiusX(0); this->setRadiusY(0); this->setSightRadiusBerryTreeID("0"); this->setFrameFromMovement(project->facingDirections.value(this->getMovement())); } const QSet<QString> expectedObjectFields = { "graphics_id", "elevation", "movement_type", "movement_range_x", "movement_range_y", "trainer_type", "trainer_sight_or_berry_tree_id", "script", "flag", }; QSet<QString> ObjectEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedObjectFields; if (projectConfig.eventCloneObjectEnabled) { expectedFields.insert("type"); } expectedFields << "x" << "y"; return expectedFields; } void ObjectEvent::loadPixmap(Project *project) { EventGraphics *eventGfx = project->eventGraphicsMap.value(this->gfx, nullptr); if (!eventGfx) { // Invalid gfx constant. // If this is a number, try to use that instead. bool ok; int altGfx = ParseUtil::gameStringToInt(this->gfx, &ok); if (ok && (altGfx < project->gfxDefines.count())) { eventGfx = project->eventGraphicsMap.value(project->gfxDefines.key(altGfx, "NULL"), nullptr); } } if (!eventGfx || eventGfx->spritesheet.isNull()) { // No sprite associated with this gfx constant. // Use default sprite instead. Event::loadPixmap(project); this->spriteWidth = 16; this->spriteHeight = 16; this->usingSprite = false; } else { this->setFrameFromMovement(project->facingDirections.value(this->movement)); this->setPixmapFromSpritesheet(eventGfx); } } void ObjectEvent::setPixmapFromSpritesheet(EventGraphics * gfx) { QImage img; if (gfx->inanimate) { img = gfx->spritesheet.copy(0, 0, gfx->spriteWidth, gfx->spriteHeight); } else { int x = 0; int y = 0; // Get frame's position in spritesheet. // Assume horizontal layout. If position would exceed sheet width, try vertical layout. if ((this->frame + 1) * gfx->spriteWidth <= gfx->spritesheet.width()) { x = this->frame * gfx->spriteWidth; } else if ((this->frame + 1) * gfx->spriteHeight <= gfx->spritesheet.height()) { y = this->frame * gfx->spriteHeight; } img = gfx->spritesheet.copy(x, y, gfx->spriteWidth, gfx->spriteHeight); // Right-facing sprite is just the left-facing sprite mirrored if (this->hFlip) { img = img.transformed(QTransform().scale(-1, 1)); } } // Set first palette color fully transparent. img.setColor(0, qRgba(0, 0, 0, 0)); pixmap = QPixmap::fromImage(img); this->spriteWidth = gfx->spriteWidth; this->spriteHeight = gfx->spriteHeight; this->usingSprite = true; } void ObjectEvent::setFrameFromMovement(QString facingDir) { // defaults // TODO: read this from a file somewhere? this->frame = 0; this->hFlip = false; if (facingDir == "DIR_NORTH") { this->frame = 1; this->hFlip = false; } else if (facingDir == "DIR_SOUTH") { this->frame = 0; this->hFlip = false; } else if (facingDir == "DIR_WEST") { this->frame = 2; this->hFlip = false; } else if (facingDir == "DIR_EAST") { this->frame = 2; this->hFlip = true; } } Event *CloneObjectEvent::duplicate() { CloneObjectEvent *copy = new CloneObjectEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setGfx(this->getGfx()); copy->setTargetID(this->getTargetID()); copy->setTargetMap(this->getTargetMap()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *CloneObjectEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new CloneObjectFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object CloneObjectEvent::buildEventJson(Project *project) { OrderedJson::object cloneJson; cloneJson["type"] = "clone"; cloneJson["graphics_id"] = this->getGfx(); cloneJson["x"] = this->getX(); cloneJson["y"] = this->getY(); cloneJson["target_local_id"] = this->getTargetID(); cloneJson["target_map"] = project->mapNamesToMapConstants.value(this->getTargetMap()); this->addCustomValuesTo(&cloneJson); return cloneJson; } bool CloneObjectEvent::loadFromJson(QJsonObject json, Project *project) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setGfx(ParseUtil::jsonToQString(json["graphics_id"])); this->setTargetID(ParseUtil::jsonToInt(json["target_local_id"])); // Ensure the target map constant is valid before adding it to the events. const QString dynamicMapConstant = project->getDynamicMapDefineName(); QString mapConstant = ParseUtil::jsonToQString(json["target_map"]); if (project->mapConstantsToMapNames.contains(mapConstant)) { this->setTargetMap(project->mapConstantsToMapNames.value(mapConstant)); } else if (mapConstant == dynamicMapConstant) { this->setTargetMap(DYNAMIC_MAP_NAME); } else { logWarn(QString("Target Map constant '%1' is invalid. Using default '%2'.").arg(mapConstant).arg(dynamicMapConstant)); this->setTargetMap(DYNAMIC_MAP_NAME); } this->readCustomValues(json); return true; } void CloneObjectEvent::setDefaultValues(Project *project) { this->setGfx(project->gfxDefines.keys().value(0, "0")); this->setTargetID(1); if (this->getMap()) this->setTargetMap(this->getMap()->name); } const QSet<QString> expectedCloneObjectFields = { "type", "graphics_id", "target_local_id", "target_map", }; QSet<QString> CloneObjectEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedCloneObjectFields; expectedFields << "x" << "y"; return expectedFields; } void CloneObjectEvent::loadPixmap(Project *project) { // Try to get the targeted object to clone int eventIndex = this->targetID - 1; Map *clonedMap = project->getMap(this->targetMap); Event *clonedEvent = clonedMap ? clonedMap->events[Event::Group::Object].value(eventIndex, nullptr) : nullptr; if (clonedEvent && clonedEvent->getEventType() == Event::Type::Object) { // Get graphics data from cloned object ObjectEvent *clonedObject = dynamic_cast<ObjectEvent *>(clonedEvent); this->gfx = clonedObject->getGfx(); this->movement = clonedObject->getMovement(); } else { // Invalid object specified, use default graphics data (as would be shown in-game) this->gfx = project->gfxDefines.key(0, "0"); this->movement = project->movementTypes.value(0, "0"); } EventGraphics *eventGfx = project->eventGraphicsMap.value(gfx, nullptr); if (!eventGfx || eventGfx->spritesheet.isNull()) { // No sprite associated with this gfx constant. // Use default sprite instead. Event::loadPixmap(project); this->spriteWidth = 16; this->spriteHeight = 16; this->usingSprite = false; } else { this->setFrameFromMovement(project->facingDirections.value(this->movement)); this->setPixmapFromSpritesheet(eventGfx); } } Event *WarpEvent::duplicate() { WarpEvent *copy = new WarpEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setDestinationMap(this->getDestinationMap()); copy->setDestinationWarpID(this->getDestinationWarpID()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *WarpEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new WarpFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object WarpEvent::buildEventJson(Project *project) { OrderedJson::object warpJson; warpJson["x"] = this->getX(); warpJson["y"] = this->getY(); warpJson["elevation"] = this->getElevation(); warpJson["dest_map"] = project->mapNamesToMapConstants.value(this->getDestinationMap()); warpJson["dest_warp_id"] = this->getDestinationWarpID(); this->addCustomValuesTo(&warpJson); return warpJson; } bool WarpEvent::loadFromJson(QJsonObject json, Project *project) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setElevation(ParseUtil::jsonToInt(json["elevation"])); this->setDestinationWarpID(ParseUtil::jsonToQString(json["dest_warp_id"])); // Ensure the warp destination map constant is valid before adding it to the warps. const QString dynamicMapConstant = project->getDynamicMapDefineName(); QString mapConstant = ParseUtil::jsonToQString(json["dest_map"]); if (project->mapConstantsToMapNames.contains(mapConstant)) { this->setDestinationMap(project->mapConstantsToMapNames.value(mapConstant)); } else if (mapConstant == dynamicMapConstant) { this->setDestinationMap(DYNAMIC_MAP_NAME); } else { logWarn(QString("Destination Map constant '%1' is invalid. Using default '%2'.").arg(mapConstant).arg(dynamicMapConstant)); this->setDestinationMap(DYNAMIC_MAP_NAME); } this->readCustomValues(json); return true; } void WarpEvent::setDefaultValues(Project *) { if (this->getMap()) this->setDestinationMap(this->getMap()->name); this->setDestinationWarpID("0"); this->setElevation(0); } const QSet<QString> expectedWarpFields = { "elevation", "dest_map", "dest_warp_id", }; QSet<QString> WarpEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedWarpFields; expectedFields << "x" << "y"; return expectedFields; } void WarpEvent::setWarningEnabled(bool enabled) { WarpFrame * frame = static_cast<WarpFrame*>(this->getEventFrame()); if (frame && frame->warning) frame->warning->setVisible(enabled); } Event *TriggerEvent::duplicate() { TriggerEvent *copy = new TriggerEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setScriptVar(this->getScriptVar()); copy->setScriptVarValue(this->getScriptVarValue()); copy->setScriptLabel(this->getScriptLabel()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *TriggerEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new TriggerFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object TriggerEvent::buildEventJson(Project *) { OrderedJson::object triggerJson; triggerJson["type"] = "trigger"; triggerJson["x"] = this->getX(); triggerJson["y"] = this->getY(); triggerJson["elevation"] = this->getElevation(); triggerJson["var"] = this->getScriptVar(); triggerJson["var_value"] = this->getScriptVarValue(); triggerJson["script"] = this->getScriptLabel(); this->addCustomValuesTo(&triggerJson); return triggerJson; } bool TriggerEvent::loadFromJson(QJsonObject json, Project *) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setElevation(ParseUtil::jsonToInt(json["elevation"])); this->setScriptVar(ParseUtil::jsonToQString(json["var"])); this->setScriptVarValue(ParseUtil::jsonToQString(json["var_value"])); this->setScriptLabel(ParseUtil::jsonToQString(json["script"])); this->readCustomValues(json); return true; } void TriggerEvent::setDefaultValues(Project *project) { this->setScriptLabel("NULL"); this->setScriptVar(project->varNames.value(0, "0")); this->setScriptVarValue("0"); this->setElevation(0); } const QSet<QString> expectedTriggerFields = { "type", "elevation", "var", "var_value", "script", }; QSet<QString> TriggerEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedTriggerFields; expectedFields << "x" << "y"; return expectedFields; } Event *WeatherTriggerEvent::duplicate() { WeatherTriggerEvent *copy = new WeatherTriggerEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setWeather(this->getWeather()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *WeatherTriggerEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new WeatherTriggerFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object WeatherTriggerEvent::buildEventJson(Project *) { OrderedJson::object weatherJson; weatherJson["type"] = "weather"; weatherJson["x"] = this->getX(); weatherJson["y"] = this->getY(); weatherJson["elevation"] = this->getElevation(); weatherJson["weather"] = this->getWeather(); this->addCustomValuesTo(&weatherJson); return weatherJson; } bool WeatherTriggerEvent::loadFromJson(QJsonObject json, Project *) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setElevation(ParseUtil::jsonToInt(json["elevation"])); this->setWeather(ParseUtil::jsonToQString(json["weather"])); this->readCustomValues(json); return true; } void WeatherTriggerEvent::setDefaultValues(Project *project) { this->setWeather(project->coordEventWeatherNames.value(0, "0")); this->setElevation(0); } const QSet<QString> expectedWeatherTriggerFields = { "type", "elevation", "weather", }; QSet<QString> WeatherTriggerEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedWeatherTriggerFields; expectedFields << "x" << "y"; return expectedFields; } Event *SignEvent::duplicate() { SignEvent *copy = new SignEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setFacingDirection(this->getFacingDirection()); copy->setScriptLabel(this->getScriptLabel()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *SignEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new SignFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object SignEvent::buildEventJson(Project *) { OrderedJson::object signJson; signJson["type"] = "sign"; signJson["x"] = this->getX(); signJson["y"] = this->getY(); signJson["elevation"] = this->getElevation(); signJson["player_facing_dir"] = this->getFacingDirection(); signJson["script"] = this->getScriptLabel(); this->addCustomValuesTo(&signJson); return signJson; } bool SignEvent::loadFromJson(QJsonObject json, Project *) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setElevation(ParseUtil::jsonToInt(json["elevation"])); this->setFacingDirection(ParseUtil::jsonToQString(json["player_facing_dir"])); this->setScriptLabel(ParseUtil::jsonToQString(json["script"])); this->readCustomValues(json); return true; } void SignEvent::setDefaultValues(Project *project) { this->setFacingDirection(project->bgEventFacingDirections.value(0, "0")); this->setScriptLabel("NULL"); this->setElevation(0); } const QSet<QString> expectedSignFields = { "type", "elevation", "player_facing_dir", "script", }; QSet<QString> SignEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedSignFields; expectedFields << "x" << "y"; return expectedFields; } Event *HiddenItemEvent::duplicate() { HiddenItemEvent *copy = new HiddenItemEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setItem(this->getItem()); copy->setFlag(this->getFlag()); copy->setQuantity(this->getQuantity()); copy->setQuantity(this->getQuantity()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *HiddenItemEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new HiddenItemFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object HiddenItemEvent::buildEventJson(Project *) { OrderedJson::object hiddenItemJson; hiddenItemJson["type"] = "hidden_item"; hiddenItemJson["x"] = this->getX(); hiddenItemJson["y"] = this->getY(); hiddenItemJson["elevation"] = this->getElevation(); hiddenItemJson["item"] = this->getItem(); hiddenItemJson["flag"] = this->getFlag(); if (projectConfig.hiddenItemQuantityEnabled) { hiddenItemJson["quantity"] = this->getQuantity(); } if (projectConfig.hiddenItemRequiresItemfinderEnabled) { hiddenItemJson["underfoot"] = this->getUnderfoot(); } this->addCustomValuesTo(&hiddenItemJson); return hiddenItemJson; } bool HiddenItemEvent::loadFromJson(QJsonObject json, Project *) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setElevation(ParseUtil::jsonToInt(json["elevation"])); this->setItem(ParseUtil::jsonToQString(json["item"])); this->setFlag(ParseUtil::jsonToQString(json["flag"])); if (projectConfig.hiddenItemQuantityEnabled) { this->setQuantity(ParseUtil::jsonToInt(json["quantity"])); } if (projectConfig.hiddenItemRequiresItemfinderEnabled) { this->setUnderfoot(ParseUtil::jsonToBool(json["underfoot"])); } this->readCustomValues(json); return true; } void HiddenItemEvent::setDefaultValues(Project *project) { this->setItem(project->itemNames.value(0, "0")); this->setFlag(project->flagNames.value(0, "0")); if (projectConfig.hiddenItemQuantityEnabled) { this->setQuantity(1); } if (projectConfig.hiddenItemRequiresItemfinderEnabled) { this->setUnderfoot(false); } } const QSet<QString> expectedHiddenItemFields = { "type", "elevation", "item", "flag", }; QSet<QString> HiddenItemEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedHiddenItemFields; if (projectConfig.hiddenItemQuantityEnabled) { expectedFields << "quantity"; } if (projectConfig.hiddenItemRequiresItemfinderEnabled) { expectedFields << "underfoot"; } expectedFields << "x" << "y"; return expectedFields; } Event *SecretBaseEvent::duplicate() { SecretBaseEvent *copy = new SecretBaseEvent(); copy->setX(this->getX()); copy->setY(this->getY()); copy->setElevation(this->getElevation()); copy->setBaseID(this->getBaseID()); copy->setCustomValues(this->getCustomValues()); return copy; } EventFrame *SecretBaseEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new SecretBaseFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object SecretBaseEvent::buildEventJson(Project *) { OrderedJson::object secretBaseJson; secretBaseJson["type"] = "secret_base"; secretBaseJson["x"] = this->getX(); secretBaseJson["y"] = this->getY(); secretBaseJson["elevation"] = this->getElevation(); secretBaseJson["secret_base_id"] = this->getBaseID(); this->addCustomValuesTo(&secretBaseJson); return secretBaseJson; } bool SecretBaseEvent::loadFromJson(QJsonObject json, Project *) { this->setX(ParseUtil::jsonToInt(json["x"])); this->setY(ParseUtil::jsonToInt(json["y"])); this->setElevation(ParseUtil::jsonToInt(json["elevation"])); this->setBaseID(ParseUtil::jsonToQString(json["secret_base_id"])); this->readCustomValues(json); return true; } void SecretBaseEvent::setDefaultValues(Project *project) { this->setBaseID(project->secretBaseIds.value(0, "0")); this->setElevation(0); } const QSet<QString> expectedSecretBaseFields = { "type", "elevation", "secret_base_id", }; QSet<QString> SecretBaseEvent::getExpectedFields() { QSet<QString> expectedFields = QSet<QString>(); expectedFields = expectedSecretBaseFields; expectedFields << "x" << "y"; return expectedFields; } EventFrame *HealLocationEvent::createEventFrame() { if (!this->eventFrame) { this->eventFrame = new HealLocationFrame(this); this->eventFrame->setup(); } return this->eventFrame; } OrderedJson::object HealLocationEvent::buildEventJson(Project *) { return OrderedJson::object(); } void HealLocationEvent::setDefaultValues(Project *) { this->setElevation(projectConfig.defaultElevation); if (!this->getMap()) return; bool respawnEnabled = projectConfig.healLocationRespawnDataEnabled; const QString mapConstant = Map::mapConstantFromName(this->getMap()->name, false); const QString prefix = projectConfig.getIdentifier(respawnEnabled ? ProjectIdentifier::define_spawn_prefix : ProjectIdentifier::define_heal_locations_prefix); this->setLocationName(mapConstant); this->setIdName(prefix + mapConstant); if (respawnEnabled) { this->setRespawnMap(this->getMap()->name); this->setRespawnNPC(1); } }