change Event class design in favor of polymorphism

This commit is contained in:
garak 2022-07-19 17:56:12 -04:00
parent dd66f967f8
commit 582405d68b
34 changed files with 3675 additions and 1661 deletions

View file

@ -813,8 +813,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>428</width> <width>423</width>
<height>77</height> <height>74</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_7"> <layout class="QHBoxLayout" name="horizontalLayout_7">
@ -1001,10 +1001,10 @@
</property> </property>
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>8</x>
<y>0</y> <y>0</y>
<width>411</width> <width>411</width>
<height>449</height> <height>413</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1155,7 +1155,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>428</width> <width>428</width>
<height>704</height> <height>696</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_7"> <layout class="QGridLayout" name="gridLayout_7">
@ -1404,16 +1404,6 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>3</number> <number>3</number>
</property> </property>
<item row="1" column="0">
<widget class="QLabel" name="label_NoEvents">
<property name="text">
<string>There are no events on the current map.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QFrame" name="frame_4"> <widget class="QFrame" name="frame_4">
<property name="maximumSize"> <property name="maximumSize">
@ -1522,6 +1512,16 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="label_NoEvents">
<property name="text">
<string>There are no events on the current map.</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QTabWidget" name="tabWidget_EventType"> <widget class="QTabWidget" name="tabWidget_EventType">
<property name="currentIndex"> <property name="currentIndex">
@ -1544,8 +1544,57 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<layout class="QHBoxLayout" name="hbox_Objects">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSpinBox" name="spinner_ObjectID">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_16_5">
<property name="text">
<string>object id</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QScrollArea" name="scrollArea_Objects"> <widget class="QScrollArea" name="scrollArea_Objects">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -1557,8 +1606,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>98</width> <width>434</width>
<height>28</height> <height>581</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1589,8 +1638,57 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<layout class="QHBoxLayout" name="hbox_Warps">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSpinBox" name="spinner_WarpID">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_16_1">
<property name="text">
<string>warp id</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QScrollArea" name="scrollArea_Warps"> <widget class="QScrollArea" name="scrollArea_Warps">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -1602,8 +1700,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>98</width> <width>434</width>
<height>28</height> <height>581</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1634,8 +1732,57 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<layout class="QHBoxLayout" name="hbox_Triggers">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSpinBox" name="spinner_TriggerID">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_16_2">
<property name="text">
<string>coord id</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QScrollArea" name="scrollArea_Triggers"> <widget class="QScrollArea" name="scrollArea_Triggers">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -1647,8 +1794,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>98</width> <width>434</width>
<height>28</height> <height>581</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1679,8 +1826,63 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<layout class="QHBoxLayout" name="hbox_BGs">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSpinBox" name="spinner_BgID">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_16_3">
<property name="text">
<string>bg id</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QScrollArea" name="scrollArea_BGs"> <widget class="QScrollArea" name="scrollArea_BGs">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -1692,8 +1894,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>98</width> <width>434</width>
<height>28</height> <height>581</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1724,8 +1926,57 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<layout class="QHBoxLayout" name="hbox_Heals">
<property name="leftMargin">
<number>12</number>
</property>
<property name="topMargin">
<number>12</number>
</property>
<property name="rightMargin">
<number>12</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSpinBox" name="spinner_HealID">
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_16_4">
<property name="text">
<string>heal id</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item> <item>
<widget class="QScrollArea" name="scrollArea_Healspots"> <widget class="QScrollArea" name="scrollArea_Healspots">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -1737,8 +1988,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>98</width> <width>434</width>
<height>28</height> <height>581</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1777,6 +2028,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable"> <property name="widgetResizable">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -1788,8 +2042,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>98</width> <width>434</width>
<height>28</height> <height>625</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -2679,7 +2933,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1287</width> <width>1287</width>
<height>21</height> <height>22</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">

View file

@ -1,123 +0,0 @@
#pragma once
#ifndef EVENT_H
#define EVENT_H
#include <QString>
#include <QPixmap>
#include <QMap>
#include "orderedjson.h"
using OrderedJson = poryjson::Json;
class EventType
{
public:
static QString Object;
static QString CloneObject;
static QString Warp;
static QString Trigger;
static QString WeatherTrigger;
static QString Sign;
static QString HiddenItem;
static QString SecretBase;
static QString HealLocation;
};
class EventGroup
{
public:
static QString Object;
static QString Warp;
static QString Coord;
static QString Bg;
static QString Heal;
};
class DraggablePixmapItem;
class Project;
class Event
{
public:
Event();
Event(const Event&);
Event(QJsonObject, QString);
public:
int x() const {
return getInt("x");
}
int y() const {
return getInt("y");
}
int elevation() {
return getInt("elevation");
}
void setX(int x) {
put("x", x);
}
void setY(int y) {
put("y", y);
}
QString get(const QString &key) const {
return values.value(key);
}
int getInt(const QString &key) const {
return values.value(key).toInt(nullptr, 0);
}
uint16_t getU16(const QString &key) const {
return values.value(key).toUShort(nullptr, 0);
}
int16_t getS16(const QString &key) const {
return values.value(key).toShort(nullptr, 0);
}
void put(QString key, int value) {
put(key, QString("%1").arg(value));
}
void put(QString key, QString value) {
values.insert(key, value);
}
static Event* createNewEvent(QString, QString, Project*);
static Event* createNewObjectEvent(Project*);
static Event* createNewCloneObjectEvent(Project*, QString);
static Event* createNewWarpEvent(QString);
static Event* createNewHealLocationEvent(QString);
static Event* createNewTriggerEvent(Project*);
static Event* createNewWeatherTriggerEvent(Project*);
static Event* createNewSignEvent(Project*);
static Event* createNewHiddenItemEvent(Project*);
static Event* createNewSecretBaseEvent(Project*);
static bool isValidType(QString event_type);
static QString typeToGroup(QString event_type);
static int getIndexOffset(QString group_type);
OrderedJson::object buildObjectEventJSON();
OrderedJson::object buildCloneObjectEventJSON(const QMap<QString, QString> &);
OrderedJson::object buildWarpEventJSON(const QMap<QString, QString> &);
OrderedJson::object buildTriggerEventJSON();
OrderedJson::object buildWeatherTriggerEventJSON();
OrderedJson::object buildSignEventJSON();
OrderedJson::object buildHiddenItemEventJSON();
OrderedJson::object buildSecretBaseEventJSON();
void setPixmapFromSpritesheet(QImage, int, int, bool);
int getPixelX();
int getPixelY();
QSet<QString> getExpectedFields();
void readCustomValues(QJsonObject values);
void addCustomValuesTo(OrderedJson::object *obj);
void setFrameFromMovement(QString);
QMap<QString, QString> values;
QMap<QString, QString> customValues;
QPixmap pixmap;
int spriteWidth;
int spriteHeight;
int frame = 0;
bool hFlip = false;
bool usingSprite;
DraggablePixmapItem *pixmapItem = nullptr;
void setPixmapItem(DraggablePixmapItem *item) { pixmapItem = item; }
};
#endif // EVENT_H

669
include/core/events.h Normal file
View file

@ -0,0 +1,669 @@
#pragma once
#ifndef EVENTS_H
#define EVENTS_H
#include <QString>
#include <QMap>
#include <QSet>
#include <QPixmap>
#include <QJsonObject>
#include "orderedjson.h"
using OrderedJson = poryjson::Json;
class Project;
class Map;
class EventFrame;
class ObjectFrame;
class CloneObjectFrame;
class WarpFrame;
class DraggablePixmapItem;
class Event;
class ObjectEvent;
class CloneObjectEvent;
class WarpEvent;
class CoordEvent;
class TriggerEvent;
class WeatherTriggerEvent;
class BgEvent;
class SignEvent;
class HiddenItemEvent;
class SecretBaseEvent;
class HealLocationEvent;
class EventVisitor {
public:
virtual void nothing() { }
virtual void visitObject(ObjectEvent *) = 0;
virtual void visitTrigger(TriggerEvent *) = 0;
virtual void visitSign(SignEvent *) = 0;
};
///
/// Event base class -- purely virtual
///
class Event {
public:
virtual ~Event();
// disable copy constructor
Event(const Event &other) = delete;
// disable assignment operator
Event& operator=(const Event &other) = delete;
protected:
Event() {
this->spriteWidth = 16;
this->spriteHeight = 16;
this->usingSprite = false;
}
// public enums & static methods
public:
enum class Type {
Object, CloneObject,
Warp,
Trigger, WeatherTrigger,
Sign, HiddenItem, SecretBase,
HealLocation,
Generic,
None,
};
enum class Group {
Object,
Warp,
Coord,
Bg,
Heal,
None,
};
// all event groups excepts warps have IDs that start at 1
static int getIndexOffset(Event::Group group) {
return (group == Event::Group::Warp) ? 0 : 1;
}
static Event::Group typeToGroup(Event::Type type) {
switch (type) {
case Event::Type::Object:
case Event::Type::CloneObject:
return Event::Group::Object;
case Event::Type::Warp:
return Event::Group::Warp;
case Event::Type::Trigger:
case Event::Type::WeatherTrigger:
return Event::Group::Coord;
case Event::Type::Sign:
case Event::Type::HiddenItem:
case Event::Type::SecretBase:
return Event::Group::Bg;
case Event::Type::HealLocation:
return Event::Group::Heal;
default:
return Event::Group::None;
}
}
// standard public methods
public:
virtual Event *duplicate() = 0;
void setMap(Map *newMap) { this->map = newMap; }
Map *getMap() const { return this->map; }
virtual void accept(EventVisitor *) { }
void setX(int newX) { this->x = newX; }
void setY(int newY) { this->y = newY; }
void setZ(int newZ) { this->elevation = newZ; }
void setElevation(int newElevation) { this->elevation = newElevation; }
int getX() const { return this->x; }
int getY() const { return this->y; }
int getZ() const { return this->elevation; }
int getElevation() const { return this->elevation; }
int getPixelX() const { return (this->x * 16) - qMax(0, (this->spriteWidth - 16) / 2); }
int getPixelY() const { return (this->y * 16) - qMax(0, this->spriteHeight - 16); }
virtual EventFrame *getEventFrame();
virtual EventFrame *createEventFrame() = 0;
void destroyEventFrame();
Event::Group getEventGroup() const { return this->eventGroup; }
Event::Type getEventType() const { return this->eventType; }
virtual OrderedJson::object buildEventJson(Project *project) = 0;
virtual bool loadFromJson(QJsonObject json, Project *project) = 0;
virtual void setDefaultValues(Project *project);
virtual QSet<QString> getExpectedFields() = 0;
void readCustomValues(QJsonObject values);
void addCustomValuesTo(OrderedJson::object *obj);
QMap<QString, QString> getCustomValues() { return this->customValues; }
void setCustomValues(QMap<QString, QString> newCustomValues) { this->customValues = newCustomValues; }
virtual void loadPixmap(Project *project) = 0;
void setPixmap(QPixmap newPixmap) { this->pixmap = newPixmap; }
QPixmap getPixmap() { return this->pixmap; }
void setPixmapItem(DraggablePixmapItem *item) { this->pixmapItem = item; }
DraggablePixmapItem *getPixmapItem() { return this->pixmapItem; }
void setUsingSprite(bool newUsingSprite) { this->usingSprite = newUsingSprite; }
bool getUsingSprite() const { return this->usingSprite; }
void setSpriteWidth(int newSpriteWidth) { this->spriteWidth = newSpriteWidth; }
int getspriteWidth() const { return this->spriteWidth; }
void setSpriteHeight(int newSpriteHeight) { this->spriteHeight = newSpriteHeight; }
int getspriteHeight() const { return this->spriteHeight; }
int getEventIndex();
static QString eventTypeToString(Event::Type type);
static Event::Type eventTypeFromString(QString type);
// pure virtual public methods
public:
// // update spinbox values, etc, combo indices
// virtual void updateFrame(); // setFrameFromMovement, (aka redisplay?)
// virtual void disableFrame(); // setParrent(nullptr), disconnectSignals()
// protected attributes
protected:
Map *map = nullptr;
Type eventType = Event::Type::None;
Group eventGroup = Event::Group::None;
// could be private?
int x = 0;
int y = 0;
int elevation = 0;
int spriteWidth = 16;
int spriteHeight = 16;
bool usingSprite = false;
QMap<QString, QString> customValues;
QPixmap pixmap;
DraggablePixmapItem *pixmapItem = nullptr;
EventFrame *eventFrame = nullptr;
};
///
/// Object Event
///
class ObjectEvent : public Event {
//
// in each derived class constructor, need to createEventFrame, since not
// doing that in base class. make sure to upcall though
public:
ObjectEvent() : Event() {
this->eventGroup = Event::Group::Object;
this->eventType = Event::Type::Object;
}
virtual ~ObjectEvent() {}
virtual Event *duplicate() override;
virtual void accept(EventVisitor *visitor) override { visitor->visitObject(this); }
//virtual EventFrame *getEventFrame() override;
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
virtual void loadPixmap(Project *project) override;
void setGfx(QString newGfx) { this->gfx = newGfx; }
QString getGfx() { return this->gfx; }
void setMovement(QString newMovement) { this->movement = newMovement; }
QString getMovement() { return this->movement; }
void setRadiusX(int newRadiusX) { this->radiusX = newRadiusX; }
int getRadiusX() { return this->radiusX; }
void setRadiusY(int newRadiusY) { this->radiusY = newRadiusY; }
int getRadiusY() { return this->radiusY; }
void setTrainerType(QString newTrainerType) { this->trainerType = newTrainerType; }
QString getTrainerType() { return this->trainerType; }
void setSightRadiusBerryTreeID(QString newValue) { this->sightRadiusBerryTreeID = newValue; }
QString getSightRadiusBerryTreeID() { return this->sightRadiusBerryTreeID; }
void setScript(QString newScript) { this->script = newScript; }
QString getScript() { return this->script; }
void setFlag(QString newFlag) { this->flag = newFlag; }
QString getFlag() { return this->flag; }
public:
void setFrameFromMovement(QString movement);
void setPixmapFromSpritesheet(QImage, int, int, bool);
protected:
QString gfx;
QString movement;
int radiusX = 0;
int radiusY = 0;
QString trainerType;
QString sightRadiusBerryTreeID; // TODO: int?
QString script;
QString flag;
int frame = 0;
bool hFlip = false;
bool vFlip = false;
};
///
/// Clone Object Event
///
class CloneObjectEvent : public ObjectEvent {
public:
CloneObjectEvent() : ObjectEvent() {
this->eventGroup = Event::Group::Object;
this->eventType = Event::Type::CloneObject;
}
virtual ~CloneObjectEvent() {}
virtual Event *duplicate() override;
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
virtual void loadPixmap(Project *project) override;
void setTargetMap(QString newTargetMap) { this->targetMap = newTargetMap; }
QString getTargetMap() { return this->targetMap; }
void setTargetID(int newTargetID) { this->targetID = newTargetID; }
int getTargetID() { return this->targetID; }
private:
QString targetMap;
int targetID = 0;
};
///
/// Warp Event
///
class WarpEvent : public Event {
public:
WarpEvent() : Event() {
this->eventGroup = Event::Group::Warp;
this->eventType = Event::Type::Warp;
}
virtual ~WarpEvent() {}
virtual Event *duplicate() override;
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
virtual void loadPixmap(Project *) override;
void setDestinationMap(QString newDestinationMap) { this->destinationMap = newDestinationMap; }
QString getDestinationMap() { return this->destinationMap; }
void setDestinationWarpID(int newDestinationWarpID) { this->destinationWarpID = newDestinationWarpID; }
int getDestinationWarpID() { return this->destinationWarpID; }
private:
QString destinationMap;
int destinationWarpID = 0;
};
///
/// Coord Event
///
class CoordEvent : public Event {
public:
CoordEvent() : Event() {}
virtual ~CoordEvent() {}
virtual Event *duplicate() override = 0;
virtual EventFrame *createEventFrame() override = 0;
virtual OrderedJson::object buildEventJson(Project *project) override = 0;
virtual bool loadFromJson(QJsonObject json, Project *project) override = 0;
virtual void setDefaultValues(Project *project) override = 0;
virtual QSet<QString> getExpectedFields() override = 0;
virtual void loadPixmap(Project *) override;
};
///
/// Trigger Event
///
class TriggerEvent : public CoordEvent {
public:
TriggerEvent() : CoordEvent() {
this->eventGroup = Event::Group::Coord;
this->eventType = Event::Type::Trigger;
}
virtual ~TriggerEvent() {}
virtual Event *duplicate() override;
virtual void accept(EventVisitor *visitor) override { visitor->visitTrigger(this); }
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
void setScriptVar(QString newScriptVar) { this->scriptVar = newScriptVar; }
QString getScriptVar() { return this->scriptVar; }
void setScriptVarValue(QString newScriptVarValue) { this->scriptVarValue = newScriptVarValue; }
QString getScriptVarValue() { return this->scriptVarValue; }
void setScriptLabel(QString newScriptLabel) { this->scriptLabel = newScriptLabel; }
QString getScriptLabel() { return this->scriptLabel; }
private:
QString scriptVar;
QString scriptVarValue;
QString scriptLabel;
};
///
/// Weather Trigger Event
///
class WeatherTriggerEvent : public CoordEvent {
public:
WeatherTriggerEvent() : CoordEvent() {
this->eventGroup = Event::Group::Coord;
this->eventType = Event::Type::WeatherTrigger;
}
virtual ~WeatherTriggerEvent() {}
virtual Event *duplicate() override;
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
void setWeather(QString newWeather) { this->weather = newWeather; }
QString getWeather() { return this->weather; }
private:
QString weather;
};
///
/// BG Event
///
class BGEvent : public Event {
public:
BGEvent() : Event() {
this->eventGroup = Event::Group::Bg;
}
virtual ~BGEvent() {}
virtual Event *duplicate() override = 0;
virtual EventFrame *createEventFrame() override = 0;
virtual OrderedJson::object buildEventJson(Project *project) override = 0;
virtual bool loadFromJson(QJsonObject json, Project *project) override = 0;
virtual void setDefaultValues(Project *project) override = 0;
virtual QSet<QString> getExpectedFields() override = 0;
virtual void loadPixmap(Project *project) override;
};
///
/// Sign Event
///
class SignEvent : public BGEvent {
public:
SignEvent() : BGEvent() {
this->eventType = Event::Type::Sign;
}
virtual ~SignEvent() {}
virtual Event *duplicate() override;
virtual void accept(EventVisitor *visitor) override { visitor->visitSign(this); }
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
void setFacingDirection(QString newFacingDirection) { this->facingDirection = newFacingDirection; }
QString getFacingDirection() { return this->facingDirection; }
void setScriptLabel(QString newScriptLabel) { this->scriptLabel = newScriptLabel; }
QString getScriptLabel() { return this->scriptLabel; }
private:
QString facingDirection;
QString scriptLabel;
};
///
/// Hidden Item Event
///
class HiddenItemEvent : public BGEvent {
public:
HiddenItemEvent() : BGEvent() {
this->eventType = Event::Type::HiddenItem;
}
virtual ~HiddenItemEvent() {}
virtual Event *duplicate() override;
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
void setItem(QString newItem) { this->item = newItem; }
QString getItem() { return this->item; }
void setFlag(QString newFlag) { this->flag = newFlag; }
QString getFlag() { return this->flag; }
void setQuantity(int newQuantity) { this->quantity = newQuantity; }
int getQuantity() { return this->quantity; }
void setUnderfoot(bool newUnderfoot) { this->underfoot = newUnderfoot; }
bool getUnderfoot() { return this->underfoot; }
private:
QString item;
QString flag;
// optional
int quantity = 0;
bool underfoot = false;
};
///
/// Secret Base Event
///
class SecretBaseEvent : public BGEvent {
public:
SecretBaseEvent() : BGEvent() {
this->eventType = Event::Type::SecretBase;
}
virtual ~SecretBaseEvent() {}
virtual Event *duplicate() override;
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject json, Project *project) override;
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override;
void setBaseID(QString newBaseID) { this->baseID = newBaseID; }
QString getBaseID() { return this->baseID; }
private:
QString baseID;
};
///
/// Heal Location Event
///
class HealLocationEvent : public Event {
public:
HealLocationEvent() : Event() {
this->eventGroup = Event::Group::Heal;
this->eventType = Event::Type::HealLocation;
}
virtual ~HealLocationEvent() {}
virtual Event *duplicate() override { return nullptr; }
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
virtual bool loadFromJson(QJsonObject, Project *) override { return false; }
virtual void setDefaultValues(Project *project) override;
virtual QSet<QString> getExpectedFields() override { return QSet<QString>(); }
virtual void loadPixmap(Project *project) override;
void setIndex(int newIndex) { this->index = newIndex; }
int getIndex() { return this->index; }
void setLocationName(QString newLocationName) { this->locationName = newLocationName; }
QString getLocationName() { return this->locationName; }
void setIdName(QString newIdName) { this->idName = newIdName; }
QString getIdName() { return this->idName; }
void setRespawnMap(QString newRespawnMap) { this->respawnMap = newRespawnMap; }
QString getRespawnMap() { return this->respawnMap; }
void setRespawnNPC(uint16_t newRespawnNPC) { this->respawnNPC = newRespawnNPC; }
uint16_t getRespawnNPC() { return this->respawnNPC; }
private:
int index = -1;
QString locationName;
QString idName;
QString respawnMap;
uint16_t respawnNPC = 0;
};
///
/// Keeps track of scripts
///
class ScriptTracker : public EventVisitor {
public:
virtual void visitObject(ObjectEvent *object) override { this->scripts << object->getScript(); };
virtual void visitTrigger(TriggerEvent *trigger) override { this->scripts << trigger->getScriptLabel(); };
virtual void visitSign(SignEvent *sign) override { this->scripts << sign->getScriptLabel(); };
QStringList getScripts() { return this->scripts; }
private:
QStringList scripts;
};
#endif // EVENTS_H

