Merge pull request #447 from garakmon/and-i-oop--

Internal Event Rewrite
This commit is contained in:
Marcus Huderle 2022-10-17 17:41:00 -07:00 committed by GitHub
commit f5c050828e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 3858 additions and 1727 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">
@ -1387,7 +1387,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>330</width> <width>0</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -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">
@ -1423,11 +1413,14 @@
</size> </size>
</property> </property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
@ -1522,8 +1515,24 @@
</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="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>0</number>
</property> </property>
@ -1544,8 +1553,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 +1615,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 +1647,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 +1709,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 +1741,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 +1803,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 +1835,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 +1903,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 +1935,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 +1997,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 +2037,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 +2051,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 +2942,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

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

@ -0,0 +1,658 @@
#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 except 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; }
void modify();
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);
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);
// 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 {
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 *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;
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);
@ -104,9 +107,7 @@ public:
bool hasUnsavedChanges(); bool hasUnsavedChanges();
bool isWithinBounds(int x, int y); bool isWithinBounds(int x, int y);
bool isWithinBorderBounds(int x, int y); bool isWithinBorderBounds(int x, int y);
void openScript(QString label);
// for memory management
QVector<Event *> ownedEvents;
MapPixmapItem *mapItem = nullptr; MapPixmapItem *mapItem = nullptr;
void setMapItem(MapPixmapItem *item) { mapItem = item; } void setMapItem(MapPixmapItem *item) { mapItem = item; }
@ -118,6 +119,8 @@ public:
void setBorderItem(BorderMetatilesPixmapItem *item) { borderItem = item; } void setBorderItem(BorderMetatilesPixmapItem *item) { borderItem = item; }
QUndoStack editHistory; QUndoStack editHistory;
void modify();
void clean();
private: private:
void setNewDimensionsBlockdata(int newWidth, int newHeight); void setNewDimensionsBlockdata(int newWidth, int newHeight);
@ -125,8 +128,10 @@ private:
signals: signals:
void mapChanged(Map *map); void mapChanged(Map *map);
void modified();
void mapDimensionsChanged(const QSize &size); void mapDimensionsChanged(const QSize &size);
void mapNeedsRedrawing(); void mapNeedsRedrawing();
void openScriptRequested(QString label);
}; };
#endif // MAP_H #endif // MAP_H

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,8 +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 updateSelectedEvents(); void updateSelectedEvents();
void duplicateSelectedEvents(); void duplicateSelectedEvents();
void redrawObject(DraggablePixmapItem *item); void redrawObject(DraggablePixmapItem *item);
@ -105,6 +104,8 @@ public:
void updateCursorRectPos(int x, int y); void updateCursorRectPos(int x, int y);
void setCursorRectVisible(bool visible); void setCursorRectVisible(bool visible);
bool eventLimitReached(Map *, Event::Type);
QGraphicsScene *scene = nullptr; QGraphicsScene *scene = nullptr;
QGraphicsPixmapItem *current_view = nullptr; QGraphicsPixmapItem *current_view = nullptr;
MapPixmapItem *map_item = nullptr; MapPixmapItem *map_item = nullptr;
@ -131,8 +132,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 +151,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 +159,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);
@ -207,10 +208,9 @@ private slots:
signals: signals:
void objectsChanged(); void objectsChanged();
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

@ -104,8 +104,8 @@ public:
Json(double value); // NUMBER Json(double value); // NUMBER
Json(int value); // NUMBER Json(int value); // NUMBER
Json(bool value); // BOOL Json(bool value); // BOOL
Json(const QString &value); // STRING Json(const QString &value); // STRING
Json(QString &&value); // STRING Json(QString &&value); // STRING
Json(const char * value); // STRING Json(const char * value); // STRING
Json(const array &values); // ARRAY Json(const array &values); // ARRAY
Json(array &&values); // ARRAY Json(array &&values); // ARRAY

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,8 @@ private slots:
void on_toolButton_deleteObject_clicked(); void on_toolButton_deleteObject_clicked();
void addNewEvent(QString); void addNewEvent(Event::Type type);
void displayEventTabs();
void updateSelectedObjects(); void updateSelectedObjects();
void updateObjects(); void updateObjects();
@ -265,8 +268,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();
@ -325,8 +326,6 @@ private:
DraggablePixmapItem *selectedBG; DraggablePixmapItem *selectedBG;
DraggablePixmapItem *selectedHealspot; DraggablePixmapItem *selectedHealspot;
QVector<QToolButton *> openScriptButtons;
bool isProgrammaticEventTabChange; bool isProgrammaticEventTabChange;
bool projectHasUnsavedChanges; bool projectHasUnsavedChanges;
bool projectOpenFailure = false; bool projectOpenFailure = false;
@ -374,7 +373,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*);

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

@ -0,0 +1,291 @@
#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);
void invalidateConnections();
void invalidateUi();
void invalidateValues();
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 *hideable_label_z;
QLabel *label_icon;
QFrame *frame_contents;
QVBoxLayout *layout_contents;
protected:
bool populated = false;
bool initialized = false;
bool connected = 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;
QToolButton *button_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 ~TriggerFrame() {
delete this->scriptCompleter;
}
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 ~SignFrame() {
delete this->scriptCompleter;
}
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:
QFrame *hideable_quantity;
QFrame *hideable_itemfinder;
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:
QFrame *hideable_respawn_map;
QFrame *hideable_respawn_npc;
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());
}

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

