porymap/src/core/event.cpp

432 lines
13 KiB
C++
Raw Normal View History

2018-09-25 01:12:29 +01:00
#include "event.h"
#include "map.h"
#include "project.h"
#include "config.h"
2018-09-25 01:12:29 +01:00
QString EventType::Object = "event_object";
QString EventType::Warp = "event_warp";
QString EventType::Trigger = "event_trigger";
QString EventType::WeatherTrigger = "event_weather_trigger";
2018-09-25 01:12:29 +01:00
QString EventType::Sign = "event_sign";
QString EventType::HiddenItem = "event_hidden_item";
QString EventType::SecretBase = "event_secret_base";
QString EventType::HealLocation = "event_heal_location";
Event::Event()
{
this->spriteWidth = 16;
this->spriteHeight = 16;
this->usingSprite = false;
2018-09-25 01:12:29 +01:00
}
Event::Event(QJsonObject obj, QString type)
{
Event();
this->put("event_type", type);
this->readCustomValues(obj);
}
Event* Event::createNewEvent(QString event_type, QString map_name, Project *project)
2018-09-25 01:12:29 +01:00
{
Event *event = new Event;
if (event_type == EventType::Object) {
event = createNewObjectEvent(project);
2020-05-22 01:11:37 +01:00
event->setFrameFromMovement(event->get("movement_type"));
2018-09-25 01:12:29 +01:00
} else if (event_type == EventType::Warp) {
event = createNewWarpEvent(map_name);
} else if (event_type == EventType::HealLocation) {
event = createNewHealLocationEvent(map_name);
} else if (event_type == EventType::Trigger) {
event = createNewTriggerEvent(project);
} else if (event_type == EventType::WeatherTrigger) {
event = createNewWeatherTriggerEvent(project);
2018-09-25 01:12:29 +01:00
} else if (event_type == EventType::Sign) {
event = createNewSignEvent(project);
2018-09-25 01:12:29 +01:00
} else if (event_type == EventType::HiddenItem) {
event = createNewHiddenItemEvent(project);
2018-09-25 01:12:29 +01:00
} else if (event_type == EventType::SecretBase) {
event = createNewSecretBaseEvent(project);
2018-09-25 01:12:29 +01:00
}
event->setX(0);
event->setY(0);
return event;
}
Event* Event::createNewObjectEvent(Project *project)
2018-09-25 01:12:29 +01:00
{
Event *event = new Event;
event->put("event_group_type", "object_event_group");
event->put("event_type", EventType::Object);
event->put("sprite", project->getEventObjGfxConstants().keys().first());
event->put("movement_type", project->movementTypes->first());
if (projectConfig.getObjectEventInConnectionEnabled()) {
2020-03-11 20:45:52 +00:00
event->put("in_connection", false);
}
2018-09-25 01:12:29 +01:00
event->put("radius_x", 0);
event->put("radius_y", 0);
event->put("script_label", "NULL");
event->put("event_flag", "0");
event->put("replacement", "0");
event->put("trainer_type", project->trainerTypes->value(0, "0"));
2018-09-25 01:12:29 +01:00
event->put("sight_radius_tree_id", 0);
event->put("elevation", 3);
2018-09-25 01:12:29 +01:00
return event;
}
Event* Event::createNewWarpEvent(QString map_name)
{
Event *event = new Event;
event->put("event_group_type", "warp_event_group");
event->put("event_type", EventType::Warp);
event->put("destination_warp", 0);
event->put("destination_map_name", map_name);
event->put("elevation", 0);
2018-09-25 01:12:29 +01:00
return event;
}
Event* Event::createNewHealLocationEvent(QString map_name)
{
Event *event = new Event;
event->put("event_group_type", "heal_event_group");
event->put("event_type", EventType::HealLocation);
2020-03-20 17:41:40 +00:00
event->put("loc_name", QString(Map::mapConstantFromName(map_name)).remove(0,4));
event->put("id_name", map_name.replace(QRegularExpression("([a-z])([A-Z])"), "\\1_\\2").toUpper());
event->put("elevation", 3);
if (projectConfig.getHealLocationRespawnDataEnabled()) {
2020-03-20 17:41:40 +00:00
event->put("respawn_map", map_name);
event->put("respawn_npc", 1);
}
2018-09-25 01:12:29 +01:00
return event;
}
Event* Event::createNewTriggerEvent(Project *project)
2018-09-25 01:12:29 +01:00
{
Event *event = new Event;
event->put("event_group_type", "coord_event_group");
event->put("event_type", EventType::Trigger);
2018-09-25 01:12:29 +01:00
event->put("script_label", "NULL");
event->put("script_var", project->varNames->first());
2018-09-25 01:12:29 +01:00
event->put("script_var_value", "0");
event->put("elevation", 0);
2018-09-25 01:12:29 +01:00
return event;
}
Event* Event::createNewWeatherTriggerEvent(Project *project)
2018-09-25 01:12:29 +01:00
{
Event *event = new Event;
event->put("event_group_type", "coord_event_group");
event->put("event_type", EventType::WeatherTrigger);
event->put("weather", project->coordEventWeatherNames->first());
event->put("elevation", 0);
2018-09-25 01:12:29 +01:00
return event;
}
Event* Event::createNewSignEvent(Project *project)
2018-09-25 01:12:29 +01:00
{
Event *event = new Event;
event->put("event_group_type", "bg_event_group");
event->put("event_type", EventType::Sign);
event->put("player_facing_direction", project->bgEventFacingDirections->first());
2018-09-25 01:12:29 +01:00
event->put("script_label", "NULL");
event->put("elevation", 0);
2018-09-25 01:12:29 +01:00
return event;
}
Event* Event::createNewHiddenItemEvent(Project *project)
2018-09-25 01:12:29 +01:00
{
Event *event = new Event;
event->put("event_group_type", "bg_event_group");
event->put("event_type", EventType::HiddenItem);
event->put("item", project->itemNames->first());
event->put("flag", project->flagNames->first());
event->put("elevation", 3);
if (projectConfig.getHiddenItemQuantityEnabled()) {
event->put("quantity", 1);
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
event->put("underfoot", false);
}
2018-09-25 01:12:29 +01:00
return event;
}
Event* Event::createNewSecretBaseEvent(Project *project)
2018-09-25 01:12:29 +01:00
{
Event *event = new Event;
event->put("event_group_type", "bg_event_group");
event->put("event_type", EventType::SecretBase);
event->put("secret_base_id", project->secretBaseIds->first());
event->put("elevation", 0);
2018-09-25 01:12:29 +01:00
return event;
}
int Event::getPixelX()
{
return (this->x() * 16) - qMax(0, (this->spriteWidth - 16) / 2);
}
int Event::getPixelY()
{
return (this->y() * 16) - qMax(0, this->spriteHeight - 16);
}
static QMap<QString, bool> expectedObjectFields {
{"graphics_id", true},
{"x", true},
{"y", true},
{"elevation", true},
{"movement_type", true},
{"movement_range_x", true},
{"movement_range_y", true},
{"trainer_type", true},
{"trainer_sight_or_berry_tree_id", true},
{"script", true},
{"flag", true},
};
static QMap<QString, bool> expectedWarpFields {
{"x", true},
{"y", true},
{"elevation", true},
{"dest_map", true},
{"dest_warp_id", true},
};
static QMap<QString, bool> expectedTriggerFields {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"var", true},
{"var_value", true},
{"script", true},
};
static QMap<QString, bool> expectedWeatherTriggerFields {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"weather", true},
};
static QMap<QString, bool> expectedSignFields {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"player_facing_dir", true},
{"script", true},
};
static QMap<QString, bool> expectedHiddenItemFields {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"item", true},
{"flag", true},
};
static QMap<QString, bool> expectedSecretBaseFields {
{"type", true},
{"x", true},
{"y", true},
{"elevation", true},
{"secret_base_id", true},
};
QMap<QString, bool> Event::getExpectedFields()
{
QString type = this->get("event_type");
QMap<QString, bool> expectedFields = QMap<QString, bool>();
if (type == EventType::Object) {
expectedFields = expectedObjectFields;
if (projectConfig.getObjectEventInConnectionEnabled()) {
expectedFields.insert("in_connection", true);
2020-03-11 20:45:52 +00:00
}
} else if (type == EventType::Warp) {
expectedFields = expectedWarpFields;
} else if (type == EventType::Trigger) {
expectedFields = expectedTriggerFields;
} else if (type == EventType::WeatherTrigger) {
expectedFields = expectedWeatherTriggerFields;
} else if (type == EventType::Sign) {
expectedFields = expectedSignFields;
} else if (type == EventType::HiddenItem) {
expectedFields = expectedHiddenItemFields;
if (projectConfig.getHiddenItemQuantityEnabled()) {
expectedFields.insert("quantity", true);
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
expectedFields.insert("underfoot", true);
}
} else if (type == EventType::SecretBase) {
expectedFields = expectedSecretBaseFields;
}
return expectedFields;
};
void Event::readCustomValues(QJsonObject values)
{
this->customValues.clear();
QMap<QString, bool> expectedValues = this->getExpectedFields();
for (QString key : values.keys()) {
if (!expectedValues.contains(key)) {
this->customValues[key] = values[key].toString();
}
}
}
void Event::addCustomValuesTo(OrderedJson::object *obj)
{
for (QString key : this->customValues.keys()) {
if (!obj->contains(key)) {
(*obj)[key] = this->customValues[key];
}
}
}
OrderedJson::object Event::buildObjectEventJSON()
2019-02-01 17:43:25 +00:00
{
OrderedJson::object eventObj;
2019-02-01 17:43:25 +00:00
eventObj["graphics_id"] = this->get("sprite");
if (projectConfig.getObjectEventInConnectionEnabled()) {
2020-03-11 20:45:52 +00:00
eventObj["in_connection"] = this->getInt("in_connection") > 0 || this->get("in_connection") == "TRUE";
}
eventObj["x"] = this->getS16("x");
eventObj["y"] = this->getS16("y");
2019-02-01 17:43:25 +00:00
eventObj["elevation"] = this->getInt("elevation");
eventObj["movement_type"] = this->get("movement_type");
eventObj["movement_range_x"] = this->getInt("radius_x");
eventObj["movement_range_y"] = this->getInt("radius_y");
eventObj["trainer_type"] = this->get("trainer_type");
eventObj["trainer_sight_or_berry_tree_id"] = this->get("sight_radius_tree_id");
eventObj["script"] = this->get("script_label");
eventObj["flag"] = this->get("event_flag");
this->addCustomValuesTo(&eventObj);
2019-02-01 17:43:25 +00:00
return eventObj;
}
OrderedJson::object Event::buildWarpEventJSON(QMap<QString, QString> *mapNamesToMapConstants)
2019-02-01 17:43:25 +00:00
{
OrderedJson::object warpObj;
2019-02-01 17:43:25 +00:00
warpObj["x"] = this->getU16("x");
warpObj["y"] = this->getU16("y");
warpObj["elevation"] = this->getInt("elevation");
warpObj["dest_map"] = mapNamesToMapConstants->value(this->get("destination_map_name"));
warpObj["dest_warp_id"] = this->getInt("destination_warp");
this->addCustomValuesTo(&warpObj);
2019-02-01 17:43:25 +00:00
return warpObj;
}
OrderedJson::object Event::buildTriggerEventJSON()
2019-02-01 17:43:25 +00:00
{
OrderedJson::object triggerObj;
2019-02-01 17:43:25 +00:00
triggerObj["type"] = "trigger";
triggerObj["x"] = this->getU16("x");
triggerObj["y"] = this->getU16("y");
triggerObj["elevation"] = this->getInt("elevation");
triggerObj["var"] = this->get("script_var");
triggerObj["var_value"] = this->get("script_var_value");
triggerObj["script"] = this->get("script_label");
this->addCustomValuesTo(&triggerObj);
2019-02-01 17:43:25 +00:00
return triggerObj;
}
OrderedJson::object Event::buildWeatherTriggerEventJSON()
2019-02-01 17:43:25 +00:00
{
OrderedJson::object weatherObj;
2019-02-01 17:43:25 +00:00
weatherObj["type"] = "weather";
weatherObj["x"] = this->getU16("x");
weatherObj["y"] = this->getU16("y");
weatherObj["elevation"] = this->getInt("elevation");
weatherObj["weather"] = this->get("weather");
this->addCustomValuesTo(&weatherObj);
2019-02-01 17:43:25 +00:00
return weatherObj;
}
OrderedJson::object Event::buildSignEventJSON()
2019-02-01 17:43:25 +00:00
{
OrderedJson::object signObj;
2019-02-01 17:43:25 +00:00
signObj["type"] = "sign";
signObj["x"] = this->getU16("x");
signObj["y"] = this->getU16("y");
signObj["elevation"] = this->getInt("elevation");
signObj["player_facing_dir"] = this->get("player_facing_direction");
signObj["script"] = this->get("script_label");
this->addCustomValuesTo(&signObj);
2019-02-01 17:43:25 +00:00
return signObj;
}
OrderedJson::object Event::buildHiddenItemEventJSON()
2019-02-01 17:43:25 +00:00
{
OrderedJson::object hiddenItemObj;
2019-02-01 17:43:25 +00:00
hiddenItemObj["type"] = "hidden_item";
hiddenItemObj["x"] = this->getU16("x");
hiddenItemObj["y"] = this->getU16("y");
hiddenItemObj["elevation"] = this->getInt("elevation");
hiddenItemObj["item"] = this->get("item");
hiddenItemObj["flag"] = this->get("flag");
if (projectConfig.getHiddenItemQuantityEnabled()) {
hiddenItemObj["quantity"] = this->getInt("quantity");
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
hiddenItemObj["underfoot"] = this->getInt("underfoot") > 0 || this->get("underfoot") == "TRUE";
}
this->addCustomValuesTo(&hiddenItemObj);
2019-02-01 17:43:25 +00:00
return hiddenItemObj;
}
OrderedJson::object Event::buildSecretBaseEventJSON()
2019-02-01 17:43:25 +00:00
{
OrderedJson::object secretBaseObj;
2019-02-01 17:43:25 +00:00
secretBaseObj["type"] = "secret_base";
secretBaseObj["x"] = this->getU16("x");
secretBaseObj["y"] = this->getU16("y");
secretBaseObj["elevation"] = this->getInt("elevation");
secretBaseObj["secret_base_id"] = this->get("secret_base_id");
this->addCustomValuesTo(&secretBaseObj);
2019-02-01 17:43:25 +00:00
return secretBaseObj;
2018-09-25 01:12:29 +01:00
}
2019-04-03 00:51:33 +01:00
void Event::setPixmapFromSpritesheet(QImage spritesheet, int spriteWidth, int spriteHeight, int frame, bool hFlip)
2018-09-25 01:12:29 +01:00
{
// Set first palette color fully transparent.
2019-04-03 00:51:33 +01:00
QImage img = spritesheet.copy(frame * spriteWidth % spritesheet.width(), 0, spriteWidth, spriteHeight);
if (hFlip) {
img = img.transformed(QTransform().scale(-1, 1));
}
2018-09-25 01:12:29 +01:00
img.setColor(0, qRgba(0, 0, 0, 0));
pixmap = QPixmap::fromImage(img);
this->spriteWidth = spriteWidth;
this->spriteHeight = spriteHeight;
this->usingSprite = true;
2018-09-25 01:12:29 +01:00
}
2019-04-03 00:51:33 +01:00
void Event::setFrameFromMovement(QString facingDir) {
// defaults
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;
}
}