View file

@ -2,10 +2,11 @@
#ifndef HEALLOCATION_H #ifndef HEALLOCATION_H
#define HEALLOCATION_H #define HEALLOCATION_H
#include "event.h"
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
class Event;
class HealLocation { class HealLocation {
public: public:
@ -21,7 +22,7 @@ public:
uint16_t y; uint16_t y;
QString respawnMap; QString respawnMap;
uint16_t respawnNPC; uint16_t respawnNPC;
static HealLocation fromEvent(Event*); static HealLocation fromEvent(Event *);
}; };
#endif // HEALLOCATION_H #endif // HEALLOCATION_H

View file

@ -6,7 +6,7 @@
#include "mapconnection.h" #include "mapconnection.h"
#include "maplayout.h" #include "maplayout.h"
#include "tileset.h" #include "tileset.h"
#include "event.h" #include "events.h"
#include <QUndoStack> #include <QUndoStack>
#include <QPixmap> #include <QPixmap>
@ -63,7 +63,10 @@ public:
QPixmap collision_pixmap; QPixmap collision_pixmap;
QImage image; QImage image;
QPixmap pixmap; QPixmap pixmap;
QMap<QString, QList<Event*>> events;
QMap<Event::Group, QList<Event *>> events;
QList<Event *> ownedEvents; // for memory management
QList<MapConnection*> connections; QList<MapConnection*> connections;
QList<int> metatileLayerOrder; QList<int> metatileLayerOrder;
QList<float> metatileLayerOpacity; QList<float> metatileLayerOpacity;
@ -92,10 +95,10 @@ public:
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation); void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation); void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation); void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
QList<Event*> getAllEvents() const; QList<Event *> getAllEvents() const;
QStringList eventScriptLabels(const QString &event_group_type = QString()) const; QStringList eventScriptLabels(Event::Group group = Event::Group::None) const;
void removeEvent(Event*); void removeEvent(Event *);
void addEvent(Event*); void addEvent(Event *);
QPixmap renderConnection(MapConnection, MapLayout *); QPixmap renderConnection(MapConnection, MapLayout *);
QPixmap renderBorder(bool ignoreCache = false); QPixmap renderBorder(bool ignoreCache = false);
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false); void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
@ -105,9 +108,6 @@ public:
bool isWithinBounds(int x, int y); bool isWithinBounds(int x, int y);
bool isWithinBorderBounds(int x, int y); bool isWithinBorderBounds(int x, int y);
// for memory management
QVector<Event *> ownedEvents;
MapPixmapItem *mapItem = nullptr; MapPixmapItem *mapItem = nullptr;
void setMapItem(MapPixmapItem *item) { mapItem = item; } void setMapItem(MapPixmapItem *item) { mapItem = item; }

View file

@ -4,6 +4,7 @@
#include "heallocation.h" #include "heallocation.h"
#include "log.h" #include "log.h"
#include "orderedjson.h"
#include <QString> #include <QString>
#include <QList> #include <QList>

View file

@ -158,7 +158,7 @@ public:
void undo() override; void undo() override;
void redo() override; void redo() override;
bool mergeWith(const QUndoCommand *command) override { return false; } bool mergeWith(const QUndoCommand *) override { return false; }
int id() const override { return RMCommandId::ID_ClearEntries; } int id() const override { return RMCommandId::ID_ClearEntries; }
private: private:

View file

@ -96,7 +96,7 @@ public:
DraggablePixmapItem *addMapEvent(Event *event); DraggablePixmapItem *addMapEvent(Event *event);
void selectMapEvent(DraggablePixmapItem *object); void selectMapEvent(DraggablePixmapItem *object);
void selectMapEvent(DraggablePixmapItem *object, bool toggle); void selectMapEvent(DraggablePixmapItem *object, bool toggle);
DraggablePixmapItem *addNewEvent(QString event_type); DraggablePixmapItem *addNewEvent(Event::Type type);
void deleteEvent(Event *); void deleteEvent(Event *);
void updateSelectedEvents(); void updateSelectedEvents();
void duplicateSelectedEvents(); void duplicateSelectedEvents();
@ -131,8 +131,7 @@ public:
CurrentSelectedMetatilesPixmapItem *current_metatile_selection_item = nullptr; CurrentSelectedMetatilesPixmapItem *current_metatile_selection_item = nullptr;
MovementPermissionsSelector *movement_permissions_selector_item = nullptr; MovementPermissionsSelector *movement_permissions_selector_item = nullptr;
QList<DraggablePixmapItem*> *events = nullptr; QList<DraggablePixmapItem *> *selected_events = nullptr;
QList<DraggablePixmapItem*> *selected_events = nullptr;
QString map_edit_mode = "paint"; QString map_edit_mode = "paint";
QString obj_edit_mode = "select"; QString obj_edit_mode = "select";
@ -151,7 +150,7 @@ public:
void shouldReselectEvents(); void shouldReselectEvents();
void scaleMapView(int); void scaleMapView(int);
void openInTextEditor(const QString &path, int lineNum = 0) const; void openInTextEditor(const QString &path, int lineNum = 0) const;
bool eventLimitReached(QString event_type); bool eventLimitReached(Event::Type type);
public slots: public slots:
void openMapScripts() const; void openMapScripts() const;
@ -159,6 +158,7 @@ public slots:
void openProjectInTextEditor() const; void openProjectInTextEditor() const;
void maskNonVisibleConnectionTiles(); void maskNonVisibleConnectionTiles();
void onBorderMetatilesChanged(); void onBorderMetatilesChanged();
void selectedEventIndexChanged(int index, Event::Group eventGroup);
private: private:
void setConnectionItemsVisible(bool); void setConnectionItemsVisible(bool);
@ -210,7 +210,7 @@ signals:
void selectedObjectsChanged(); void selectedObjectsChanged();
void loadMapRequested(QString, QString); void loadMapRequested(QString, QString);
void wildMonDataChanged(); void wildMonDataChanged();
void warpEventDoubleClicked(QString, QString, QString); void warpEventDoubleClicked(QString, int, Event::Group);
void currentMetatilesSelectionChanged(); void currentMetatilesSelectionChanged();
void mapRulerStatusChanged(const QString &); void mapRulerStatusChanged(const QString &);
void editedMapData(); void editedMapData();

View file

@ -26,6 +26,8 @@
#include "shortcutseditor.h" #include "shortcutseditor.h"
#include "preferenceeditor.h" #include "preferenceeditor.h"
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
} }
@ -161,7 +163,7 @@ private slots:
void on_action_Reload_Project_triggered(); void on_action_Reload_Project_triggered();
void on_mapList_activated(const QModelIndex &index); void on_mapList_activated(const QModelIndex &index);
void on_action_Save_Project_triggered(); void on_action_Save_Project_triggered();
void openWarpMap(QString map_name, QString event_id, QString event_group); void openWarpMap(QString map_name, int event_id, Event::Group event_group);
void duplicate(); void duplicate();
void setClipboardData(poryjson::Json::object); void setClipboardData(poryjson::Json::object);
@ -216,7 +218,7 @@ private slots:
void on_toolButton_deleteObject_clicked(); void on_toolButton_deleteObject_clicked();
void addNewEvent(QString); void addNewEvent(Event::Type type);
void updateSelectedObjects(); void updateSelectedObjects();
void updateObjects(); void updateObjects();
@ -265,8 +267,6 @@ private slots:
void eventTabChanged(int index); void eventTabChanged(int index);
void selectedEventIndexChanged(int index);
void on_horizontalSlider_CollisionTransparency_valueChanged(int value); void on_horizontalSlider_CollisionTransparency_valueChanged(int value);
void on_toolButton_ExpandAll_clicked(); void on_toolButton_ExpandAll_clicked();
void on_toolButton_CollapseAll_clicked(); void on_toolButton_CollapseAll_clicked();
@ -374,7 +374,7 @@ private:
void setTheme(QString); void setTheme(QString);
bool openRecentProject(); bool openRecentProject();
void updateTilesetEditor(); void updateTilesetEditor();
QString getEventGroupFromTabWidget(QWidget *tab); Event::Group getEventGroupFromTabWidget(QWidget *tab);
void closeSupplementaryWindows(); void closeSupplementaryWindows();
void setWindowDisabled(bool); void setWindowDisabled(bool);

View file

@ -5,7 +5,6 @@
#include "map.h" #include "map.h"
#include "blockdata.h" #include "blockdata.h"
#include "heallocation.h" #include "heallocation.h"
#include "event.h"
#include "wildmoninfo.h" #include "wildmoninfo.h"
#include "parseutil.h" #include "parseutil.h"
#include "orderedjson.h" #include "orderedjson.h"
@ -83,6 +82,8 @@ public:
QMap<QString, qint64> modifiedFileTimestamps; QMap<QString, qint64> modifiedFileTimestamps;
bool usingAsmTilesets; bool usingAsmTilesets;
const QPixmap entitiesPixmap = QPixmap(":/images/Entities_16x16.png");
void set_root(QString); void set_root(QString);
void initSignals(); void initSignals();
@ -194,7 +195,7 @@ public:
bool readEventGraphics(); bool readEventGraphics();
QMap<QString, QMap<QString, QString>> readObjEventGfxInfo(); QMap<QString, QMap<QString, QString>> readObjEventGfxInfo();
void setEventPixmap(Event * event, bool forceLoad = false); void setEventPixmap(Event *event, bool forceLoad = false);
QString fixPalettePath(QString path); QString fixPalettePath(QString path);
QString fixGraphicPath(QString path); QString fixGraphicPath(QString path);
@ -204,6 +205,7 @@ public:
QString getMapScriptsFilePath(const QString &mapName) const; QString getMapScriptsFilePath(const QString &mapName) const;
QStringList getEventScriptsFilePaths() const; QStringList getEventScriptsFilePaths() const;
QCompleter *getEventScriptLabelCompleter(QStringList additionalScriptLabels); QCompleter *getEventScriptLabelCompleter(QStringList additionalScriptLabels);
QStringList getGlobalScriptLabels();
void saveMapHealEvents(Map *map); void saveMapHealEvents(Map *map);

View file

@ -1,7 +1,7 @@
#ifndef CUSTOMATTRIBUTESTABLE_H #ifndef CUSTOMATTRIBUTESTABLE_H
#define CUSTOMATTRIBUTESTABLE_H #define CUSTOMATTRIBUTESTABLE_H
#include "event.h" #include "events.h"
#include <QObject> #include <QObject>
#include <QFrame> #include <QFrame>
#include <QTableWidget> #include <QTableWidget>

View file

@ -8,7 +8,7 @@
#include <QtWidgets> #include <QtWidgets>
#include "event.h" #include "events.h"
class Editor; class Editor;
@ -17,10 +17,10 @@ class DraggablePixmapItem : public QObject, public QGraphicsPixmapItem {
public: public:
DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {} DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {}
DraggablePixmapItem(Event *event_, Editor *editor_) : QGraphicsPixmapItem(event_->pixmap) { DraggablePixmapItem(Event *event, Editor *editor) : QGraphicsPixmapItem(event->getPixmap()) {
event = event_; this->event = event;
event->setPixmapItem(this); event->setPixmapItem(this);
editor = editor_; this->editor = editor;
updatePosition(); updatePosition();
} }
@ -37,8 +37,6 @@ public:
void moveTo(const QPoint &pos); void moveTo(const QPoint &pos);
void emitPositionChanged(); void emitPositionChanged();
void updatePixmap(); void updatePixmap();
void bind(QComboBox *combo, QString key);
void bindToUserData(QComboBox *combo, QString key);
signals: signals:
void positionChanged(Event *event); void positionChanged(Event *event);
@ -49,25 +47,18 @@ signals:
void onPropertyChanged(QString key, QString value); void onPropertyChanged(QString key, QString value);
public slots: public slots:
void set_x(const QString &text) { void set_x(int x) {
event->put("x", text); event->setX(x);
updatePosition(); updatePosition();
} }
void set_y(const QString &text) { void set_y(int y) {
event->put("y", text); event->setY(y);
updatePosition(); updatePosition();
} }
void set_elevation(const QString &text) { void set_elevation(int z) {
event->put("elevation", text); event->setElevation(z);
updatePosition(); updatePosition();
} }
void set_sprite(const QString &text) {
event->put("sprite", text);
updatePixmap();
}
void set_script(const QString &text) {
event->put("script_label", text);
}
protected: protected:
void mousePressEvent(QGraphicsSceneMouseEvent*); void mousePressEvent(QGraphicsSceneMouseEvent*);

272
include/ui/eventframes.h Normal file
View file

@ -0,0 +1,272 @@
#pragma once
#ifndef EVENTRAMES_H
#define EVENTRAMES_H
#include <QtWidgets>
#include "noscrollspinbox.h"
#include "noscrollcombobox.h"
#include "events.h"
class Project;
class EventFrame : public QFrame {
Q_OBJECT
public:
EventFrame(Event *event, QWidget *parent = nullptr)
: QFrame(parent), event(event) { }
virtual void setup();
void initCustomAttributesTable();
virtual void connectSignals();
virtual void initialize();
virtual void populate(Project *project);
virtual void setActive(bool active);
public:
QLabel *label_id;
QVBoxLayout *layout_main;
QSpinBox *spinner_id;
NoScrollSpinBox *spinner_x;
NoScrollSpinBox *spinner_y;
NoScrollSpinBox *spinner_z;
QLabel *label_icon;
QFrame *frame_contents;
QVBoxLayout *layout_contents;
protected:
bool populated = false;
bool initialized = false;
private:
Event *event;
};
class ObjectFrame : public EventFrame {
Q_OBJECT
public:
ObjectFrame(ObjectEvent *object, QWidget *parent = nullptr)
: EventFrame(object, parent), object(object) {}
virtual ~ObjectFrame() {
delete this->scriptCompleter;
}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_sprite;
NoScrollComboBox *combo_movement;
NoScrollSpinBox *spinner_radius_x;
NoScrollSpinBox *spinner_radius_y;
NoScrollComboBox *combo_script;
NoScrollComboBox *combo_flag;
NoScrollComboBox *combo_trainer_type;
NoScrollComboBox *combo_radius_treeid;
QCheckBox *check_in_connection;
private:
ObjectEvent *object;
QCompleter *scriptCompleter = nullptr;
};
class CloneObjectFrame : public EventFrame {
Q_OBJECT
public:
CloneObjectFrame(CloneObjectEvent *clone, QWidget *parent = nullptr)
: EventFrame(clone, parent), clone(clone) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_sprite;
NoScrollSpinBox *spinner_target_id;
NoScrollComboBox *combo_target_map;
private:
CloneObjectEvent *clone;
};
class WarpFrame : public EventFrame {
Q_OBJECT
public:
WarpFrame(WarpEvent *warp, QWidget *parent = nullptr)
: EventFrame(warp, parent), warp(warp) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_dest_map;
NoScrollSpinBox *spinner_dest_warp;
private:
WarpEvent *warp;
};
class TriggerFrame : public EventFrame {
Q_OBJECT
public:
TriggerFrame(TriggerEvent *trigger, QWidget *parent = nullptr)
: EventFrame(trigger, parent), trigger(trigger) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_script;
NoScrollComboBox *combo_var;
NoScrollComboBox *combo_var_value;
private:
TriggerEvent *trigger;
QCompleter *scriptCompleter = nullptr;
};
class WeatherTriggerFrame : public EventFrame {
Q_OBJECT
public:
WeatherTriggerFrame(WeatherTriggerEvent *weatherTrigger, QWidget *parent = nullptr)
: EventFrame(weatherTrigger, parent), weatherTrigger(weatherTrigger) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_weather;
private:
WeatherTriggerEvent *weatherTrigger;
};
class SignFrame : public EventFrame {
Q_OBJECT
public:
SignFrame(SignEvent *sign, QWidget *parent = nullptr)
: EventFrame(sign, parent), sign(sign) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_facing_dir;
NoScrollComboBox *combo_script;
private:
SignEvent *sign;
QCompleter *scriptCompleter = nullptr;
};
class HiddenItemFrame : public EventFrame {
Q_OBJECT
public:
HiddenItemFrame(HiddenItemEvent *hiddenItem, QWidget *parent = nullptr)
: EventFrame(hiddenItem, parent), hiddenItem(hiddenItem) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_item;
NoScrollComboBox *combo_flag;
NoScrollSpinBox *spinner_quantity;
QCheckBox *check_itemfinder;
private:
HiddenItemEvent *hiddenItem;
};
class SecretBaseFrame : public EventFrame {
Q_OBJECT
public:
SecretBaseFrame(SecretBaseEvent *secretBase, QWidget *parent = nullptr)
: EventFrame(secretBase, parent), secretBase(secretBase) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_base_id;
private:
SecretBaseEvent *secretBase;
};
class HealLocationFrame : public EventFrame {
Q_OBJECT
public:
HealLocationFrame(HealLocationEvent *healLocation, QWidget *parent = nullptr)
: EventFrame(healLocation, parent), healLocation(healLocation) {}
virtual void setup() override;
virtual void initialize() override;
virtual void connectSignals() override;
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_respawn_map;
NoScrollSpinBox *spinner_respawn_npc;
private:
HealLocationEvent *healLocation;
};
#endif // EVENTRAMES_H

View file

@ -1,29 +0,0 @@
#ifndef EVENTPROPERTIESFRAME_H
#define EVENTPROPERTIESFRAME_H
#include "event.h"
#include <QFrame>
namespace Ui {
class EventPropertiesFrame;
}
class EventPropertiesFrame : public QFrame
{
Q_OBJECT
public:
explicit EventPropertiesFrame(Event *event, QWidget *parent = nullptr);
~EventPropertiesFrame();
void paintEvent(QPaintEvent*);
public:
Ui::EventPropertiesFrame *ui;
private:
Event *event;
bool firstShow = true;
};
#endif // EVENTPROPERTIESFRAME_H

View file

@ -1,7 +1,7 @@
#ifndef NEWEVENTTOOLBUTTON_H #ifndef NEWEVENTTOOLBUTTON_H
#define NEWEVENTTOOLBUTTON_H #define NEWEVENTTOOLBUTTON_H
#include "event.h" #include "events.h"
#include <QToolButton> #include <QToolButton>
class NewEventToolButton : public QToolButton class NewEventToolButton : public QToolButton
@ -9,7 +9,7 @@ class NewEventToolButton : public QToolButton
Q_OBJECT Q_OBJECT
public: public:
explicit NewEventToolButton(QWidget *parent = nullptr); explicit NewEventToolButton(QWidget *parent = nullptr);
QString getSelectedEventType(); Event::Type getSelectedEventType();
QAction *newObjectAction; QAction *newObjectAction;
QAction *newCloneObjectAction; QAction *newCloneObjectAction;
QAction *newWarpAction; QAction *newWarpAction;
@ -30,9 +30,9 @@ public slots:
void newHiddenItem(); void newHiddenItem();
void newSecretBase(); void newSecretBase();
signals: signals:
void newEventAdded(QString); void newEventAdded(Event::Type);
private: private:
QString selectedEventType; Event::Type selectedEventType;
void init(); void init();
}; };