@ -0,0 +1,895 @@
#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 (this->eventFrame) delete this->eventFrame;
this->eventFrame = nullptr;
}
void Event::setPixmapItem(DraggablePixmapItem *item) {
this->pixmapItem = item;
if (this->eventFrame) {
this->eventFrame->invalidateConnections();
}
}
int Event::getEventIndex() {
return this->map->events.value(this->getEventGroup()).indexOf(this);
}
void Event::setDefaultValues(Project *) {
this->setX(0);
this->setY(0);
this->setElevation(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];
}
}
}
void Event::modify() {
this->map->modify();
}
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(this->gfx, nullptr);
if (!eventGfx) {
// Invalid gfx constant.
// If this is a number, try to use that instead.
bool ok;
int altGfx = this->gfx.toInt(&ok);
if (ok && (altGfx < project->gfxDefines.count())) {
eventGfx = project->eventGraphicsMap.value(project->gfxDefines.key(altGfx, "NULL"), nullptr);
}
}
if (!eventGfx || eventGfx->spritesheet.isNull()) {
// No sprite associated with this gfx constant.
// Use default sprite instead.
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

@ -340,6 +340,10 @@ void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata,
emit mapChanged(this); emit mapChanged(this);
} }
void Map::openScript(QString label) {
emit openScriptRequested(label);
}
bool Map::getBlock(int x, int y, Block *out) { bool Map::getBlock(int x, int y, Block *out) {
if (isWithinBounds(x, y)) { if (isWithinBounds(x, y)) {
int i = y * getWidth() + x; int i = y * getWidth() + x;
@ -474,37 +478,51 @@ 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);
} }
void Map::modify() {
emit modified();
}
void Map::clean() {
this->hasUnsavedDataChanges = false;
}
bool Map::hasUnsavedChanges() { bool Map::hasUnsavedChanges() {
return !editHistory.isClean() || hasUnsavedDataChanges || !isPersistedToFile; return !editHistory.isClean() || hasUnsavedDataChanges || !isPersistedToFile;
} }

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"
@ -1093,6 +1092,12 @@ bool Editor::setMap(QString map_name) {
return false; return false;
} }
// disconnect previous map's signals so they are not firing
// multiple times if set again in the future
if (map) {
map->disconnect(this);
}
if (project) { if (project) {
Map *loadedMap = project->loadMap(map_name); Map *loadedMap = project->loadMap(map_name);
if (!loadedMap) { if (!loadedMap) {
@ -1109,6 +1114,7 @@ bool Editor::setMap(QString map_name) {
} }
map_ruler->setMapDimensions(QSize(map->getWidth(), map->getHeight())); map_ruler->setMapDimensions(QSize(map->getWidth(), map->getHeight()));
connect(map, &Map::mapDimensionsChanged, map_ruler, &MapRuler::setMapDimensions); connect(map, &Map::mapDimensionsChanged, map_ruler, &MapRuler::setMapDimensions);
connect(map, &Map::openScriptRequested, this, &Editor::openScript);
updateSelectedEvents(); updateSelectedEvents();
} }
@ -1230,12 +1236,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 +1256,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 +1521,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;
@ -1977,15 +1981,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));
@ -2003,7 +2008,7 @@ void Editor::updateSelectedEvents() {
redrawObject(item); redrawObject(item);
} }
emit selectedObjectsChanged(); emit objectsChanged();
} }
void Editor::selectMapEvent(DraggablePixmapItem *object) { void Editor::selectMapEvent(DraggablePixmapItem *object) {
@ -2026,6 +2031,29 @@ void Editor::selectMapEvent(DraggablePixmapItem *object, bool toggle) {
} }
} }
void Editor::selectedEventIndexChanged(int index, Event::Group eventGroup) {
int event_offs = Event::getIndexOffset(eventGroup);
index = index - event_offs;
Event *event = nullptr;
if (index < this->map->events.value(eventGroup).length()) {
event = this->map->events.value(eventGroup).at(index);
}
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);
} else {
updateSelectedEvents();
}
}
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,60 +2061,89 @@ 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 (project && map && !eventLimitReached(type)) {
if (event_type == EventType::HealLocation) { switch (type) {
HealLocation hl = HealLocation::fromEvent(event); case Event::Type::Object:
project->healLocations.append(hl); event = new ObjectEvent();
event->put("index", project->healLocations.length()); 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->setMap(this->map);
event->setDefaultValues(this->project);
map->editHistory.push(new EventCreate(this, map, event)); map->editHistory.push(new EventCreate(this, map, event));
return event->getPixmapItem();
return event->pixmapItem;
} }
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) {
Map *map = project->getMap(event->get("map_name"));
if (map) {
map->removeEvent(event);
if (event->pixmapItem) {
events_group->removeFromGroup(event->pixmapItem);
delete event->pixmapItem;
event->pixmapItem = nullptr;
}
}
//selected_events->removeAll(event);
//updateSelectedObjects();
}
void Editor::openMapScripts() const { void Editor::openMapScripts() const {
const QString scriptPath = project->getMapScriptsFilePath(map->name); const QString scriptPath = project->getMapScriptsFilePath(map->name);
openInTextEditor(scriptPath); openInTextEditor(scriptPath);

File diff suppressed because it is too large Load diff

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) { coordEventsArr.append(triggerObj);
OrderedJson::object triggerObj = event->buildTriggerEventJSON();
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);
} }
} }
} }

1091
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"