View file

@ -17,7 +17,7 @@ QMAKE_TARGET_BUNDLE_PREFIX = com.pret
SOURCES += src/core/block.cpp \ SOURCES += src/core/block.cpp \
src/core/blockdata.cpp \ src/core/blockdata.cpp \
src/core/event.cpp \ src/core/events.cpp \
src/core/heallocation.cpp \ src/core/heallocation.cpp \
src/core/imageexport.cpp \ src/core/imageexport.cpp \
src/core/map.cpp \ src/core/map.cpp \
@ -53,7 +53,7 @@ SOURCES += src/core/block.cpp \
src/ui/regionmapentriespixmapitem.cpp \ src/ui/regionmapentriespixmapitem.cpp \
src/ui/cursortilerect.cpp \ src/ui/cursortilerect.cpp \
src/ui/customattributestable.cpp \ src/ui/customattributestable.cpp \
src/ui/eventpropertiesframe.cpp \ src/ui/eventframes.cpp \
src/ui/filterchildrenproxymodel.cpp \ src/ui/filterchildrenproxymodel.cpp \
src/ui/graphicsview.cpp \ src/ui/graphicsview.cpp \
src/ui/imageproviders.cpp \ src/ui/imageproviders.cpp \
@ -99,7 +99,7 @@ SOURCES += src/core/block.cpp \
HEADERS += include/core/block.h \ HEADERS += include/core/block.h \
include/core/blockdata.h \ include/core/blockdata.h \
include/core/event.h \ include/core/events.h \
include/core/heallocation.h \ include/core/heallocation.h \
include/core/history.h \ include/core/history.h \
include/core/imageexport.h \ include/core/imageexport.h \
@ -136,7 +136,7 @@ HEADERS += include/core/block.h \
include/ui/regionmapentriespixmapitem.h \ include/ui/regionmapentriespixmapitem.h \
include/ui/cursortilerect.h \ include/ui/cursortilerect.h \
include/ui/customattributestable.h \ include/ui/customattributestable.h \
include/ui/eventpropertiesframe.h \ include/ui/eventframes.h \
include/ui/filterchildrenproxymodel.h \ include/ui/filterchildrenproxymodel.h \
include/ui/graphicsview.h \ include/ui/graphicsview.h \
include/ui/imageproviders.h \ include/ui/imageproviders.h \
@ -185,7 +185,6 @@ HEADERS += include/core/block.h \
include/log.h include/log.h
FORMS += forms/mainwindow.ui \ FORMS += forms/mainwindow.ui \
forms/eventpropertiesframe.ui \
forms/prefabcreationdialog.ui \ forms/prefabcreationdialog.ui \
forms/prefabframe.ui \ forms/prefabframe.ui \
forms/tileseteditor.ui \ forms/tileseteditor.ui \
@ -209,5 +208,6 @@ INCLUDEPATH += include
INCLUDEPATH += include/core INCLUDEPATH += include/core
INCLUDEPATH += include/ui INCLUDEPATH += include/ui
INCLUDEPATH += include/lib INCLUDEPATH += include/lib
INCLUDEPATH += forms
include(src/vendor/QtGifImage/gifimage/qtgifimage.pri) include(src/vendor/QtGifImage/gifimage/qtgifimage.pri)

View file

@ -9,16 +9,16 @@
int getEventTypeMask(QList<Event *> events) { int getEventTypeMask(QList<Event *> events) {
int eventTypeMask = 0; int eventTypeMask = 0;
for (auto event : events) { for (auto event : events) {
QString groupType = event->get("event_group_type"); Event::Group groupType = event->getEventGroup();
if (groupType == EventGroup::Object) { if (groupType == Event::Group::Object) {
eventTypeMask |= IDMask_EventType_Object; eventTypeMask |= IDMask_EventType_Object;
} else if (groupType == EventGroup::Warp) { } else if (groupType == Event::Group::Warp) {
eventTypeMask |= IDMask_EventType_Warp; eventTypeMask |= IDMask_EventType_Warp;
} else if (groupType == EventGroup::Coord) { } else if (groupType == Event::Group::Coord) {
eventTypeMask |= IDMask_EventType_Trigger; eventTypeMask |= IDMask_EventType_Trigger;
} else if (groupType == EventGroup::Bg) { } else if (groupType == Event::Group::Bg) {
eventTypeMask |= IDMask_EventType_BG; eventTypeMask |= IDMask_EventType_BG;
} else if (groupType == EventGroup::Heal) { } else if (groupType == Event::Group::Heal) {
eventTypeMask |= IDMask_EventType_Heal; eventTypeMask |= IDMask_EventType_Heal;
} }
} }
@ -261,13 +261,13 @@ void EventMove::redo() {
QUndoCommand::redo(); QUndoCommand::redo();
for (Event *event : events) { for (Event *event : events) {
event->pixmapItem->move(deltaX, deltaY); event->getPixmapItem()->move(deltaX, deltaY);
} }
} }
void EventMove::undo() { void EventMove::undo() {
for (Event *event : events) { for (Event *event : events) {
event->pixmapItem->move(-deltaX, -deltaY); event->getPixmapItem()->move(-deltaX, -deltaY);
} }
QUndoCommand::undo(); QUndoCommand::undo();
@ -331,16 +331,16 @@ void EventCreate::redo() {
// select this event // select this event
editor->selected_events->clear(); editor->selected_events->clear();
editor->selectMapEvent(event->pixmapItem, false); editor->selectMapEvent(event->getPixmapItem(), false);
} }
void EventCreate::undo() { void EventCreate::undo() {
map->removeEvent(event); map->removeEvent(event);
if (editor->scene->items().contains(event->pixmapItem)) { if (editor->scene->items().contains(event->getPixmapItem())) {
editor->scene->removeItem(event->pixmapItem); editor->scene->removeItem(event->getPixmapItem());
} }
editor->selected_events->removeOne(event->pixmapItem); editor->selected_events->removeOne(event->getPixmapItem());
editor->shouldReselectEvents(); editor->shouldReselectEvents();
@ -377,15 +377,15 @@ void EventDelete::redo() {
for (Event *event : selectedEvents) { for (Event *event : selectedEvents) {
map->removeEvent(event); map->removeEvent(event);
if (editor->scene->items().contains(event->pixmapItem)) { if (editor->scene->items().contains(event->getPixmapItem())) {
editor->scene->removeItem(event->pixmapItem); editor->scene->removeItem(event->getPixmapItem());
} }
editor->selected_events->removeOne(event->pixmapItem); editor->selected_events->removeOne(event->getPixmapItem());
} }
editor->selected_events->clear(); editor->selected_events->clear();
if (nextSelectedEvent) if (nextSelectedEvent)
editor->selected_events->append(nextSelectedEvent->pixmapItem); editor->selected_events->append(nextSelectedEvent->getPixmapItem());
editor->shouldReselectEvents(); editor->shouldReselectEvents();
} }
@ -399,7 +399,7 @@ void EventDelete::undo() {
// select these events // select these events
editor->selected_events->clear(); editor->selected_events->clear();
for (Event *event : selectedEvents) { for (Event *event : selectedEvents) {
editor->selected_events->append(event->pixmapItem); editor->selected_events->append(event->getPixmapItem());
} }
editor->shouldReselectEvents(); editor->shouldReselectEvents();
@ -441,7 +441,7 @@ void EventDuplicate::redo() {
// select these events // select these events
editor->selected_events->clear(); editor->selected_events->clear();
for (Event *event : selectedEvents) { for (Event *event : selectedEvents) {
editor->selected_events->append(event->pixmapItem); editor->selected_events->append(event->getPixmapItem());
} }
editor->shouldReselectEvents(); editor->shouldReselectEvents();
} }
@ -450,10 +450,10 @@ void EventDuplicate::undo() {
for (Event *event : selectedEvents) { for (Event *event : selectedEvents) {
map->removeEvent(event); map->removeEvent(event);
if (editor->scene->items().contains(event->pixmapItem)) { if (editor->scene->items().contains(event->getPixmapItem())) {
editor->scene->removeItem(event->pixmapItem); editor->scene->removeItem(event->getPixmapItem());
} }
editor->selected_events->removeOne(event->pixmapItem); editor->selected_events->removeOne(event->getPixmapItem());
} }
editor->shouldReselectEvents(); editor->shouldReselectEvents();
@ -471,7 +471,7 @@ int EventDuplicate::id() const {
EventPaste::EventPaste(Editor *editor, Map *map, EventPaste::EventPaste(Editor *editor, Map *map,
QList<Event *> pastedEvents, QList<Event *> pastedEvents,
QUndoCommand *parent) : EventDuplicate(editor, map, pastedEvents) { QUndoCommand *parent) : EventDuplicate(editor, map, pastedEvents, parent) {
if (pastedEvents.size() > 1) { if (pastedEvents.size() > 1) {
setText("Paste Events"); setText("Paste Events");
} else { } else {

View file

@ -1,480 +0,0 @@
#include "event.h"
#include "map.h"
#include "project.h"
#include "config.h"
QString EventGroup::Object = "object_event_group";
QString EventGroup::Warp = "warp_event_group";
QString EventGroup::Heal = "heal_event_group";
QString EventGroup::Coord = "coord_event_group";
QString EventGroup::Bg = "bg_event_group";
QString EventType::Object = "event_object";
QString EventType::CloneObject = "event_clone_object";
QString EventType::Warp = "event_warp";
QString EventType::Trigger = "event_trigger";
QString EventType::WeatherTrigger = "event_weather_trigger";
QString EventType::Sign = "event_sign";
QString EventType::HiddenItem = "event_hidden_item";
QString EventType::SecretBase = "event_secret_base";
QString EventType::HealLocation = "event_healspot";
const QMap<QString, QString> EventTypeTable = {
{EventType::Object, EventGroup::Object},
{EventType::CloneObject, EventGroup::Object},
{EventType::Warp, EventGroup::Warp},
{EventType::Trigger, EventGroup::Coord},
{EventType::WeatherTrigger, EventGroup::Coord},
{EventType::Sign, EventGroup::Bg},
{EventType::HiddenItem, EventGroup::Bg},
{EventType::SecretBase, EventGroup::Bg},
{EventType::HealLocation, EventGroup::Heal},
};
Event::Event() :
spriteWidth(16),
spriteHeight(16),
usingSprite(false)
{ }
Event::Event(const Event& toCopy) :
values(toCopy.values),
customValues(toCopy.customValues),
pixmap(toCopy.pixmap),
spriteWidth(toCopy.spriteWidth),
spriteHeight(toCopy.spriteHeight),
frame(toCopy.frame),
hFlip(toCopy.hFlip),
usingSprite(toCopy.usingSprite)
{ }
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)
{
Event *event = nullptr;
if (event_type == EventType::Object) {
event = createNewObjectEvent(project);
event->setFrameFromMovement(event->get("movement_type"));
} else if (event_type == EventType::CloneObject) {
event = createNewCloneObjectEvent(project, map_name);
} 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);
} else if (event_type == EventType::Sign) {
event = createNewSignEvent(project);
} else if (event_type == EventType::HiddenItem) {
event = createNewHiddenItemEvent(project);
} else if (event_type == EventType::SecretBase) {
event = createNewSecretBaseEvent(project);
} else {
// should never be reached but just in case
event = new Event;
}
event->put("event_type", event_type);
event->put("event_group_type", typeToGroup(event_type));
event->setX(0);
event->setY(0);
return event;
}
Event* Event::createNewObjectEvent(Project *project)
{
Event *event = new Event;
event->put("sprite", project->gfxDefines.keys().first());
event->put("movement_type", project->movementTypes.first());
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"));
event->put("sight_radius_tree_id", 0);
event->put("elevation", 3);
return event;
}
Event* Event::createNewCloneObjectEvent(Project *project, QString map_name)
{
Event *event = new Event;
event->put("sprite", project->gfxDefines.keys().first());
event->put("target_local_id", 1);
event->put("target_map", map_name);
return event;
}
Event* Event::createNewWarpEvent(QString map_name)
{
Event *event = new Event;
event->put("destination_warp", 0);
event->put("destination_map_name", map_name);
event->put("elevation", 0);
return event;
}
Event* Event::createNewHealLocationEvent(QString map_name)
{
Event *event = new Event;
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()) {
event->put("respawn_map", map_name);
event->put("respawn_npc", 1);
}
return event;
}
Event* Event::createNewTriggerEvent(Project *project)
{
Event *event = new Event;
event->put("script_label", "NULL");
event->put("script_var", project->varNames.first());
event->put("script_var_value", "0");
event->put("elevation", 0);
return event;
}
Event* Event::createNewWeatherTriggerEvent(Project *project)
{
Event *event = new Event;
event->put("weather", project->coordEventWeatherNames.first());
event->put("elevation", 0);
return event;
}
Event* Event::createNewSignEvent(Project *project)
{
Event *event = new Event;
event->put("player_facing_direction", project->bgEventFacingDirections.first());
event->put("script_label", "NULL");
event->put("elevation", 0);
return event;
}
Event* Event::createNewHiddenItemEvent(Project *project)
{
Event *event = new Event;
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);
}
return event;
}
Event* Event::createNewSecretBaseEvent(Project *project)
{
Event *event = new Event;
event->put("secret_base_id", project->secretBaseIds.first());
event->put("elevation", 0);
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);
}
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",
};
const QSet<QString> expectedCloneObjectFields = {
"type",
"graphics_id",
"target_local_id",
"target_map",
};
const QSet<QString> expectedWarpFields = {
"elevation",
"dest_map",
"dest_warp_id",
};
const QSet<QString> expectedTriggerFields = {
"type",
"elevation",
"var",
"var_value",
"script",
};
const QSet<QString> expectedWeatherTriggerFields = {
"type",
"elevation",
"weather",
};
const QSet<QString> expectedSignFields = {
"type",
"elevation",
"player_facing_dir",
"script",
};
const QSet<QString> expectedHiddenItemFields = {
"type",
"elevation",
"item",
"flag",
};
const QSet<QString> expectedSecretBaseFields = {
"type",
"elevation",
"secret_base_id",
};
QSet<QString> Event::getExpectedFields()
{
QString type = this->get("event_type");
QSet<QString> expectedFields = QSet<QString>();
if (type == EventType::Object) {
expectedFields = expectedObjectFields;
if (projectConfig.getEventCloneObjectEnabled()) {
expectedFields.insert("type");
}
} else if (type == EventType::CloneObject) {
expectedFields = expectedCloneObjectFields;
} 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");
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
expectedFields.insert("underfoot");
}
} else if (type == EventType::SecretBase) {
expectedFields = expectedSecretBaseFields;
}
expectedFields << "x" << "y";
return expectedFields;
};
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].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()
{
OrderedJson::object objectObj;
if (projectConfig.getEventCloneObjectEnabled()) {
objectObj["type"] = "object";
}
objectObj["graphics_id"] = this->get("sprite");
objectObj["x"] = this->getS16("x");
objectObj["y"] = this->getS16("y");
objectObj["elevation"] = this->getInt("elevation");
objectObj["movement_type"] = this->get("movement_type");
objectObj["movement_range_x"] = this->getInt("radius_x");
objectObj["movement_range_y"] = this->getInt("radius_y");
objectObj["trainer_type"] = this->get("trainer_type");
objectObj["trainer_sight_or_berry_tree_id"] = this->get("sight_radius_tree_id");
objectObj["script"] = this->get("script_label");
objectObj["flag"] = this->get("event_flag");
this->addCustomValuesTo(&objectObj);
return objectObj;
}
OrderedJson::object Event::buildCloneObjectEventJSON(const QMap<QString, QString> &mapNamesToMapConstants)
{
OrderedJson::object cloneObj;
cloneObj["type"] = "clone";
cloneObj["graphics_id"] = this->get("sprite");
cloneObj["x"] = this->getS16("x");
cloneObj["y"] = this->getS16("y");
cloneObj["target_local_id"] = this->getInt("target_local_id");
cloneObj["target_map"] = mapNamesToMapConstants.value(this->get("target_map"));
this->addCustomValuesTo(&cloneObj);
return cloneObj;
}
OrderedJson::object Event::buildWarpEventJSON(const QMap<QString, QString> &mapNamesToMapConstants)
{
OrderedJson::object warpObj;
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);
return warpObj;
}
OrderedJson::object Event::buildTriggerEventJSON()
{
OrderedJson::object triggerObj;
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);
return triggerObj;
}
OrderedJson::object Event::buildWeatherTriggerEventJSON()
{
OrderedJson::object weatherObj;
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);
return weatherObj;
}
OrderedJson::object Event::buildSignEventJSON()
{
OrderedJson::object signObj;
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);
return signObj;
}
OrderedJson::object Event::buildHiddenItemEventJSON()
{
OrderedJson::object hiddenItemObj;
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);
return hiddenItemObj;
}
OrderedJson::object Event::buildSecretBaseEventJSON()
{
OrderedJson::object secretBaseObj;
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);
return secretBaseObj;
}
void Event::setPixmapFromSpritesheet(QImage spritesheet, int spriteWidth, int spriteHeight, bool inanimate)
{
int frame = inanimate ? 0 : this->frame;
QImage img = spritesheet.copy(frame * spriteWidth % spritesheet.width(), 0, spriteWidth, spriteHeight);
if (this->hFlip && !inanimate) {
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 = spriteWidth;
this->spriteHeight = spriteHeight;
this->usingSprite = true;
}
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;
}
}
// All event groups excepts warps have IDs that start at 1
int Event::getIndexOffset(QString group_type) {
return (group_type == EventGroup::Warp) ? 0 : 1;
}
bool Event::isValidType(QString event_type) {
return EventTypeTable.contains(event_type);
}
QString Event::typeToGroup(QString event_type) {
return EventTypeTable.value(event_type, QString());
}

875
src/core/events.cpp Normal file
View file

@ -0,0 +1,875 @@
#include "events.h"
#include "eventframes.h"
#include "project.h"
#include "config.h"
Event::~Event() {
if (this->eventFrame)
this->eventFrame->deleteLater();
}
EventFrame *Event::getEventFrame() {
if (!this->eventFrame) createEventFrame();
return this->eventFrame;
}
void Event::destroyEventFrame() {
if (eventFrame) delete eventFrame;
eventFrame = nullptr;
}
int Event::getEventIndex() {
return this->map->events.value(this->getEventGroup()).indexOf(this);
}
void Event::setDefaultValues(Project *) {
this->setX(0);
this->setY(0);
this->setElevation(3);
}
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].toString();
}
}
}
void Event::addCustomValuesTo(OrderedJson::object *obj) {
for (QString key : this->customValues.keys()) {
if (!obj->contains(key)) {
(*obj)[key] = this->customValues[key];
}
}
}
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;
}
}
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
return this->eventFrame;
}
OrderedJson::object ObjectEvent::buildEventJson(Project *) {
OrderedJson::object objectJson;
if (projectConfig.getEventCloneObjectEnabled()) {
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(json["x"].toInt());
this->setY(json["y"].toInt());
this->setElevation(json["elevation"].toInt());
this->setGfx(json["graphics_id"].toString());
this->setMovement(json["movement_type"].toString());
this->setRadiusX(json["movement_range_x"].toInt());
this->setRadiusY(json["movement_range_y"].toInt());
this->setTrainerType(json["trainer_type"].toString());
this->setSightRadiusBerryTreeID(json["trainer_sight_or_berry_tree_id"].toString());
this->setScript(json["script"].toString());
this->setFlag(json["flag"].toString());
this->readCustomValues(json);
return true;
}
void ObjectEvent::setDefaultValues(Project *project) {
this->setGfx(project->gfxDefines.keys().first());
this->setMovement(project->movementTypes.first());
this->setScript("NULL");
this->setTrainerType(project->trainerTypes.value(0, "0"));
this->setRadiusX(0);
this->setRadiusY(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.getEventCloneObjectEnabled()) {
expectedFields.insert("type");
}
expectedFields << "x" << "y";
return expectedFields;
}
void ObjectEvent::loadPixmap(Project *project) {
EventGraphics *eventGfx = project->eventGraphicsMap.value(gfx, nullptr);
if (!eventGfx || eventGfx->spritesheet.isNull()) {
// No sprite associated with this gfx constant.
// Use default sprite instead.
this->pixmap = project->entitiesPixmap.copy(0, 0, 16, 16);
} else {
this->setFrameFromMovement(project->facingDirections.value(this->movement));
this->setPixmapFromSpritesheet(eventGfx->spritesheet, eventGfx->spriteWidth, eventGfx->spriteHeight, eventGfx->inanimate);
}
}
void ObjectEvent::setPixmapFromSpritesheet(QImage spritesheet, int spriteWidth, int spriteHeight, bool inanimate)
{
int frame = inanimate ? 0 : this->frame;
QImage img = spritesheet.copy(frame * spriteWidth % spritesheet.width(), 0, spriteWidth, spriteHeight);
if (this->hFlip && !inanimate) {
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 = spriteWidth;
this->spriteHeight = 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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
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(json["x"].toInt());
this->setY(json["y"].toInt());
this->setGfx(json["graphics_id"].toString());
this->setTargetID(json["target_local_id"].toInt());
// Ensure the target map constant is valid before adding it to the events.
QString mapConstant = json["target_map"].toString();
if (project->mapConstantsToMapNames.contains(mapConstant)) {
this->setTargetMap(project->mapConstantsToMapNames.value(mapConstant));
} else if (mapConstant == NONE_MAP_CONSTANT) {
this->setTargetMap(NONE_MAP_NAME);
} else {
logError(QString("Destination map constant '%1' is invalid").arg(mapConstant));
return false;
}
this->readCustomValues(json);
return true;
}
void CloneObjectEvent::setDefaultValues(Project *project) {
this->setGfx(project->gfxDefines.keys().first());
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);
this->movement = project->movementTypes.first();
}
EventGraphics *eventGfx = project->eventGraphicsMap.value(gfx, nullptr);
if (!eventGfx || eventGfx->spritesheet.isNull()) {
// No sprite associated with this gfx constant.
// Use default sprite instead.
this->pixmap = project->entitiesPixmap.copy(0, 0, 16, 16);
} else {
this->setFrameFromMovement(project->facingDirections.value(this->movement));
this->setPixmapFromSpritesheet(eventGfx->spritesheet, eventGfx->spriteWidth, eventGfx->spriteHeight, eventGfx->inanimate);
}
}
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
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(json["x"].toInt());
this->setY(json["y"].toInt());
this->setElevation(json["elevation"].toInt());
this->setDestinationWarpID(json["dest_warp_id"].toInt());
// Ensure the warp destination map constant is valid before adding it to the warps.
QString mapConstant = json["dest_map"].toString();
if (project->mapConstantsToMapNames.contains(mapConstant)) {
this->setDestinationMap(project->mapConstantsToMapNames.value(mapConstant));
} else if (mapConstant == NONE_MAP_CONSTANT) {
this->setDestinationMap(NONE_MAP_NAME);
} else {
logError(QString("Destination map constant '%1' is invalid for warp").arg(mapConstant));
return false;
}
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::loadPixmap(Project *project) {
this->pixmap = project->entitiesPixmap.copy(16, 0, 16, 16);
}
void CoordEvent::loadPixmap(Project *project) {
this->pixmap = project->entitiesPixmap.copy(32, 0, 16, 16);
}
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
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(json["x"].toInt());
this->setY(json["y"].toInt());
this->setElevation(json["elevation"].toInt());
this->setScriptVar(json["var"].toString());
this->setScriptVarValue(json["var_value"].toString());
this->setScriptLabel(json["script"].toString());
this->readCustomValues(json);
return true;
}
void TriggerEvent::setDefaultValues(Project *project) {
this->setScriptLabel("NULL");
this->setScriptVar(project->varNames.first());
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
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(json["x"].toInt());
this->setY(json["y"].toInt());
this->setElevation(json["elevation"].toInt());
this->setWeather(json["weather"].toString());
this->readCustomValues(json);
return true;
}
void WeatherTriggerEvent::setDefaultValues(Project *project) {
this->setWeather(project->coordEventWeatherNames.first());
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;
}
void BGEvent::loadPixmap(Project *project) {
this->pixmap = project->entitiesPixmap.copy(48, 0, 16, 16);
}
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
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(json["x"].toInt());
this->setY(json["y"].toInt());
this->setElevation(json["elevation"].toInt());
this->setFacingDirection(json["player_facing_dir"].toString());
this->setScriptLabel(json["script"].toString());
this->readCustomValues(json);
return true;
}
void SignEvent::setDefaultValues(Project *project) {
this->setFacingDirection(project->bgEventFacingDirections.first());
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
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.getHiddenItemQuantityEnabled()) {
hiddenItemJson["quantity"] = this->getQuantity();
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
hiddenItemJson["underfoot"] = this->getUnderfoot();
}
this->addCustomValuesTo(&hiddenItemJson);
return hiddenItemJson;
}
bool HiddenItemEvent::loadFromJson(QJsonObject json, Project *) {
this->setX(json["x"].toInt());
this->setY(json["y"].toInt());
this->setElevation(json["elevation"].toInt());
this->setItem(json["item"].toString());
this->setFlag(json["flag"].toString());
if (projectConfig.getHiddenItemQuantityEnabled()) {
this->setQuantity(json["quantity"].toInt());
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
this->setUnderfoot(json["underfoot"].toBool());
}
this->readCustomValues(json);
return true;
}
void HiddenItemEvent::setDefaultValues(Project *project) {
this->setItem(project->itemNames.first());
this->setFlag(project->flagNames.first());
if (projectConfig.getHiddenItemQuantityEnabled()) {
this->setQuantity(1);
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
this->setUnderfoot(false);
}
}
const QSet<QString> expectedHiddenItemFields = {
"type",
"elevation",
"item",
"flag",
};
QSet<QString> HiddenItemEvent::getExpectedFields() {
QSet<QString> expectedFields = QSet<QString>();
expectedFields = expectedHiddenItemFields;
if (projectConfig.getHiddenItemQuantityEnabled()) {
expectedFields << "quantity";
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
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(json["x"].toInt());
this->setY(json["y"].toInt());
this->setElevation(json["elevation"].toInt());
this->setBaseID(json["secret_base_id"].toString());
this->readCustomValues(json);
return true;
}
void SecretBaseEvent::setDefaultValues(Project *project) {
this->setBaseID(project->secretBaseIds.first());
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();
QObject::connect(this->eventFrame, &QObject::destroyed, [this](){ this->eventFrame = nullptr; });
}
return this->eventFrame;
}
OrderedJson::object HealLocationEvent::buildEventJson(Project *) {
return OrderedJson::object();
}
void HealLocationEvent::setDefaultValues(Project *) {
if (this->getMap()) {
this->setLocationName(Map::mapConstantFromName(this->getMap()->name).remove(0,4));
this->setIdName(this->getMap()->name.replace(QRegularExpression("([a-z])([A-Z])"), "\\1_\\2").toUpper());
}
this->setElevation(3);
if (projectConfig.getHealLocationRespawnDataEnabled()) {
if (this->getMap()) this->setRespawnMap(this->getMap()->name);
this->setRespawnNPC(1);
}
}
void HealLocationEvent::loadPixmap(Project *project) {
this->pixmap = project->entitiesPixmap.copy(64, 0, 16, 16);
}

View file

@ -1,9 +1,11 @@
#include "heallocation.h" #include "heallocation.h"
#include "config.h" #include "config.h"
#include "events.h"
#include "map.h" #include "map.h"
HealLocation::HealLocation(QString id, QString map, int i, uint16_t x, uint16_t y, QString respawnMap, uint16_t respawnNPC) HealLocation::HealLocation(QString id, QString map,
{ int i, uint16_t x, uint16_t y,
QString respawnMap, uint16_t respawnNPC) {
this->idName = id; this->idName = id;
this->mapName = map; this->mapName = map;
this->index = i; this->index = i;
@ -13,28 +15,23 @@ HealLocation::HealLocation(QString id, QString map, int i, uint16_t x, uint16_t
this->respawnNPC = respawnNPC; this->respawnNPC = respawnNPC;
} }
HealLocation HealLocation::fromEvent(Event *event) HealLocation HealLocation::fromEvent(Event *fromEvent) {
{ HealLocationEvent *event = dynamic_cast<HealLocationEvent *>(fromEvent);
HealLocation hl;
hl.idName = event->get("id_name"); HealLocation healLocation;
hl.mapName = event->get("loc_name"); healLocation.idName = event->getIdName();
try { healLocation.mapName = event->getLocationName();
hl.index = event->get("index").toInt(); healLocation.index = event->getIndex();
} healLocation.x = event->getX();
catch(...) { healLocation.y = event->getY();
hl.index = 0;
}
hl.x = event->getU16("x");
hl.y = event->getU16("y");
if (projectConfig.getHealLocationRespawnDataEnabled()) { if (projectConfig.getHealLocationRespawnDataEnabled()) {
hl.respawnNPC = event->getU16("respawn_npc"); healLocation.respawnNPC = event->getRespawnNPC();
hl.respawnMap = Map::mapConstantFromName(event->get("respawn_map")).remove(0,4); healLocation.respawnMap = Map::mapConstantFromName(event->getRespawnMap()).remove(0,4);
} }
return hl; return healLocation;
} }
QDebug operator<<(QDebug debug, const HealLocation &hl) QDebug operator<<(QDebug debug, const HealLocation &healLocation) {
{ debug << "HealLocation_" + healLocation.mapName << "(" << healLocation.x << ',' << healLocation.y << ")";
debug << "HealLocation_" + hl.mapName << "(" << hl.x << ',' << hl.y << ")";
return debug; return debug;
} }

View file

@ -474,34 +474,40 @@ QList<Event *> Map::getAllEvents() const {
return all_events; return all_events;
} }
QStringList Map::eventScriptLabels(const QString &event_group_type) const { QStringList Map::eventScriptLabels(Event::Group group) const {
QStringList scriptLabels; QStringList scriptLabels;
if (event_group_type.isEmpty()) {
for (const auto *event : getAllEvents()) if (group == Event::Group::None) {
scriptLabels << event->get("script_label"); ScriptTracker scriptTracker;
for (Event *event : this->getAllEvents()) {
event->accept(&scriptTracker);
}
scriptLabels = scriptTracker.getScripts();
} else { } else {
for (const auto *event : events.value(event_group_type)) ScriptTracker scriptTracker;
scriptLabels << event->get("script_label"); for (Event *event : events.value(group)) {
event->accept(&scriptTracker);
}
scriptLabels = scriptTracker.getScripts();
} }
scriptLabels.removeAll(""); scriptLabels.removeAll("");
scriptLabels.removeDuplicates(); scriptLabels.removeDuplicates();
if (scriptLabels.contains("0x0")) scriptLabels.prepend("0x0");
scriptLabels.move(scriptLabels.indexOf("0x0"), scriptLabels.count() - 1); scriptLabels.prepend("NULL");
if (scriptLabels.contains("NULL"))
scriptLabels.move(scriptLabels.indexOf("NULL"), scriptLabels.count() - 1);
return scriptLabels; return scriptLabels;
} }
void Map::removeEvent(Event *event) { void Map::removeEvent(Event *event) {
for (QString key : events.keys()) { for (Event::Group key : events.keys()) {
events[key].removeAll(event); events[key].removeAll(event);
} }
} }
void Map::addEvent(Event *event) { void Map::addEvent(Event *event) {
events[event->get("event_group_type")].append(event); event->setMap(this);
events[event->getEventGroup()].append(event);
if (!ownedEvents.contains(event)) ownedEvents.append(event); if (!ownedEvents.contains(event)) ownedEvents.append(event);
} }

View file

@ -15,6 +15,8 @@ const QRegularExpression ParseUtil::re_poryScriptLabel("\\b(script)(\\((global|l
const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)"); const QRegularExpression ParseUtil::re_globalPoryScriptLabel("\\b(script)(\\((global)\\))?\\s*\\b(?<label>[\\w_][\\w\\d_]*)");
const QRegularExpression ParseUtil::re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)"); const QRegularExpression ParseUtil::re_poryRawSection("\\b(raw)\\s*`(?<raw_script>[^`]*)");
using OrderedJson = poryjson::Json;
void ParseUtil::set_root(const QString &dir) { void ParseUtil::set_root(const QString &dir) {
this->root = dir; this->root = dir;
} }

View file

@ -260,7 +260,8 @@ void ResizeTilemap::undo() {
/// ///
ClearEntries::ClearEntries(RegionMap *map, tsl::ordered_map<QString, MapSectionEntry> entries, QUndoCommand *parent) { ClearEntries::ClearEntries(RegionMap *map, tsl::ordered_map<QString, MapSectionEntry> entries, QUndoCommand *parent)
: QUndoCommand(parent) {
setText("Clear Entries"); setText("Clear Entries");
this->map = map; this->map = map;

View file

@ -1,6 +1,5 @@
#include "editor.h" #include "editor.h"
#include "draggablepixmapitem.h" #include "draggablepixmapitem.h"
#include "event.h"
#include "imageproviders.h" #include "imageproviders.h"
#include "log.h" #include "log.h"
#include "mapconnection.h" #include "mapconnection.h"
@ -1230,12 +1229,12 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
// Left-clicking while in paint mode will add a new event of the // Left-clicking while in paint mode will add a new event of the
// type of the first currently selected events. // type of the first currently selected events.
// Disallow adding heal locations, deleting them is not possible yet // Disallow adding heal locations, deleting them is not possible yet
QString eventType = EventType::Object; Event::Type eventType = Event::Type::Object;
if (this->selected_events->size() > 0) if (this->selected_events->size() > 0)
eventType = this->selected_events->first()->event->get("event_type"); eventType = this->selected_events->first()->event->getEventType();
if (eventType != EventType::HealLocation) { if (eventType != Event::Type::HealLocation) {
DraggablePixmapItem * newEvent = addNewEvent(eventType); DraggablePixmapItem *newEvent = addNewEvent(eventType);
if (newEvent) { if (newEvent) {
newEvent->move(pos.x(), pos.y()); newEvent->move(pos.x(), pos.y());
emit objectsChanged(); emit objectsChanged();
@ -1250,7 +1249,6 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
static unsigned actionId = 0; static unsigned actionId = 0;
if (event->type() == QEvent::GraphicsSceneMouseRelease) { if (event->type() == QEvent::GraphicsSceneMouseRelease) {
// TODO: commit / update history here
actionId++; actionId++;
} else { } else {
if (event->type() == QEvent::GraphicsSceneMousePress) { if (event->type() == QEvent::GraphicsSceneMousePress) {
@ -1516,7 +1514,6 @@ void Editor::displayMapEvents() {
DraggablePixmapItem *Editor::addMapEvent(Event *event) { DraggablePixmapItem *Editor::addMapEvent(Event *event) {
DraggablePixmapItem *object = new DraggablePixmapItem(event, this); DraggablePixmapItem *object = new DraggablePixmapItem(event, this);
event->setPixmapItem(object);
this->redrawObject(object); this->redrawObject(object);
events_group->addToGroup(object); events_group->addToGroup(object);
return object; return object;
@ -1969,6 +1966,7 @@ Tileset* Editor::getCurrentMapPrimaryTileset()
} }
QList<DraggablePixmapItem *> Editor::getObjects() { QList<DraggablePixmapItem *> Editor::getObjects() {
// TODO: why using this instead of map->getAllEvents()?
QList<DraggablePixmapItem *> list; QList<DraggablePixmapItem *> list;
for (QGraphicsItem *child : events_group->childItems()) { for (QGraphicsItem *child : events_group->childItems()) {
list.append(static_cast<DraggablePixmapItem *>(child)); list.append(static_cast<DraggablePixmapItem *>(child));
@ -1977,15 +1975,16 @@ QList<DraggablePixmapItem *> Editor::getObjects() {
} }
void Editor::redrawObject(DraggablePixmapItem *item) { void Editor::redrawObject(DraggablePixmapItem *item) {
if (item && item->event && !item->event->pixmap.isNull()) { if (item && item->event && !item->event->getPixmap().isNull()) {
qreal opacity = item->event->usingSprite ? 1.0 : 0.7; qreal opacity = item->event->getUsingSprite() ? 1.0 : 0.7;
item->setOpacity(opacity); item->setOpacity(opacity);
item->setPixmap(item->event->pixmap.copy(item->event->frame * item->event->spriteWidth % item->event->pixmap.width(), 0, item->event->spriteWidth, item->event->spriteHeight)); project->setEventPixmap(item->event, true);
item->setPixmap(item->event->getPixmap());
item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); item->setShapeMode(QGraphicsPixmapItem::BoundingRectShape);
if (selected_events && selected_events->contains(item)) { if (selected_events && selected_events->contains(item)) {
QImage image = item->pixmap().toImage(); QImage image = item->pixmap().toImage();
QPainter painter(&image); QPainter painter(&image);
painter.setPen(QColor(250, 0, 255)); painter.setPen(QColor(255, 0, 255));
painter.drawRect(0, 0, image.width() - 1, image.height() - 1); painter.drawRect(0, 0, image.width() - 1, image.height() - 1);
painter.end(); painter.end();
item->setPixmap(QPixmap::fromImage(image)); item->setPixmap(QPixmap::fromImage(image));
@ -2026,6 +2025,22 @@ void Editor::selectMapEvent(DraggablePixmapItem *object, bool toggle) {
} }
} }
void Editor::selectedEventIndexChanged(int index, Event::Group eventGroup)
{
int event_offs = Event::getIndexOffset(eventGroup);
Event *event = this->map->events.value(eventGroup).at(index - event_offs);
DraggablePixmapItem *selectedEvent = nullptr;
for (QGraphicsItem *child : this->events_group->childItems()) {
DraggablePixmapItem *item = static_cast<DraggablePixmapItem *>(child);
if (item->event == event) {
selectedEvent = item;
break;
}
}
if (selectedEvent) this->selectMapEvent(selectedEvent);
}
void Editor::duplicateSelectedEvents() { void Editor::duplicateSelectedEvents() {
if (!selected_events || !selected_events->length() || !map || !current_view || map_item->paintingMode != MapPixmapItem::PaintMode::EventObjects) if (!selected_events || !selected_events->length() || !map || !current_view || map_item->paintingMode != MapPixmapItem::PaintMode::EventObjects)
return; return;
@ -2033,54 +2048,95 @@ void Editor::duplicateSelectedEvents() {
QList<Event *> selectedEvents; QList<Event *> selectedEvents;
for (int i = 0; i < selected_events->length(); i++) { for (int i = 0; i < selected_events->length(); i++) {
Event *original = selected_events->at(i)->event; Event *original = selected_events->at(i)->event;
QString eventType = original->get("event_type"); Event::Type eventType = original->getEventType();
if (eventLimitReached(eventType)) { if (eventLimitReached(eventType)) {
logWarn(QString("Skipping duplication, the map limit for events of type '%1' has been reached.").arg(eventType)); logWarn(QString("Skipping duplication, the map limit for events of type '%1' has been reached.").arg(Event::eventTypeToString(eventType)));
continue; continue;
} }
if (eventType == EventType::HealLocation) continue; if (eventType == Event::Type::HealLocation) {
Event *duplicate = new Event(*original); logWarn("Skipping duplication, event is a heal location.");
duplicate->setX(duplicate->x() + 1); continue;
duplicate->setY(duplicate->y() + 1); }
Event *duplicate = original->duplicate();
if (!duplicate) {
logError("Encountered a problem duplicating an event.");
continue;
}
duplicate->setX(duplicate->getX() + 1);
duplicate->setY(duplicate->getY() + 1);
selectedEvents.append(duplicate); selectedEvents.append(duplicate);
} }
map->editHistory.push(new EventDuplicate(this, map, selectedEvents)); map->editHistory.push(new EventDuplicate(this, map, selectedEvents));
} }
DraggablePixmapItem* Editor::addNewEvent(QString event_type) { DraggablePixmapItem *Editor::addNewEvent(Event::Type type) {
if (project && map && !event_type.isEmpty() && !eventLimitReached(event_type)) { Event *event = nullptr;
Event *event = Event::createNewEvent(event_type, map->name, project);
event->put("map_name", map->name);
if (event_type == EventType::HealLocation) {
HealLocation hl = HealLocation::fromEvent(event);
project->healLocations.append(hl);
event->put("index", project->healLocations.length());
}
map->editHistory.push(new EventCreate(this, map, event));
return event->pixmapItem; if (project && map && !eventLimitReached(type)) {
switch (type) {
case Event::Type::Object:
event = new ObjectEvent();
break;
case Event::Type::CloneObject:
event = new CloneObjectEvent();
break;
case Event::Type::Warp:
event = new WarpEvent();
break;
case Event::Type::Trigger:
event = new TriggerEvent();
break;
case Event::Type::WeatherTrigger:
event = new WeatherTriggerEvent();
break;
case Event::Type::Sign:
event = new SignEvent();
break;
case Event::Type::HiddenItem:
event = new HiddenItemEvent();
break;
case Event::Type::SecretBase:
event = new SecretBaseEvent();
break;
case Event::Type::HealLocation: {
event = new HealLocationEvent();
event->setMap(this->map);
event->setDefaultValues(this->project);
HealLocation healLocation = HealLocation::fromEvent(event);
project->healLocations.append(healLocation);
((HealLocationEvent *)event)->setIndex(project->healLocations.length());
break;
} }
default:
break;
}
if (!event) return nullptr;
event->setDefaultValues(this->project);
map->editHistory.push(new EventCreate(this, map, event));
return event->getPixmapItem();
}
return nullptr; return nullptr;
} }
// Currently only object events have an explicit limit // Currently only object events have an explicit limit
bool Editor::eventLimitReached(QString event_type) bool Editor::eventLimitReached(Event::Type event_type) {
{ if (project && map) {
if (project && map && !event_type.isEmpty()) { if (Event::typeToGroup(event_type) == Event::Group::Object)
if (Event::typeToGroup(event_type) == EventGroup::Object) return map->events.value(Event::Group::Object).length() >= project->getMaxObjectEvents();
return map->events.value(EventGroup::Object).length() >= project->getMaxObjectEvents();
} }
return false; return false;
} }
void Editor::deleteEvent(Event *event) { void Editor::deleteEvent(Event *event) {
Map *map = project->getMap(event->get("map_name")); Map *map = event->getMap();
if (map) { if (map) {
map->removeEvent(event); map->removeEvent(event);
if (event->pixmapItem) { if (event->getPixmapItem()) {
events_group->removeFromGroup(event->pixmapItem); events_group->removeFromGroup(event->getPixmapItem());
delete event->pixmapItem; delete event->getPixmapItem();
event->pixmapItem = nullptr;
} }
} }
//selected_events->removeAll(event); //selected_events->removeAll(event);
@ -2181,6 +2237,7 @@ void Editor::objectsView_onMousePress(QMouseEvent *event) {
this->ui->toolButton_Select->setChecked(true); this->ui->toolButton_Select->setChecked(true);
} }
// TODO: why do the old objects not get cleared?
bool multiSelect = event->modifiers() & Qt::ControlModifier; bool multiSelect = event->modifiers() & Qt::ControlModifier;
if (!selectingEvent && !multiSelect && selected_events->length() > 1) { if (!selectingEvent && !multiSelect && selected_events->length() > 1) {
DraggablePixmapItem *first = selected_events->first(); DraggablePixmapItem *first = selected_events->first();

View file

@ -4,9 +4,8 @@
#include "project.h" #include "project.h"
#include "log.h" #include "log.h"
#include "editor.h" #include "editor.h"
#include "eventpropertiesframe.h"
#include "ui_eventpropertiesframe.h"
#include "prefabcreationdialog.h" #include "prefabcreationdialog.h"
#include "eventframes.h"
#include "bordermetatilespixmapitem.h" #include "bordermetatilespixmapitem.h"
#include "currentselectedmetatilespixmapitem.h" #include "currentselectedmetatilespixmapitem.h"
#include "customattributestable.h" #include "customattributestable.h"
@ -291,6 +290,23 @@ void MainWindow::initEditor() {
// Toggle an asterisk in the window title when the undo state is changed // Toggle an asterisk in the window title when the undo state is changed
connect(&editor->editGroup, &QUndoGroup::cleanChanged, this, &MainWindow::showWindowTitle); connect(&editor->editGroup, &QUndoGroup::cleanChanged, this, &MainWindow::showWindowTitle);
// selecting objects from the spinners
connect(this->ui->spinner_ObjectID, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
this->editor->selectedEventIndexChanged(value, Event::Group::Object);
});
connect(this->ui->spinner_WarpID, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
this->editor->selectedEventIndexChanged(value, Event::Group::Warp);
});
connect(this->ui->spinner_TriggerID, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
this->editor->selectedEventIndexChanged(value, Event::Group::Coord);
});
connect(this->ui->spinner_BgID, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
this->editor->selectedEventIndexChanged(value, Event::Group::Bg);
});
connect(this->ui->spinner_HealID, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
this->editor->selectedEventIndexChanged(value, Event::Group::Heal);
});
} }
void MainWindow::initMiscHeapObjects() { void MainWindow::initMiscHeapObjects() {
@ -388,8 +404,6 @@ void MainWindow::setProjectSpecificUIVisibility()
ui->label_AllowRunning->setVisible(true); ui->label_AllowRunning->setVisible(true);
ui->label_AllowBiking->setVisible(true); ui->label_AllowBiking->setVisible(true);
ui->label_AllowEscapeRope->setVisible(true); ui->label_AllowEscapeRope->setVisible(true);
// TODO: pokefirered is not set up for the Region Map Editor and vice versa.
// porymap will crash on attempt. Remove below once resolved
ui->actionRegion_Map_Editor->setVisible(true); ui->actionRegion_Map_Editor->setVisible(true);
break; break;
} }
@ -704,21 +718,13 @@ void MainWindow::refreshMapScene()
on_horizontalSlider_MetatileZoom_valueChanged(ui->horizontalSlider_MetatileZoom->value()); on_horizontalSlider_MetatileZoom_valueChanged(ui->horizontalSlider_MetatileZoom->value());
} }
void MainWindow::openWarpMap(QString map_name, QString event_id, QString event_group) { void MainWindow::openWarpMap(QString map_name, int event_id, Event::Group event_group) {
// Ensure valid destination map name. // Ensure valid destination map name.
if (!editor->project->mapNames.contains(map_name)) { if (!editor->project->mapNames.contains(map_name)) {
logError(QString("Invalid map name '%1'").arg(map_name)); logError(QString("Invalid map name '%1'").arg(map_name));
return; return;
} }
// Ensure valid event number.
bool ok;
int event_index = event_id.toInt(&ok, 0);
if (!ok) {
logError(QString("Invalid event number '%1' for map '%2'").arg(event_id).arg(map_name));
return;
}
// Open the destination map. // Open the destination map.
if (!setMap(map_name, true)) { if (!setMap(map_name, true)) {
QMessageBox msgBox(this); QMessageBox msgBox(this);
@ -731,10 +737,10 @@ void MainWindow::openWarpMap(QString map_name, QString event_id, QString event_g
} }
// Select the target event. // Select the target event.
event_index -= Event::getIndexOffset(event_group); event_id -= Event::getIndexOffset(event_group);
QList<Event*> events = editor->map->events[event_group]; QList<Event*> events = editor->map->events[event_group];
if (event_index < events.length() && event_index >= 0) { if (event_id < events.length() && event_id >= 0) {
Event *event = events.at(event_index); Event *event = events.at(event_id);
for (DraggablePixmapItem *item : editor->getObjects()) { for (DraggablePixmapItem *item : editor->getObjects()) {
if (item->event == event) { if (item->event == event) {
editor->selected_events->clear(); editor->selected_events->clear();
@ -1197,9 +1203,9 @@ void MainWindow::onNewMapCreated() {
setMap(newMapName, true); setMap(newMapName, true);
if (ParseUtil::gameStringToBool(newMap->isFlyable)) { if (ParseUtil::gameStringToBool(newMap->isFlyable)) {
addNewEvent(EventType::HealLocation); addNewEvent(Event::Type::HealLocation);
editor->project->saveHealLocationStruct(newMap); editor->project->saveHealLocationStruct(newMap);
editor->save();// required editor->save();
} }
disconnect(this->newMapPrompt, &NewMapPopup::applied, this, &MainWindow::onNewMapCreated); disconnect(this->newMapPrompt, &NewMapPopup::applied, this, &MainWindow::onNewMapCreated);
@ -1444,8 +1450,7 @@ void MainWindow::updateMapList() {
drawMapListIcons(mapListModel); drawMapListIcons(mapListModel);
} }
void MainWindow::on_action_Save_Project_triggered() void MainWindow::on_action_Save_Project_triggered() {
{
editor->saveProject(); editor->saveProject();
updateMapList(); updateMapList();
} }
@ -1508,6 +1513,8 @@ void MainWindow::copy() {
} }
case 1: case 1:
{ {
if (!editor || !editor->project) break;
// copy the currently selected event(s) as a json object // copy the currently selected event(s) as a json object
OrderedJson::object copyObject; OrderedJson::object copyObject;
copyObject["object"] = "events"; copyObject["object"] = "events";
@ -1521,22 +1528,20 @@ void MainWindow::copy() {
for (auto item : events) { for (auto item : events) {
Event *event = item->event; Event *event = item->event;
QString type = event->get("event_type");
if (type == EventType::HealLocation) { if (event->getEventType() == Event::Type::HealLocation) {
// no copy on heal locations // no copy on heal locations
logWarn(QString("Copying events of type '%1' is not allowed.").arg(type)); logWarn(QString("Copying heal location events is not allowed."));
continue; continue;
} }
OrderedJson::object eventJson; OrderedJson::object eventContainer;
eventContainer["event_type"] = Event::eventTypeToString(event->getEventType());
for (QString key : event->values.keys()) { OrderedJson::object eventJson = event->buildEventJson(editor->project);
eventJson[key] = event->values[key]; eventContainer["event"] = eventJson;
eventsArray.append(eventContainer);
} }
eventsArray.append(eventJson);
}
if (!eventsArray.isEmpty()) { if (!eventsArray.isEmpty()) {
copyObject["events"] = eventsArray; copyObject["events"] = eventsArray;
setClipboardData(copyObject); setClipboardData(copyObject);
@ -1624,48 +1629,63 @@ void MainWindow::paste() {
QJsonArray events = pasteObject["events"].toArray(); QJsonArray events = pasteObject["events"].toArray();
for (QJsonValue event : events) { for (QJsonValue event : events) {
// paste the event to the map // paste the event to the map
QString type = event["event_type"].toString(); Event *pasteEvent = nullptr;
Event::Type type = Event::eventTypeFromString(event["event_type"].toString());
if (editor->eventLimitReached(type)) { if (editor->eventLimitReached(type)) {
logWarn(QString("Skipping paste, the map limit for events of type '%1' has been reached.").arg(type)); logWarn(QString("Skipping paste, the map limit for events of type '%1' has been reached.").arg(event["event_type"].toString()));
continue; continue;
} }
Event *pasteEvent = Event::createNewEvent(type, editor->map->name, editor->project); switch (type) {
case Event::Type::Object:
for (auto key : event.toObject().keys()) // TODO: check event limit?
{ pasteEvent = new ObjectEvent();
QString value; pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
QJsonValue valueJson = event[key]; case Event::Type::CloneObject:
pasteEvent = new CloneObjectEvent();
switch (valueJson.type()) { pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
case Event::Type::Warp:
pasteEvent = new WarpEvent();
pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
case Event::Type::Trigger:
pasteEvent = new TriggerEvent();
pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
case Event::Type::WeatherTrigger:
pasteEvent = new WeatherTriggerEvent();
pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
case Event::Type::Sign:
pasteEvent = new SignEvent();
pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
case Event::Type::HiddenItem:
pasteEvent = new HiddenItemEvent();
pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
case Event::Type::SecretBase:
pasteEvent = new SecretBaseEvent();
pasteEvent->loadFromJson(event["event"].toObject(), this->editor->project);
break;
default: default:
case QJsonValue::Type::Null:
case QJsonValue::Type::Array:
case QJsonValue::Type::Object:
break; break;
case QJsonValue::Type::Double:
value = QString::number(valueJson.toInt());
break;
case QJsonValue::Type::String:
value = valueJson.toString();
break;
case QJsonValue::Type::Bool:
value = QString::number(valueJson.toBool());
break;
}
pasteEvent->put(key, value);
} }
pasteEvent->put("map_name", editor->map->name); if (pasteEvent) {
pasteEvent->setMap(this->editor->map);
newEvents.append(pasteEvent); newEvents.append(pasteEvent);
} }
if (!newEvents.isEmpty()) {
updateObjects();
editor->map->editHistory.push(new EventPaste(this->editor, editor->map, newEvents));
} }
if (!newEvents.empty()) {
editor->map->editHistory.push(new EventPaste(this->editor, editor->map, newEvents));
updateObjects();
}
break; break;
} }
} }
@ -1865,10 +1885,9 @@ void MainWindow::resetMapViewScale() {
editor->scaleMapView(0); editor->scaleMapView(0);
} }
void MainWindow::addNewEvent(QString event_type) void MainWindow::addNewEvent(Event::Type type) {
{
if (editor && editor->project) { if (editor && editor->project) {
DraggablePixmapItem *object = editor->addNewEvent(event_type); DraggablePixmapItem *object = editor->addNewEvent(type);
if (object) { if (object) {
auto halfSize = ui->graphicsView_Map->size() / 2; auto halfSize = ui->graphicsView_Map->size() / 2;
auto centerPos = ui->graphicsView_Map->mapToScene(halfSize.width(), halfSize.height()); auto centerPos = ui->graphicsView_Map->mapToScene(halfSize.width(), halfSize.height());
@ -1878,7 +1897,7 @@ void MainWindow::addNewEvent(QString event_type)
} else { } else {
QMessageBox msgBox(this); QMessageBox msgBox(this);
msgBox.setText("Failed to add new event"); msgBox.setText("Failed to add new event");
if (Event::typeToGroup(event_type) == EventGroup::Object) { if (Event::typeToGroup(type) == Event::Group::Object) {
msgBox.setInformativeText(QString("The limit for object events (%1) has been reached.\n\n" msgBox.setInformativeText(QString("The limit for object events (%1) has been reached.\n\n"
"This limit can be adjusted with OBJECT_EVENT_TEMPLATES_COUNT in '%2'.") "This limit can be adjusted with OBJECT_EVENT_TEMPLATES_COUNT in '%2'.")
.arg(editor->project->getMaxObjectEvents()) .arg(editor->project->getMaxObjectEvents())
@ -1899,19 +1918,19 @@ void MainWindow::updateObjects() {
selectedHealspot = nullptr; selectedHealspot = nullptr;
ui->tabWidget_EventType->clear(); ui->tabWidget_EventType->clear();
if (editor->map->events.value(EventGroup::Object).length()) if (editor->map->events.value(Event::Group::Object).length())
ui->tabWidget_EventType->addTab(eventTabObjectWidget, "Objects"); ui->tabWidget_EventType->addTab(eventTabObjectWidget, "Objects");
if (editor->map->events.value(EventGroup::Warp).length()) if (editor->map->events.value(Event::Group::Warp).length())
ui->tabWidget_EventType->addTab(eventTabWarpWidget, "Warps"); ui->tabWidget_EventType->addTab(eventTabWarpWidget, "Warps");
if (editor->map->events.value(EventGroup::Coord).length()) if (editor->map->events.value(Event::Group::Coord).length())
ui->tabWidget_EventType->addTab(eventTabTriggerWidget, "Triggers"); ui->tabWidget_EventType->addTab(eventTabTriggerWidget, "Triggers");
if (editor->map->events.value(EventGroup::Bg).length()) if (editor->map->events.value(Event::Group::Bg).length())
ui->tabWidget_EventType->addTab(eventTabBGWidget, "BGs"); ui->tabWidget_EventType->addTab(eventTabBGWidget, "BGs");
if (editor->map->events.value(EventGroup::Heal).length()) if (editor->map->events.value(Event::Group::Heal).length())
ui->tabWidget_EventType->addTab(eventTabHealspotWidget, "Healspots"); ui->tabWidget_EventType->addTab(eventTabHealspotWidget, "Healspots");
updateSelectedObjects(); updateSelectedObjects();
@ -1919,12 +1938,17 @@ void MainWindow::updateObjects() {
// Should probably just pass layout and let the editor work it out // Should probably just pass layout and let the editor work it out
void MainWindow::updateSelectedObjects() { void MainWindow::updateSelectedObjects() {
// TODO: make events and/or frames list static? don't want to clear and
// re-add children frames if they are already there in a multi-select
// because QVBoxLayout::addWidget() is taking a lot of time
// TODO: frame->setActive(false) on old frames, (true) on active ones
QList<DraggablePixmapItem *> all_events = editor->getObjects(); QList<DraggablePixmapItem *> all_events = editor->getObjects();
QList<DraggablePixmapItem *> events; QList<DraggablePixmapItem *> events;
if (editor->selected_events && editor->selected_events->length()) { if (editor->selected_events && editor->selected_events->length()) {
events = *editor->selected_events; events = *editor->selected_events;
} else { }
else {
if (all_events.length()) { if (all_events.length()) {
DraggablePixmapItem *selectedEvent = all_events.first(); DraggablePixmapItem *selectedEvent = all_events.first();
editor->selected_events->append(selectedEvent); editor->selected_events->append(selectedEvent);
@ -1933,526 +1957,171 @@ void MainWindow::updateSelectedObjects() {
} }
} }
for (auto *button : openScriptButtons)
delete button;
openScriptButtons.clear();
QList<EventPropertiesFrame *> frames;
bool quantityEnabled = projectConfig.getHiddenItemQuantityEnabled();
bool underfootEnabled = projectConfig.getHiddenItemRequiresItemfinderEnabled();
bool respawnDataEnabled = projectConfig.getHealLocationRespawnDataEnabled();
for (DraggablePixmapItem *item : events) {
EventPropertiesFrame *frame = new EventPropertiesFrame(item->event);
// frame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
NoScrollSpinBox *x = frame->ui->spinBox_x;
NoScrollSpinBox *y = frame->ui->spinBox_y;
NoScrollSpinBox *z = frame->ui->spinBox_z;
x->setValue(item->event->x());
connect(x, QOverload<int>::of(&QSpinBox::valueChanged), [this, item, x](int value) {
int delta = value - item->event->x();
if (delta)
editor->map->editHistory.push(new EventMove(QList<Event *>() << item->event, delta, 0, x->getActionId()));
});
connect(item, &DraggablePixmapItem::xChanged, x, &NoScrollSpinBox::setValue);
y->setValue(item->event->y());
connect(y, QOverload<int>::of(&QSpinBox::valueChanged), [this, item, y](int value) {
int delta = value - item->event->y();
if (delta)
editor->map->editHistory.push(new EventMove(QList<Event *>() << item->event, 0, delta, y->getActionId()));
});
connect(item, &DraggablePixmapItem::yChanged, y, &NoScrollSpinBox::setValue);
z->setValue(item->event->elevation());
connect(z, &NoScrollSpinBox::textChanged, item, &DraggablePixmapItem::set_elevation);
connect(item, &DraggablePixmapItem::elevationChanged, z, &NoScrollSpinBox::setValue);
QString event_type = item->event->get("event_type");
QString event_group_type = item->event->get("event_group_type");
QString map_name = item->event->get("map_name");
int event_offs = Event::getIndexOffset(event_group_type);
frame->ui->label_name->setText(QString("%1 Id").arg(event_type));
if (events.count() == 1)
{
frame->ui->spinBox_index->setValue(editor->project->getMap(map_name)->events.value(event_group_type).indexOf(item->event) + event_offs);
frame->ui->spinBox_index->setMinimum(event_offs);
frame->ui->spinBox_index->setMaximum(editor->project->getMap(map_name)->events.value(event_group_type).length() + event_offs - 1);
connect(frame->ui->spinBox_index, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::selectedEventIndexChanged);
}
else
{
frame->ui->spinBox_index->setVisible(false);
}
frame->ui->label_spritePixmap->setPixmap(item->event->pixmap);
connect(item, &DraggablePixmapItem::spriteChanged, frame->ui->label_spritePixmap, &QLabel::setPixmap);
frame->ui->sprite->setVisible(false);
QMap<QString, QString> field_labels;
field_labels["script_label"] = "Script";
field_labels["event_flag"] = "Event Flag";
field_labels["movement_type"] = "Movement";
field_labels["radius_x"] = "Movement Radius X";
field_labels["radius_y"] = "Movement Radius Y";
field_labels["trainer_type"] = "Trainer Type";
field_labels["sight_radius_tree_id"] = "Sight Radius / Berry Tree ID";
field_labels["destination_warp"] = "Destination Warp";
field_labels["destination_map_name"] = "Destination Map";
field_labels["script_var"] = "Var";
field_labels["script_var_value"] = "Var Value";
field_labels["player_facing_direction"] = "Player Facing Direction";
field_labels["item"] = "Item";
field_labels["quantity"] = "Quantity";
field_labels["underfoot"] = "Requires Itemfinder";
field_labels["weather"] = "Weather";
field_labels["flag"] = "Flag";
field_labels["secret_base_id"] = "Secret Base Id";
field_labels["respawn_map"] = "Respawn Map";
field_labels["respawn_npc"] = "Respawn NPC";
field_labels["target_local_id"] = "Target Local Id";
field_labels["target_map"] = "Target Map";
QStringList fields;
if (event_type == EventType::Object) {
frame->ui->sprite->setVisible(true);
frame->ui->comboBox_sprite->addItems(editor->project->gfxDefines.keys());
frame->ui->comboBox_sprite->setCurrentIndex(frame->ui->comboBox_sprite->findText(item->event->get("sprite")));
connect(frame->ui->comboBox_sprite, &QComboBox::currentTextChanged, item, &DraggablePixmapItem::set_sprite);
connect(frame->ui->comboBox_sprite, &QComboBox::currentTextChanged, this, &MainWindow::markMapEdited);
/*
frame->ui->script->setVisible(true);
frame->ui->comboBox_script->addItem(item->event->get("script_label"));
frame->ui->comboBox_script->setCurrentText(item->event->get("script_label"));
//item->bind(frame->ui->comboBox_script, "script_label");
connect(frame->ui->comboBox_script, SIGNAL(activated(QString)), item, SLOT(set_script(QString)));
//connect(frame->ui->comboBox_script, static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::activated), item, [item](QString script_label){ item->event->put("script_label", script_label); });
//connect(item, SIGNAL(scriptChanged(QString)), frame->ui->comboBox_script, SLOT(setValue(QString)));
*/
fields << "movement_type";
fields << "radius_x";
fields << "radius_y";
fields << "script_label";
fields << "event_flag";
fields << "trainer_type";
fields << "sight_radius_tree_id";
}
else if (event_type == EventType::CloneObject) {
frame->ui->sprite->setVisible(true);
frame->ui->comboBox_sprite->setEnabled(false);
frame->ui->comboBox_sprite->addItem(item->event->get("sprite"));
frame->ui->spinBox_z->setVisible(false);
frame->ui->label_z->setVisible(false);
fields << "target_local_id";
fields << "target_map";
}
else if (event_type == EventType::Warp) {
fields << "destination_map_name";
fields << "destination_warp";
}
else if (event_type == EventType::Trigger) {
fields << "script_label";
fields << "script_var";
fields << "script_var_value";
}
else if (event_type == EventType::WeatherTrigger) {
fields << "weather";
}
else if (event_type == EventType::Sign) {
fields << "player_facing_direction";
fields << "script_label";
}
else if (event_type == EventType::HiddenItem) {
fields << "item";
fields << "flag";
if (quantityEnabled) fields << "quantity";
if (underfootEnabled) fields << "underfoot";
}
else if (event_type == EventType::SecretBase) {
fields << "secret_base_id";
}
else if (event_type == EventType::HealLocation) {
// Hide elevation so users don't get impression that editing it is meaningful.
frame->ui->spinBox_z->setVisible(false);
frame->ui->label_z->setVisible(false);
if (respawnDataEnabled) {
fields << "respawn_map";
fields << "respawn_npc";
}
}
// Some keys shouldn't use a combobox
QStringList spinKeys = {"quantity", "respawn_npc", "target_local_id"};
QStringList checkKeys = {"underfoot"};
for (QString key : fields) {
QString value = item->event->get(key);
QWidget *widget = new QWidget(frame);
QFormLayout *fl = new QFormLayout(widget);
fl->setContentsMargins(9, 0, 9, 0);
fl->setRowWrapPolicy(QFormLayout::WrapLongRows);
NoScrollSpinBox *spin;
NoScrollComboBox *combo;
QCheckBox *check;
if (spinKeys.contains(key)) {
spin = new NoScrollSpinBox(widget);
} else if (checkKeys.contains(key)) {
check = new QCheckBox(widget);
} else {
combo = new NoScrollComboBox(widget);
combo->setEditable(true);
}
if (key == "destination_map_name") {
if (!editor->project->mapNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->mapNames);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The destination map name of the warp.");
} else if (key == "destination_warp") {
combo->setToolTip("The warp id on the destination map.");
} else if (key == "item") {
if (!editor->project->itemNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->itemNames);
combo->setCurrentIndex(combo->findText(value));
} else if (key == "quantity") {
spin->setToolTip("The number of items received when the hidden item is picked up.");
// Min 1 not needed. 0 is treated as a valid quantity and works as expected in-game.
spin->setMaximum(127);
} else if (key == "underfoot") {
check->setToolTip("If checked, hidden item can only be picked up using the Itemfinder");
} else if (key == "flag" || key == "event_flag") {
if (!editor->project->flagNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->flagNames);
combo->setCurrentIndex(combo->findText(value));
if (key == "flag")
combo->setToolTip("The flag which is set when the hidden item is picked up.");
else if (key == "event_flag")
combo->setToolTip("The flag which hides the object when set.");
} else if (key == "script_var") {
if (!editor->project->varNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->varNames);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The variable by which the script is triggered.\n"
"The script is triggered when this variable's value matches 'Var Value'.");
} else if (key == "script_var_value") {
combo->setToolTip("The variable's value which triggers the script.");
} else if (key == "movement_type") {
if (!editor->project->movementTypes.contains(value)) {
combo->addItem(value);
}
connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged),
this, [item](QString value){
item->event->put("movement_type", value);
item->updatePixmap();
});
combo->addItems(editor->project->movementTypes);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The object's natural movement behavior when\n"
"the player is not interacting with it.");
} else if (key == "weather") {
if (!editor->project->coordEventWeatherNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->coordEventWeatherNames);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The weather that starts when the player steps on this spot.");
} else if (key == "secret_base_id") {
if (!editor->project->secretBaseIds.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->secretBaseIds);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The secret base id which is inside this secret\n"
"base entrance. Secret base ids are meant to be\n"
"unique to each and every secret base entrance.");
} else if (key == "player_facing_direction") {
if (!editor->project->bgEventFacingDirections.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->bgEventFacingDirections);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The direction which the player must be facing\n"
"to be able to interact with this event.");
} else if (key == "radius_x") {
combo->setToolTip("The maximum number of metatiles this object\n"
"is allowed to move left or right during its\n"
"normal movement behavior actions.");
combo->setMinimumContentsLength(4);
} else if (key == "radius_y") {
combo->setToolTip("The maximum number of metatiles this object\n"
"is allowed to move up or down during its\n"
"normal movement behavior actions.");
combo->setMinimumContentsLength(4);
} else if (key == "script_label") {
const auto localScriptLabels = editor->map->eventScriptLabels();
combo->addItems(localScriptLabels);
combo->setCompleter(editor->project->getEventScriptLabelCompleter(localScriptLabels));
combo->setToolTip("The script which is executed with this event.");
} else if (key == "trainer_type") {
combo->addItems(editor->project->trainerTypes);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The trainer type of this object event.\n"
"If it is not a trainer, use NONE. SEE ALL DIRECTIONS\n"
"should only be used with a sight radius of 1.");
} else if (key == "sight_radius_tree_id") {
combo->setToolTip("The maximum sight range of a trainer,\n"
"OR the unique id of the berry tree.");
combo->setMinimumContentsLength(4);
} else if (key == "respawn_map") {
if (!editor->project->mapNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->mapNames);
combo->setToolTip("The map where the player will respawn after whiteout.");
} else if (key == "respawn_npc") {
spin->setToolTip("event_object ID of the NPC the player interacts with\n"
"upon respawning after whiteout.");
spin->setMinimum(1);
spin->setMaximum(126);
} else if (key == "target_local_id") {
spin->setToolTip("event_object ID of the object being cloned.");
spin->setMinimum(1);
spin->setMaximum(126);
connect(spin, QOverload<int>::of(&NoScrollSpinBox::valueChanged), [item, frame](int value) {
item->event->put("target_local_id", value);
item->updatePixmap();
frame->ui->comboBox_sprite->setItemText(0, item->event->get("sprite"));
});
} else if (key == "target_map") {
if (!editor->project->mapNames.contains(value)) {
combo->addItem(value);
}
combo->addItems(editor->project->mapNames);
combo->setCurrentIndex(combo->findText(value));
combo->setToolTip("The name of the map that the object being cloned is on.");
connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged), this, [item, frame](QString value){
item->event->put("target_map", value);
item->updatePixmap();
frame->ui->comboBox_sprite->setItemText(0, item->event->get("sprite"));
});
} else {
combo->addItem(value);
}
// Keys using spin boxes
if (spinKeys.contains(key)) {
spin->setValue(value.toInt());
fl->addRow(new QLabel(field_labels[key], widget), spin);
widget->setLayout(fl);
frame->layout()->addWidget(widget);
connect(spin, QOverload<int>::of(&NoScrollSpinBox::valueChanged), [item, key](int value) {
item->event->put(key, value);
});
connect(spin, QOverload<int>::of(&NoScrollSpinBox::valueChanged), this, &MainWindow::markMapEdited);
// Keys using check boxes
} else if (checkKeys.contains(key)) {
check->setChecked(value.toInt());
fl->addRow(new QLabel(field_labels[key], widget), check);
widget->setLayout(fl);
frame->layout()->addWidget(widget);
connect(check, &QCheckBox::stateChanged, [item, key](int state) {
switch (state)
{
case Qt::Checked:
item->event->put(key, true);
break;
case Qt::Unchecked:
item->event->put(key, false);
break;
}
});
connect(check, &QCheckBox::stateChanged, this, &MainWindow::markMapEdited);
// Keys using combo boxes
} else {
combo->setCurrentText(value);
if (key == "script_label") {
// Add button next to combo which opens combo's current script.
auto *hl = new QHBoxLayout();
hl->setSpacing(3);
auto *openScriptButton = new QToolButton(widget);
openScriptButtons << openScriptButton;
openScriptButton->setFixedSize(combo->height(), combo->height());
openScriptButton->setIcon(QFileIconProvider().icon(QFileIconProvider::File));
openScriptButton->setToolTip("Go to this script definition in text editor.");
connect(openScriptButton, &QToolButton::clicked,
[this, combo]() { this->editor->openScript(combo->currentText()); });
hl->addWidget(combo);
hl->addWidget(openScriptButton);
fl->addRow(new QLabel(field_labels[key], widget), hl);
if (porymapConfig.getTextEditorGotoLine().isEmpty())
openScriptButton->hide();
} else {
fl->addRow(new QLabel(field_labels[key], widget), combo);
}
widget->setLayout(fl);
frame->layout()->addWidget(widget);
item->bind(combo, key);
connect(combo, &QComboBox::currentTextChanged, this, &MainWindow::markMapEdited);
}
}
frames.append(frame);
}
//int scroll = ui->scrollArea_4->verticalScrollBar()->value();
QScrollArea *scrollTarget = ui->scrollArea_Multiple; QScrollArea *scrollTarget = ui->scrollArea_Multiple;
QWidget *target = ui->scrollAreaWidgetContents_Multiple; QWidget *target = ui->scrollAreaWidgetContents_Multiple;
isProgrammaticEventTabChange = true; isProgrammaticEventTabChange = true;
if (events.length() == 1) if (events.length() == 1) {
{ Event *current = events[0]->event;
QString event_group_type = events[0]->event->get("event_group_type"); Event::Group event_group_type = current->getEventGroup();
int event_offs = Event::getIndexOffset(event_group_type);
if (event_group_type == EventGroup::Object) { // TODO: use switch
// TODO: don't need to set min/max every time, just when changing number of events in the group
if (event_group_type == Event::Group::Object) {
scrollTarget = ui->scrollArea_Objects; scrollTarget = ui->scrollArea_Objects;
target = ui->scrollAreaWidgetContents_Objects; target = ui->scrollAreaWidgetContents_Objects;
ui->tabWidget_EventType->setCurrentWidget(ui->tab_Objects); ui->tabWidget_EventType->setCurrentWidget(ui->tab_Objects);
this->ui->spinner_ObjectID->setValue(current->getEventIndex() + event_offs);
this->ui->spinner_ObjectID->setMinimum(event_offs);
this->ui->spinner_ObjectID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1);
} }
else if (event_group_type == EventGroup::Warp) { else if (event_group_type == Event::Group::Warp) {
scrollTarget = ui->scrollArea_Warps; scrollTarget = ui->scrollArea_Warps;
target = ui->scrollAreaWidgetContents_Warps; target = ui->scrollAreaWidgetContents_Warps;
ui->tabWidget_EventType->setCurrentWidget(ui->tab_Warps); ui->tabWidget_EventType->setCurrentWidget(ui->tab_Warps);
this->ui->spinner_WarpID->setValue(current->getEventIndex() + event_offs);
this->ui->spinner_WarpID->setMinimum(event_offs);
this->ui->spinner_WarpID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1);
} }
else if (event_group_type == EventGroup::Coord) { else if (event_group_type == Event::Group::Coord) {
scrollTarget = ui->scrollArea_Triggers; scrollTarget = ui->scrollArea_Triggers;
target = ui->scrollAreaWidgetContents_Triggers; target = ui->scrollAreaWidgetContents_Triggers;
ui->tabWidget_EventType->setCurrentWidget(ui->tab_Triggers); ui->tabWidget_EventType->setCurrentWidget(ui->tab_Triggers);
this->ui->spinner_TriggerID->setValue(current->getEventIndex() + event_offs);
this->ui->spinner_TriggerID->setMinimum(event_offs);
this->ui->spinner_TriggerID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1);
} }
else if (event_group_type == EventGroup::Bg) { else if (event_group_type == Event::Group::Bg) {
scrollTarget = ui->scrollArea_BGs; scrollTarget = ui->scrollArea_BGs;
target = ui->scrollAreaWidgetContents_BGs; target = ui->scrollAreaWidgetContents_BGs;
ui->tabWidget_EventType->setCurrentWidget(ui->tab_BGs); ui->tabWidget_EventType->setCurrentWidget(ui->tab_BGs);
this->ui->spinner_BgID->setValue(current->getEventIndex() + event_offs);
this->ui->spinner_BgID->setMinimum(event_offs);
this->ui->spinner_BgID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1);
} }
else if (event_group_type == EventGroup::Heal) { else if (event_group_type == Event::Group::Heal) {
scrollTarget = ui->scrollArea_Healspots; scrollTarget = ui->scrollArea_Healspots;
target = ui->scrollAreaWidgetContents_Healspots; target = ui->scrollAreaWidgetContents_Healspots;
ui->tabWidget_EventType->setCurrentWidget(ui->tab_Healspots); ui->tabWidget_EventType->setCurrentWidget(ui->tab_Healspots);
this->ui->spinner_HealID->setValue(current->getEventIndex() + event_offs);
this->ui->spinner_HealID->setMinimum(event_offs);
this->ui->spinner_HealID->setMaximum(current->getMap()->events.value(event_group_type).length() + event_offs - 1);
} }
ui->tabWidget_EventType->removeTab(ui->tabWidget_EventType->indexOf(ui->tab_Multiple)); ui->tabWidget_EventType->removeTab(ui->tabWidget_EventType->indexOf(ui->tab_Multiple));
} }
else if (events.length() > 1) else if (events.length() > 1) {
{
ui->tabWidget_EventType->addTab(ui->tab_Multiple, "Multiple"); ui->tabWidget_EventType->addTab(ui->tab_Multiple, "Multiple");
ui->tabWidget_EventType->setCurrentWidget(ui->tab_Multiple); ui->tabWidget_EventType->setCurrentWidget(ui->tab_Multiple);
} }
isProgrammaticEventTabChange = false; isProgrammaticEventTabChange = false;
if (events.length() != 0) QList<EventFrame *> frames;
{ for (DraggablePixmapItem *item : events) {
if (target->children().length()) Event *event = item->event;
{ EventFrame *eventFrame = event->createEventFrame();
for (QObject *obj : target->children()) eventFrame->populate(this->editor->project);
{ eventFrame->initialize();
obj->deleteLater(); eventFrame->setParent(nullptr);
// TODO: hide
eventFrame->connectSignals();
// connect(item, &DraggablePixmapItem::spriteChanged, frame->ui->label_spritePixmap, &QLabel::setPixmap);
frames.append(eventFrame);
}
if (target->layout() && target->children().length()) {
for (QFrame *frame : target->findChildren<EventFrame *>()) {
frame->hide();
} }
delete target->layout(); delete target->layout();
} }
QVBoxLayout *layout = new QVBoxLayout(target); // TODO: clear every layout instead?
// TODO: layout not clearing?
// eg: scrolling through objets to clone object you
// can see previous obj frame below clone frame
// possibly can just set enabled (false) which can hide frame
if (!events.empty()) {
QVBoxLayout *layout = new QVBoxLayout;
target->setLayout(layout); target->setLayout(layout);
scrollTarget->setWidgetResizable(true); scrollTarget->setWidgetResizable(true);
scrollTarget->setWidget(target); scrollTarget->setWidget(target);
for (EventPropertiesFrame *frame : frames) { for (EventFrame *frame : frames) {
frame->show();
layout->addWidget(frame); layout->addWidget(frame);
} }
layout->addStretch(1); layout->addStretch(1);
// doesn't work
//QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
//ui->scrollArea_4->ensureVisible(0, scroll);
ui->label_NoEvents->hide(); ui->label_NoEvents->hide();
ui->tabWidget_EventType->show(); ui->tabWidget_EventType->show();
} }
else else {
{
ui->tabWidget_EventType->hide(); ui->tabWidget_EventType->hide();
ui->label_NoEvents->show(); ui->label_NoEvents->show();
} }
} }
QString MainWindow::getEventGroupFromTabWidget(QWidget *tab) Event::Group MainWindow::getEventGroupFromTabWidget(QWidget *tab)
{ {
QString ret = ""; Event::Group ret = Event::Group::None;
if (tab == eventTabObjectWidget) if (tab == eventTabObjectWidget)
{ {
ret = EventGroup::Object; ret = Event::Group::Object;
} }
else if (tab == eventTabWarpWidget) else if (tab == eventTabWarpWidget)
{ {
ret = EventGroup::Warp; ret = Event::Group::Warp;
} }
else if (tab == eventTabTriggerWidget) else if (tab == eventTabTriggerWidget)
{ {
ret = EventGroup::Coord; ret = Event::Group::Coord;
} }
else if (tab == eventTabBGWidget) else if (tab == eventTabBGWidget)
{ {
ret = EventGroup::Bg; ret = Event::Group::Bg;
} }
else if (tab == eventTabHealspotWidget) else if (tab == eventTabHealspotWidget)
{ {
ret = EventGroup::Heal; ret = Event::Group::Heal;
} }
return ret; return ret;
} }
void MainWindow::eventTabChanged(int index) { void MainWindow::eventTabChanged(int index) {
if (editor->map) { if (editor->map) {
QString group = getEventGroupFromTabWidget(ui->tabWidget_EventType->widget(index)); Event::Group group = getEventGroupFromTabWidget(ui->tabWidget_EventType->widget(index));
DraggablePixmapItem *selectedEvent = nullptr; DraggablePixmapItem *selectedEvent = nullptr;
if (group == EventGroup::Object) { // TODO: use switch
if (group == Event::Group::Object) {
selectedEvent = selectedObject; selectedEvent = selectedObject;
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newObjectAction); ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newObjectAction);
} }
else if (group == EventGroup::Warp) { else if (group == Event::Group::Warp) {
selectedEvent = selectedWarp; selectedEvent = selectedWarp;
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newWarpAction); ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newWarpAction);
} }
else if (group == EventGroup::Coord) { else if (group == Event::Group::Coord) {
selectedEvent = selectedTrigger; selectedEvent = selectedTrigger;
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newTriggerAction); ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newTriggerAction);
} }
else if (group == EventGroup::Bg) { else if (group == Event::Group::Bg) {
selectedEvent = selectedBG; selectedEvent = selectedBG;
ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newSignAction); ui->newEventToolButton->setDefaultAction(ui->newEventToolButton->newSignAction);
} }
else if (group == EventGroup::Heal) { else if (group == Event::Group::Heal) {
selectedEvent = selectedHealspot; selectedEvent = selectedHealspot;
} }
@ -2475,24 +2144,6 @@ void MainWindow::eventTabChanged(int index) {
isProgrammaticEventTabChange = false; isProgrammaticEventTabChange = false;
} }
void MainWindow::selectedEventIndexChanged(int index)
{
QString group = getEventGroupFromTabWidget(ui->tabWidget_EventType->currentWidget());
int event_offs = Event::getIndexOffset(group);
Event *event = editor->map->events.value(group).at(index - event_offs);
DraggablePixmapItem *selectedEvent = nullptr;
for (QGraphicsItem *child : editor->events_group->childItems()) {
DraggablePixmapItem *item = static_cast<DraggablePixmapItem *>(child);
if (item->event == event) {
selectedEvent = item;
break;
}
}
if (selectedEvent != nullptr)
editor->selectMapEvent(selectedEvent);
}
void MainWindow::on_horizontalSlider_CollisionTransparency_valueChanged(int value) { void MainWindow::on_horizontalSlider_CollisionTransparency_valueChanged(int value) {
this->editor->collisionOpacity = static_cast<qreal>(value) / 100; this->editor->collisionOpacity = static_cast<qreal>(value) / 100;
porymapConfig.setCollisionOpacity(value); porymapConfig.setCollisionOpacity(value);
@ -2511,8 +2162,8 @@ void MainWindow::on_toolButton_deleteObject_clicked() {
int numEvents = editor->selected_events->length(); int numEvents = editor->selected_events->length();
int numDeleted = 0; int numDeleted = 0;
for (DraggablePixmapItem *item : *editor->selected_events) { for (DraggablePixmapItem *item : *editor->selected_events) {
QString event_group = item->event->get("event_group_type"); Event::Group event_group = item->event->getEventGroup();
if (event_group != EventGroup::Heal) { if (event_group != Event::Group::Heal) {
// Get the index for the event that should be selected after this event has been deleted. // Get the index for the event that should be selected after this event has been deleted.
// If it's at the end of the list, select the previous event, otherwise select the next one. // If it's at the end of the list, select the previous event, otherwise select the next one.
// Don't bother getting the event to select if there are still more events to delete // Don't bother getting the event to select if there are still more events to delete
@ -2537,7 +2188,7 @@ void MainWindow::on_toolButton_deleteObject_clicked() {
selectedEvents.append(item->event); selectedEvents.append(item->event);
} }
else { // don't allow deletion of heal locations else { // don't allow deletion of heal locations
logWarn(QString("Cannot delete event of type '%1'").arg(item->event->get("event_type"))); logWarn(QString("Cannot delete event of type '%1'").arg(Event::eventTypeToString(item->event->getEventType())));
} }
} }
if (numDeleted) { if (numDeleted) {

View file

@ -211,7 +211,7 @@ bool Project::loadMapData(Map* map) {
map->sharedScriptsMap = mapObj["shared_scripts_map"].toString(); map->sharedScriptsMap = mapObj["shared_scripts_map"].toString();
// Events // Events
map->events[EventGroup::Object].clear(); map->events[Event::Group::Object].clear();
QJsonArray objectEventsArr = mapObj["object_events"].toArray(); QJsonArray objectEventsArr = mapObj["object_events"].toArray();
bool hasCloneObjects = projectConfig.getEventCloneObjectEnabled(); bool hasCloneObjects = projectConfig.getEventCloneObjectEnabled();
for (int i = 0; i < objectEventsArr.size(); i++) { for (int i = 0; i < objectEventsArr.size(); i++) {
@ -219,176 +219,100 @@ bool Project::loadMapData(Map* map) {
// If clone objects are not enabled then no type field is present // If clone objects are not enabled then no type field is present
QString type = hasCloneObjects ? event["type"].toString() : "object"; QString type = hasCloneObjects ? event["type"].toString() : "object";
if (type.isEmpty() || type == "object") { if (type.isEmpty() || type == "object") {
Event *object = new Event(event, EventType::Object); ObjectEvent *object = new ObjectEvent();
object->put("map_name", map->name); object->loadFromJson(event, this);
object->put("sprite", event["graphics_id"].toString()); map->addEvent(object);
object->put("x", QString::number(event["x"].toInt()));
object->put("y", QString::number(event["y"].toInt()));
object->put("elevation", QString::number(event["elevation"].toInt()));
object->put("movement_type", event["movement_type"].toString());
object->put("radius_x", QString::number(event["movement_range_x"].toInt()));
object->put("radius_y", QString::number(event["movement_range_y"].toInt()));
object->put("trainer_type", event["trainer_type"].toString());
object->put("sight_radius_tree_id", event["trainer_sight_or_berry_tree_id"].toString());
object->put("script_label", event["script"].toString());
object->put("event_flag", event["flag"].toString());
object->put("event_group_type", EventGroup::Object);
map->events[EventGroup::Object].append(object);
} else if (type == "clone") { } else if (type == "clone") {
Event *object = new Event(event, EventType::CloneObject); CloneObjectEvent *clone = new CloneObjectEvent();
object->put("map_name", map->name); if (clone->loadFromJson(event, this)) {
object->put("sprite", event["graphics_id"].toString()); map->addEvent(clone);
object->put("x", QString::number(event["x"].toInt())); }
object->put("y", QString::number(event["y"].toInt())); else {
object->put("target_local_id", QString::number(event["target_local_id"].toInt())); delete clone;
// Ensure the target map constant is valid before adding it to the events.
QString mapConstant = event["target_map"].toString();
if (mapConstantsToMapNames.contains(mapConstant)) {
object->put("target_map", mapConstantsToMapNames.value(mapConstant));
object->put("event_group_type", EventGroup::Object);
map->events[EventGroup::Object].append(object);
} else if (mapConstant == NONE_MAP_CONSTANT) {
object->put("target_map", NONE_MAP_NAME);
object->put("event_group_type", EventGroup::Object);
map->events[EventGroup::Object].append(object);
} else {
logError(QString("Destination map constant '%1' is invalid").arg(mapConstant));
} }
} else { } else {
logError(QString("Map %1 object_event %2 has invalid type '%3'. Must be 'object' or 'clone'.").arg(map->name).arg(i).arg(type)); logError(QString("Map %1 object_event %2 has invalid type '%3'. Must be 'object' or 'clone'.").arg(map->name).arg(i).arg(type));
} }
} }
map->events[EventGroup::Warp].clear(); map->events[Event::Group::Warp].clear();
QJsonArray warpEventsArr = mapObj["warp_events"].toArray(); QJsonArray warpEventsArr = mapObj["warp_events"].toArray();
for (int i = 0; i < warpEventsArr.size(); i++) { for (int i = 0; i < warpEventsArr.size(); i++) {
QJsonObject event = warpEventsArr[i].toObject(); QJsonObject event = warpEventsArr[i].toObject();
Event *warp = new Event(event, EventType::Warp); WarpEvent *warp = new WarpEvent();
warp->put("map_name", map->name); if (warp->loadFromJson(event, this)) {
warp->put("x", QString::number(event["x"].toInt())); map->addEvent(warp);
warp->put("y", QString::number(event["y"].toInt())); }
warp->put("elevation", QString::number(event["elevation"].toInt())); else {
warp->put("destination_warp", QString::number(event["dest_warp_id"].toInt())); delete warp;
// Ensure the warp destination map constant is valid before adding it to the warps.
QString mapConstant = event["dest_map"].toString();
if (mapConstantsToMapNames.contains(mapConstant)) {
warp->put("destination_map_name", mapConstantsToMapNames.value(mapConstant));
warp->put("event_group_type", EventGroup::Warp);
map->events[EventGroup::Warp].append(warp);
} else if (mapConstant == NONE_MAP_CONSTANT) {
warp->put("destination_map_name", NONE_MAP_NAME);
warp->put("event_group_type", EventGroup::Warp);
map->events[EventGroup::Warp].append(warp);
} else {
logError(QString("Destination map constant '%1' is invalid for warp").arg(mapConstant));
} }
} }
map->events[EventGroup::Heal].clear(); map->events[Event::Group::Coord].clear();
for (auto it = healLocations.begin(); it != healLocations.end(); it++) {
HealLocation loc = *it;
//if TRUE map is flyable / has healing location
if (loc.mapName == QString(mapNamesToMapConstants.value(map->name)).remove(0,4)) {
Event *heal = new Event;
heal->put("map_name", map->name);
heal->put("x", loc.x);
heal->put("y", loc.y);
heal->put("loc_name", loc.mapName);
heal->put("id_name", loc.idName);
heal->put("index", loc.index);
heal->put("elevation", 3); // TODO: change this?
heal->put("destination_map_name", mapConstantsToMapNames.value(map->name));
heal->put("event_group_type", EventGroup::Heal);
heal->put("event_type", EventType::HealLocation);
if (projectConfig.getHealLocationRespawnDataEnabled()) {
heal->put("respawn_map", mapConstantsToMapNames.value(QString("MAP_" + loc.respawnMap)));
heal->put("respawn_npc", loc.respawnNPC);
}
map->events[EventGroup::Heal].append(heal);
}
}
map->events[EventGroup::Coord].clear();
QJsonArray coordEventsArr = mapObj["coord_events"].toArray(); QJsonArray coordEventsArr = mapObj["coord_events"].toArray();
for (int i = 0; i < coordEventsArr.size(); i++) { for (int i = 0; i < coordEventsArr.size(); i++) {
QJsonObject event = coordEventsArr[i].toObject(); QJsonObject event = coordEventsArr[i].toObject();
QString type = event["type"].toString(); QString type = event["type"].toString();
if (type == "trigger") { if (type == "trigger") {
Event *coord = new Event(event, EventType::Trigger); TriggerEvent *coord = new TriggerEvent();
coord->put("map_name", map->name); coord->loadFromJson(event, this);
coord->put("x", QString::number(event["x"].toInt())); map->addEvent(coord);
coord->put("y", QString::number(event["y"].toInt()));
coord->put("elevation", QString::number(event["elevation"].toInt()));
coord->put("script_var", event["var"].toString());
coord->put("script_var_value", event["var_value"].toString());
coord->put("script_label", event["script"].toString());
coord->put("event_group_type", EventGroup::Coord);
map->events[EventGroup::Coord].append(coord);
} else if (type == "weather") { } else if (type == "weather") {
Event *coord = new Event(event, EventType::WeatherTrigger); WeatherTriggerEvent *coord = new WeatherTriggerEvent();
coord->put("map_name", map->name); coord->loadFromJson(event, this);
coord->put("x", QString::number(event["x"].toInt())); map->addEvent(coord);
coord->put("y", QString::number(event["y"].toInt()));
coord->put("elevation", QString::number(event["elevation"].toInt()));
coord->put("weather", event["weather"].toString());
coord->put("event_group_type", EventGroup::Coord);
coord->put("event_type", EventType::WeatherTrigger);
map->events[EventGroup::Coord].append(coord);
} else { } else {
logError(QString("Map %1 coord_event %2 has invalid type '%3'. Must be 'trigger' or 'weather'.").arg(map->name).arg(i).arg(type)); logError(QString("Map %1 coord_event %2 has invalid type '%3'. Must be 'trigger' or 'weather'.").arg(map->name).arg(i).arg(type));
} }
} }
map->events[EventGroup::Bg].clear(); map->events[Event::Group::Bg].clear();
QJsonArray bgEventsArr = mapObj["bg_events"].toArray(); QJsonArray bgEventsArr = mapObj["bg_events"].toArray();
for (int i = 0; i < bgEventsArr.size(); i++) { for (int i = 0; i < bgEventsArr.size(); i++) {
QJsonObject event = bgEventsArr[i].toObject(); QJsonObject event = bgEventsArr[i].toObject();
QString type = event["type"].toString(); QString type = event["type"].toString();
if (type == "sign") { if (type == "sign") {
Event *bg = new Event(event, EventType::Sign); SignEvent *bg = new SignEvent();
bg->put("map_name", map->name); bg->loadFromJson(event, this);
bg->put("x", QString::number(event["x"].toInt())); map->addEvent(bg);
bg->put("y", QString::number(event["y"].toInt()));
bg->put("elevation", QString::number(event["elevation"].toInt()));
bg->put("player_facing_direction", event["player_facing_dir"].toString());
bg->put("script_label", event["script"].toString());
bg->put("event_group_type", EventGroup::Bg);
map->events[EventGroup::Bg].append(bg);
} else if (type == "hidden_item") { } else if (type == "hidden_item") {
Event *bg = new Event(event, EventType::HiddenItem); HiddenItemEvent *bg = new HiddenItemEvent();
bg->put("map_name", map->name); bg->loadFromJson(event, this);
bg->put("x", QString::number(event["x"].toInt())); map->addEvent(bg);
bg->put("y", QString::number(event["y"].toInt()));
bg->put("elevation", QString::number(event["elevation"].toInt()));
bg->put("item", event["item"].toString());
bg->put("flag", event["flag"].toString());
if (projectConfig.getHiddenItemQuantityEnabled()) {
bg->put("quantity", event["quantity"].toInt());
}
if (projectConfig.getHiddenItemRequiresItemfinderEnabled()) {
bg->put("underfoot", event["underfoot"].toBool());
}
bg->put("event_group_type", EventGroup::Bg);
map->events[EventGroup::Bg].append(bg);
} else if (type == "secret_base") { } else if (type == "secret_base") {
Event *bg = new Event(event, EventType::SecretBase); SecretBaseEvent *bg = new SecretBaseEvent();
bg->put("map_name", map->name); bg->loadFromJson(event, this);
bg->put("x", QString::number(event["x"].toInt())); map->addEvent(bg);
bg->put("y", QString::number(event["y"].toInt()));
bg->put("elevation", QString::number(event["elevation"].toInt()));
bg->put("secret_base_id", event["secret_base_id"].toString());
bg->put("event_group_type", EventGroup::Bg);
map->events[EventGroup::Bg].append(bg);
} else { } else {
logError(QString("Map %1 bg_event %2 has invalid type '%3'. Must be 'sign', 'hidden_item', or 'secret_base'.").arg(map->name).arg(i).arg(type)); logError(QString("Map %1 bg_event %2 has invalid type '%3'. Must be 'sign', 'hidden_item', or 'secret_base'.").arg(map->name).arg(i).arg(type));
} }
} }
map->events[Event::Group::Heal].clear();
for (auto it = healLocations.begin(); it != healLocations.end(); it++) {
HealLocation loc = *it;
//if TRUE map is flyable / has healing location
if (loc.mapName == QString(mapNamesToMapConstants.value(map->name)).remove(0,4)) {
HealLocationEvent *heal = new HealLocationEvent();
heal->setMap(map);
heal->setX(loc.x);
heal->setY(loc.y);
heal->setElevation(3);
heal->setLocationName(loc.mapName);
heal->setIdName(loc.idName);
heal->setIndex(loc.index);
// TODO: what is this
// heal->put("destination_map_name", mapConstantsToMapNames.value(map->name));
if (projectConfig.getHealLocationRespawnDataEnabled()) {
heal->setRespawnMap(mapConstantsToMapNames.value(QString("MAP_" + loc.respawnMap)));
heal->setRespawnNPC(loc.respawnNPC);
}
map->events[Event::Group::Heal].append(heal);
}
}
map->connections.clear(); map->connections.clear();
QJsonArray connectionsArr = mapObj["connections"].toArray(); QJsonArray connectionsArr = mapObj["connections"].toArray();
if (!connectionsArr.isEmpty()) { if (!connectionsArr.isEmpty()) {
@ -887,8 +811,8 @@ void Project::saveHealLocationStruct(Map *map) {
} }
// set new location in healLocations list // set new location in healLocations list
if (map->events[EventGroup::Heal].length() > 0) { if (map->events[Event::Group::Heal].length() > 0) {
for (Event *healEvent : map->events[EventGroup::Heal]) { for (Event *healEvent : map->events[Event::Group::Heal]) {
HealLocation hl = HealLocation::fromEvent(healEvent); HealLocation hl = HealLocation::fromEvent(healEvent);
healLocations[hl.index - 1] = hl; healLocations[hl.index - 1] = hl;
} }
@ -1361,9 +1285,9 @@ void Project::saveMap(Map *map) {
for (MapConnection* connection : map->connections) { for (MapConnection* connection : map->connections) {
if (mapNamesToMapConstants.contains(connection->map_name)) { if (mapNamesToMapConstants.contains(connection->map_name)) {
OrderedJson::object connectionObj; OrderedJson::object connectionObj;
connectionObj["direction"] = connection->direction;
connectionObj["offset"] = connection->offset.toInt();
connectionObj["map"] = this->mapNamesToMapConstants.value(connection->map_name); connectionObj["map"] = this->mapNamesToMapConstants.value(connection->map_name);
connectionObj["offset"] = connection->offset.toInt();
connectionObj["direction"] = connection->direction;
connectionsArr.append(connectionObj); connectionsArr.append(connectionObj);
} else { } else {
logError(QString("Failed to write map connection. '%1' is not a valid map name").arg(connection->map_name)); logError(QString("Failed to write map connection. '%1' is not a valid map name").arg(connection->map_name));
@ -1377,58 +1301,38 @@ void Project::saveMap(Map *map) {
if (map->sharedEventsMap.isEmpty()) { if (map->sharedEventsMap.isEmpty()) {
// Object events // Object events
OrderedJson::array objectEventsArr; OrderedJson::array objectEventsArr;
for (int i = 0; i < map->events[EventGroup::Object].length(); i++) { for (int i = 0; i < map->events[Event::Group::Object].length(); i++) {
Event *event = map->events[EventGroup::Object].value(i); Event *event = map->events[Event::Group::Object].value(i);
QString event_type = event->get("event_type"); OrderedJson::object jsonObj = event->buildEventJson(this);
OrderedJson::object jsonObj;
if (event_type == EventType::Object) {
jsonObj = event->buildObjectEventJSON();
} else if (event_type == EventType::CloneObject) {
jsonObj = event->buildCloneObjectEventJSON(mapNamesToMapConstants);
}
objectEventsArr.push_back(jsonObj); objectEventsArr.push_back(jsonObj);
} }
mapObj["object_events"] = objectEventsArr; mapObj["object_events"] = objectEventsArr;
// Warp events // Warp events
OrderedJson::array warpEventsArr; OrderedJson::array warpEventsArr;
for (int i = 0; i < map->events[EventGroup::Warp].length(); i++) { for (int i = 0; i < map->events[Event::Group::Warp].length(); i++) {
Event *warp_event = map->events[EventGroup::Warp].value(i); Event *event = map->events[Event::Group::Warp].value(i);
OrderedJson::object warpObj = warp_event->buildWarpEventJSON(mapNamesToMapConstants); OrderedJson::object warpObj = event->buildEventJson(this);
warpEventsArr.append(warpObj); warpEventsArr.append(warpObj);
} }
mapObj["warp_events"] = warpEventsArr; mapObj["warp_events"] = warpEventsArr;
// Coord events // Coord events
OrderedJson::array coordEventsArr; OrderedJson::array coordEventsArr;
for (int i = 0; i < map->events[EventGroup::Coord].length(); i++) { for (int i = 0; i < map->events[Event::Group::Coord].length(); i++) {
Event *event = map->events[EventGroup::Coord].value(i); Event *event = map->events[Event::Group::Coord].value(i);
QString event_type = event->get("event_type"); OrderedJson::object triggerObj = event->buildEventJson(this);
if (event_type == EventType::Trigger) {
OrderedJson::object triggerObj = event->buildTriggerEventJSON();
coordEventsArr.append(triggerObj); coordEventsArr.append(triggerObj);
} else if (event_type == EventType::WeatherTrigger) {
OrderedJson::object weatherObj = event->buildWeatherTriggerEventJSON();
coordEventsArr.append(weatherObj);
}
} }
mapObj["coord_events"] = coordEventsArr; mapObj["coord_events"] = coordEventsArr;
// Bg Events // Bg Events
OrderedJson::array bgEventsArr; OrderedJson::array bgEventsArr;
for (int i = 0; i < map->events[EventGroup::Bg].length(); i++) { for (int i = 0; i < map->events[Event::Group::Bg].length(); i++) {
Event *event = map->events[EventGroup::Bg].value(i); Event *event = map->events[Event::Group::Bg].value(i);
QString event_type = event->get("event_type"); OrderedJson::object bgObj = event->buildEventJson(this);
if (event_type == EventType::Sign) { bgEventsArr.append(bgObj);
OrderedJson::object signObj = event->buildSignEventJSON();
bgEventsArr.append(signObj);
} else if (event_type == EventType::HiddenItem) {
OrderedJson::object hiddenItemObj = event->buildHiddenItemEventJSON();
bgEventsArr.append(hiddenItemObj);
} else if (event_type == EventType::SecretBase) {
OrderedJson::object secretBaseObj = event->buildSecretBaseEventJSON();
bgEventsArr.append(secretBaseObj);
}
} }
mapObj["bg_events"] = bgEventsArr; mapObj["bg_events"] = bgEventsArr;
} else { } else {
@ -2379,6 +2283,10 @@ bool Project::readMiscellaneousConstants() {
return true; return true;
} }
QStringList Project::getGlobalScriptLabels() {
return this->eventScriptLabelModel.stringList();
}
bool Project::readEventScriptLabels() { bool Project::readEventScriptLabels() {
for (const auto &filePath : getEventScriptsFilePaths()) for (const auto &filePath : getEventScriptsFilePaths())
globalScriptLabels << ParseUtil::getGlobalScriptLabels(filePath); globalScriptLabels << ParseUtil::getGlobalScriptLabels(filePath);
@ -2461,58 +2369,9 @@ QCompleter *Project::getEventScriptLabelCompleter(QStringList additionalScriptLa
return &eventScriptLabelCompleter; return &eventScriptLabelCompleter;
} }
void Project::setEventPixmap(Event * event, bool forceLoad) { void Project::setEventPixmap(Event *event, bool forceLoad) {
if (!event || (!event->pixmap.isNull() && !forceLoad)) if (event && (event->getPixmap().isNull() || forceLoad))
return; event->loadPixmap(this);
event->spriteWidth = 16;
event->spriteHeight = 16;
event->usingSprite = false;
QString group_type = event->get("event_group_type");
if (group_type == EventGroup::Object) {
QString gfxName;
QString movement;
QString event_type = event->get("event_type");
if (event_type == EventType::CloneObject) {
// Try to get the targeted object to clone
int eventIndex = event->getInt("target_local_id") - 1;
Map * clonedMap = getMap(event->get("target_map"));
Event * clonedEvent = clonedMap ? clonedMap->events[EventGroup::Object].value(eventIndex, nullptr) : nullptr;
if (clonedEvent && clonedEvent->get("event_type") == EventType::Object) {
// Get graphics data from cloned object
gfxName = clonedEvent->get("sprite");
movement = clonedEvent->get("movement_type");
} else {
// Invalid object specified, use default graphics data (as would be shown in-game)
gfxName = gfxDefines.key(0);
movement = movementTypes.first();
}
// Update clone object's sprite text to match target object
event->put("sprite", gfxName);
} else {
// Get graphics data of regular object
gfxName = event->get("sprite");
movement = event->get("movement_type");
}
EventGraphics * eventGfx = eventGraphicsMap.value(gfxName, nullptr);
if (!eventGfx || eventGfx->spritesheet.isNull()) {
// No sprite associated with this gfx constant.
// Use default sprite instead.
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(0, 0, 16, 16);
} else {
event->setFrameFromMovement(facingDirections.value(movement));
event->setPixmapFromSpritesheet(eventGfx->spritesheet, eventGfx->spriteWidth, eventGfx->spriteHeight, eventGfx->inanimate);
}
} else if (group_type == EventGroup::Warp) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(16, 0, 16, 16);
} else if (group_type == EventGroup::Coord) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(32, 0, 16, 16);
} else if (group_type == EventGroup::Bg) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(48, 0, 16, 16);
} else if (group_type == EventGroup::Heal) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(64, 0, 16, 16);
}
} }
bool Project::readEventGraphics() { bool Project::readEventGraphics() {
@ -2601,8 +2460,8 @@ bool Project::readSpeciesIconPaths() {
void Project::saveMapHealEvents(Map *map) { void Project::saveMapHealEvents(Map *map) {
// save heal event changes // save heal event changes
if (map->events[EventGroup::Heal].length() > 0) { if (map->events[Event::Group::Heal].length() > 0) {
for (Event *healEvent : map->events[EventGroup::Heal]) { for (Event *healEvent : map->events[Event::Group::Heal]) {
HealLocation hl = HealLocation::fromEvent(healEvent); HealLocation hl = HealLocation::fromEvent(healEvent);
healLocations[hl.index - 1] = hl; healLocations[hl.index - 1] = hl;
} }
@ -2611,11 +2470,11 @@ void Project::saveMapHealEvents(Map *map) {
} }
void Project::setNewMapEvents(Map *map) { void Project::setNewMapEvents(Map *map) {
map->events[EventGroup::Object].clear(); map->events[Event::Group::Object].clear();
map->events[EventGroup::Warp].clear(); map->events[Event::Group::Warp].clear();
map->events[EventGroup::Heal].clear(); map->events[Event::Group::Heal].clear();
map->events[EventGroup::Coord].clear(); map->events[Event::Group::Coord].clear();
map->events[EventGroup::Bg].clear(); map->events[Event::Group::Bg].clear();
} }
int Project::getNumTilesPrimary() int Project::getNumTilesPrimary()

View file

@ -33,7 +33,8 @@ CustomAttributesTable::CustomAttributesTable(Event *event, QWidget *parent) :
this->table->horizontalHeader()->setStretchLastSection(true); this->table->horizontalHeader()->setStretchLastSection(true);
layout->addWidget(this->table); layout->addWidget(this->table);
for (auto it = event->customValues.begin(); it != event->customValues.end(); it++) { QMap<QString, QString> customValues = this->event->getCustomValues();
for (auto it = customValues.begin(); it != customValues.end(); it++) {
int rowIndex = this->table->rowCount(); int rowIndex = this->table->rowCount();
this->table->insertRow(rowIndex); this->table->insertRow(rowIndex);
this->table->setItem(rowIndex, 0, new QTableWidgetItem(it.key())); this->table->setItem(rowIndex, 0, new QTableWidgetItem(it.key()));
@ -44,7 +45,7 @@ CustomAttributesTable::CustomAttributesTable(Event *event, QWidget *parent) :
int rowIndex = this->table->rowCount(); int rowIndex = this->table->rowCount();
this->table->insertRow(rowIndex); this->table->insertRow(rowIndex);
this->table->selectRow(rowIndex); this->table->selectRow(rowIndex);
this->event->customValues = this->getTableFields(); this->event->setCustomValues(this->getTableFields());
this->resizeVertically(); this->resizeVertically();
}); });
@ -66,13 +67,13 @@ CustomAttributesTable::CustomAttributesTable(Event *event, QWidget *parent) :
this->table->selectRow(0); this->table->selectRow(0);
} }
this->event->customValues = this->getTableFields(); this->event->setCustomValues(this->getTableFields());
this->resizeVertically(); this->resizeVertically();
} }
}); });
connect(this->table, &QTableWidget::cellChanged, [=]() { connect(this->table, &QTableWidget::cellChanged, [=]() {
this->event->customValues = this->getTableFields(); this->event->setCustomValues(this->getTableFields());
}); });
this->resizeVertically(); this->resizeVertically();

View file

@ -13,44 +13,23 @@ void DraggablePixmapItem::updatePosition() {
setX(x); setX(x);
setY(y); setY(y);
if (editor->selected_events && editor->selected_events->contains(this)) { if (editor->selected_events && editor->selected_events->contains(this)) {
setZValue(event->y() + 1); setZValue(event->getY() + 1);
} else { } else {
setZValue(event->y()); setZValue(event->getY());
} }
} }
void DraggablePixmapItem::emitPositionChanged() { void DraggablePixmapItem::emitPositionChanged() {
emit xChanged(event->x()); emit xChanged(event->getX());
emit yChanged(event->y()); emit yChanged(event->getY());
emit elevationChanged(event->elevation()); emit elevationChanged(event->getElevation());
} }
void DraggablePixmapItem::updatePixmap() { void DraggablePixmapItem::updatePixmap() {
editor->project->setEventPixmap(event, true); editor->project->setEventPixmap(event, true);
this->updatePosition(); this->updatePosition();
editor->redrawObject(this); editor->redrawObject(this);
emit spriteChanged(event->pixmap); emit spriteChanged(event->getPixmap());
}
void DraggablePixmapItem::bind(QComboBox *combo, QString key) {
connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged),
this, [this, key](QString value){
this->event->put(key, value);
});
connect(this, &DraggablePixmapItem::onPropertyChanged,
this, [combo, key](QString key2, QString value){
if (key2 == key) {
combo->addItem(value);
combo->setCurrentText(value);
}
});
}
void DraggablePixmapItem::bindToUserData(QComboBox *combo, QString key) {
connect(combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, [this, combo, key](int index) {
this->event->put(key, combo->itemData(index).toString());
});
} }
void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) {
@ -63,8 +42,8 @@ void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) {
} }
void DraggablePixmapItem::move(int dx, int dy) { void DraggablePixmapItem::move(int dx, int dy) {
event->setX(event->x() + dx); event->setX(event->getX() + dx);
event->setY(event->y() + dy); event->setY(event->getY() + dy);
updatePosition(); updatePosition();
emitPositionChanged(); emitPositionChanged();
} }
@ -102,24 +81,27 @@ void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) {
} }
void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) { void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
QString eventType = this->event->get("event_type"); Event::Type eventType = this->event->getEventType();
if (eventType == EventType::Warp) { if (eventType == Event::Type::Warp) {
QString destMap = this->event->get("destination_map_name"); WarpEvent *warp = dynamic_cast<WarpEvent *>(this->event);
QString destMap = warp->getDestinationMap();
if (destMap != NONE_MAP_NAME) { if (destMap != NONE_MAP_NAME) {
emit editor->warpEventDoubleClicked(destMap, this->event->get("destination_warp"), EventGroup::Warp); emit editor->warpEventDoubleClicked(destMap, warp->getDestinationWarpID(), Event::Group::Warp);
} }
} }
else if (eventType == EventType::CloneObject) { else if (eventType == Event::Type::CloneObject) {
QString destMap = this->event->get("target_map"); CloneObjectEvent *clone = dynamic_cast<CloneObjectEvent *>(this->event);
QString destMap = clone->getTargetMap();
if (destMap != NONE_MAP_NAME) { if (destMap != NONE_MAP_NAME) {
emit editor->warpEventDoubleClicked(destMap, this->event->get("target_local_id"), EventGroup::Object); emit editor->warpEventDoubleClicked(destMap, clone->getTargetID(), Event::Group::Object);
} }
} }
else if (eventType == EventType::SecretBase) { else if (eventType == Event::Type::SecretBase) {
QString baseId = this->event->get("secret_base_id"); SecretBaseEvent *base = dynamic_cast<SecretBaseEvent *>(this->event);
QString baseId = base->getBaseID();
QString destMap = editor->project->mapConstantsToMapNames.value("MAP_" + baseId.left(baseId.lastIndexOf("_"))); QString destMap = editor->project->mapConstantsToMapNames.value("MAP_" + baseId.left(baseId.lastIndexOf("_")));
if (destMap != NONE_MAP_NAME) { if (destMap != NONE_MAP_NAME) {
emit editor->warpEventDoubleClicked(destMap, "0", EventGroup::Warp); emit editor->warpEventDoubleClicked(destMap, 0, Event::Group::Warp);
} }
} }
} }

1054
src/ui/eventframes.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,28 +0,0 @@
#include "eventpropertiesframe.h"
#include "customattributestable.h"
#include "ui_eventpropertiesframe.h"
EventPropertiesFrame::EventPropertiesFrame(Event *event, QWidget *parent) :
QFrame(parent),
ui(new Ui::EventPropertiesFrame)
{
ui->setupUi(this);
this->event = event;
this->firstShow = true;
}
EventPropertiesFrame::~EventPropertiesFrame()
{
delete ui;
}
void EventPropertiesFrame::paintEvent(QPaintEvent *painter) {
// Custom fields table.
if (firstShow && event->get("event_type") != EventType::HealLocation) {
CustomAttributesTable *customAttributes = new CustomAttributesTable(event, this);
this->layout()->addWidget(customAttributes);
}
QFrame::paintEvent(painter);
firstShow = false;
}

View file

@ -365,21 +365,6 @@ QPixmap MapImageExporter::getFormattedMapPixmap(Map *map, bool ignoreBorder) {
pixmap = map->pixmap; pixmap = map->pixmap;
} }
// draw events
QPainter eventPainter(&pixmap);
QList<Event*> events = map->getAllEvents();
for (Event *event : events) {
editor->project->setEventPixmap(event);
QString group = event->get("event_group_type");
if ((showObjects && group == EventGroup::Object)
|| (showWarps && group == EventGroup::Warp)
|| (showBGs && group == EventGroup::Bg)
|| (showTriggers && group == EventGroup::Coord)
|| (showHealSpots && group == EventGroup::Heal))
eventPainter.drawImage(QPoint(event->getPixelX(), event->getPixelY()), event->pixmap.toImage());
}
eventPainter.end();
// draw map border // draw map border
// note: this will break when allowing map to be selected from drop down maybe // note: this will break when allowing map to be selected from drop down maybe
int borderHeight = 0, borderWidth = 0; int borderHeight = 0, borderWidth = 0;
@ -419,6 +404,21 @@ QPixmap MapImageExporter::getFormattedMapPixmap(Map *map, bool ignoreBorder) {
connectionPainter.end(); connectionPainter.end();
} }
// draw events
QPainter eventPainter(&pixmap);
QList<Event *> events = map->getAllEvents();
for (Event *event : events) {
editor->project->setEventPixmap(event);
Event::Group group = event->getEventGroup();
if ((showObjects && group == Event::Group::Object)
|| (showWarps && group == Event::Group::Warp)
|| (showBGs && group == Event::Group::Bg)
|| (showTriggers && group == Event::Group::Coord)
|| (showHealSpots && group == Event::Group::Heal))
eventPainter.drawImage(QPoint(event->getPixelX(), event->getPixelY()), event->getPixmap().toImage());
}
eventPainter.end();
// draw grid directly onto the pixmap // draw grid directly onto the pixmap
// since the last grid lines are outside of the pixmap, add a pixel to the bottom and right // since the last grid lines are outside of the pixmap, add a pixel to the bottom and right
if (showGrid) { if (showGrid) {

View file

@ -66,61 +66,61 @@ void NewEventToolButton::init()
this->setDefaultAction(this->newObjectAction); this->setDefaultAction(this->newObjectAction);
} }
QString NewEventToolButton::getSelectedEventType() Event::Type NewEventToolButton::getSelectedEventType()
{ {
return this->selectedEventType; return this->selectedEventType;
} }
void NewEventToolButton::newObject() void NewEventToolButton::newObject()
{ {
this->selectedEventType = EventType::Object; this->selectedEventType = Event::Type::Object;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newCloneObject() void NewEventToolButton::newCloneObject()
{ {
this->selectedEventType = EventType::CloneObject; this->selectedEventType = Event::Type::CloneObject;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newWarp() void NewEventToolButton::newWarp()
{ {
this->selectedEventType = EventType::Warp; this->selectedEventType = Event::Type::Warp;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newHealLocation() void NewEventToolButton::newHealLocation()
{ {
this->selectedEventType = EventType::HealLocation; this->selectedEventType = Event::Type::HealLocation;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newTrigger() void NewEventToolButton::newTrigger()
{ {
this->selectedEventType = EventType::Trigger; this->selectedEventType = Event::Type::Trigger;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newWeatherTrigger() void NewEventToolButton::newWeatherTrigger()
{ {
this->selectedEventType = EventType::WeatherTrigger; this->selectedEventType = Event::Type::WeatherTrigger;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newSign() void NewEventToolButton::newSign()
{ {
this->selectedEventType = EventType::Sign; this->selectedEventType = Event::Type::Sign;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newHiddenItem() void NewEventToolButton::newHiddenItem()
{ {
this->selectedEventType = EventType::HiddenItem; this->selectedEventType = Event::Type::HiddenItem;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }
void NewEventToolButton::newSecretBase() void NewEventToolButton::newSecretBase()
{ {
this->selectedEventType = EventType::SecretBase; this->selectedEventType = Event::Type::SecretBase;
emit newEventAdded(this->selectedEventType); emit newEventAdded(this->selectedEventType);
} }

View file

@ -1,5 +1,4 @@
#include "newmappopup.h" #include "newmappopup.h"
#include "event.h"
#include "maplayout.h" #include "maplayout.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "ui_newmappopup.h" #include "ui_newmappopup.h"