Map Editor

RD Core / Commit #3

Commit Map Editor

Alex Alex committed 18/10/2026 23:40 main Patch
436 files +250,791 -0
A RD_Map_Editor/source/monster_generator_dialog.h +78-0 View file
@@ -0,0 +1,78 @@
1+#ifndef RME_MONSTER_GENERATOR_DIALOG_H_
2+#define RME_MONSTER_GENERATOR_DIALOG_H_
3+
4+#include <wx/wx.h>
5+#include <wx/notebook.h>
6+#include <wx/spinctrl.h>
7+#include <wx/listctrl.h>
8+
9+class MonsterGeneratorDialog : public wxDialog {
10+public:
11+ MonsterGeneratorDialog(wxWindow* parent);
12+ virtual ~MonsterGeneratorDialog();
13+
14+protected:
15+ // Event handlers
16+ void OnSave(wxCommandEvent& event);
17+ void OnLoad(wxCommandEvent& event);
18+ void OnOutfitChange(wxSpinEvent& event);
19+ void OnAddAttack(wxCommandEvent& event);
20+ void OnAddDefense(wxCommandEvent& event);
21+ void OnAddLoot(wxCommandEvent& event);
22+
23+private:
24+ void CreateGUI();
25+ void UpdatePreview();
26+ void SaveMonsterFile();
27+ void LoadMonsterFile();
28+
29+ // GUI elements
30+ wxNotebook* notebook;
31+
32+ // Basic info page
33+ wxPanel* basicPanel;
34+ wxTextCtrl* nameCtrl;
35+ wxTextCtrl* descriptionCtrl;
36+ wxChoice* raceChoice;
37+ wxSpinCtrl* experienceCtrl;
38+ wxSpinCtrl* healthCtrl;
39+ wxSpinCtrl* speedCtrl;
40+ wxSpinCtrl* armorCtrl;
41+ wxSpinCtrl* defenseCtrl;
42+
43+ // Outfit page
44+ wxPanel* outfitPanel;
45+ wxSpinCtrl* lookTypeCtrl;
46+ wxSpinCtrl* headCtrl;
47+ wxSpinCtrl* bodyCtrl;
48+ wxSpinCtrl* legsCtrl;
49+ wxSpinCtrl* feetCtrl;
50+ wxSpinCtrl* addonsCtrl;
51+ wxStaticBitmap* outfitPreview;
52+
53+ // Attacks page
54+ wxPanel* attacksPanel;
55+ wxListCtrl* attacksList;
56+
57+ // Defenses page
58+ wxPanel* defensesPanel;
59+ wxListCtrl* defensesList;
60+
61+ // Immunities page
62+ wxPanel* immunitiesPanel;
63+ wxCheckBox* holyCheck;
64+ wxCheckBox* deathCheck;
65+ wxCheckBox* fireCheck;
66+ wxCheckBox* energyCheck;
67+ wxCheckBox* poisonCheck;
68+ wxCheckBox* iceCheck;
69+ wxCheckBox* physicalCheck;
70+
71+ // Loot page
72+ wxPanel* lootPanel;
73+ wxListCtrl* lootList;
74+
75+ DECLARE_EVENT_TABLE()
76+};
77+
78+#endif // RME_MONSTER_GENERATOR_DIALOG_H_
A RD_Map_Editor/source/mt_rand.cpp +121-0 View file
@@ -0,0 +1,121 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#include "main.h"
19+
20+static inline unsigned long int mt_get(void* vstate);
21+static double mt_get_double(void* vstate);
22+static void mt_set(void* state, unsigned long int s);
23+
24+#define N 624 /* Period parameters */
25+#define M 397
26+
27+/* most significant w-r bits */
28+static const unsigned long UPPER_MASK = 0x80000000UL;
29+
30+/* least significant r bits */
31+static const unsigned long LOWER_MASK = 0x7fffffffUL;
32+
33+typedef struct
34+{
35+ unsigned long mt[N];
36+ int mti;
37+} mt_state_t;
38+
39+static inline unsigned long
40+mt_get(void* vstate) {
41+ mt_state_t* state = (mt_state_t*)vstate;
42+
43+ unsigned long k;
44+ unsigned long int* const mt = state->mt;
45+
46+#define MAGIC(y) (((y) & 0x1) ? 0x9908b0dfUL : 0)
47+
48+ if (state->mti >= N) { /* generate N words at one time */
49+ int kk;
50+
51+ for (kk = 0; kk < N - M; kk++) {
52+ unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
53+ mt[kk] = mt[kk + M] ^ (y >> 1) ^ MAGIC(y);
54+ }
55+ for (; kk < N - 1; kk++) {
56+ unsigned long y = (mt[kk] & UPPER_MASK) | (mt[kk + 1] & LOWER_MASK);
57+ mt[kk] = mt[kk + (M - N)] ^ (y >> 1) ^ MAGIC(y);
58+ }
59+
60+ {
61+ unsigned long y = (mt[N - 1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
62+ mt[N - 1] = mt[M - 1] ^ (y >> 1) ^ MAGIC(y);
63+ }
64+
65+ state->mti = 0;
66+ }
67+
68+ /* Tempering */
69+
70+ k = mt[state->mti];
71+ k ^= (k >> 11);
72+ k ^= (k << 7) & 0x9d2c5680UL;
73+ k ^= (k << 15) & 0xefc60000UL;
74+ k ^= (k >> 18);
75+
76+ state->mti++;
77+
78+ return k;
79+}
80+
81+static double
82+mt_get_double(void* vstate) {
83+ return mt_get(vstate) / 4294967296.0;
84+}
85+
86+static void
87+mt_set(void* vstate, unsigned long int s) {
88+ mt_state_t* state = (mt_state_t*)vstate;
89+ int i;
90+
91+ if (s == 0) {
92+ s = 4357; /* the default seed is 4357 */
93+ }
94+
95+ state->mt[0] = s & 0xffffffffUL;
96+
97+ for (i = 1; i < N; i++) {
98+ /* See Knuth's "Art of Computer Programming" Vol. 2, 3rd
99+ Ed. p.106 for multiplier. */
100+
101+ state->mt[i] = (1812433253UL * (state->mt[i - 1] ^ (state->mt[i - 1] >> 30)) + i);
102+
103+ state->mt[i] &= 0xffffffffUL;
104+ }
105+
106+ state->mti = i;
107+}
108+
109+static mt_state_t mt_state;
110+
111+void mt_seed(unsigned long s) {
112+ mt_set(&mt_state, s);
113+}
114+
115+unsigned long mt_randi() {
116+ return mt_get(&mt_state);
117+}
118+
119+double mt_randd() {
120+ return mt_get_double(&mt_state);
121+}
A RD_Map_Editor/source/mt_rand.h +25-0 View file
@@ -0,0 +1,25 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef RME_MT_RAND_H_
19+#define RME_MT_RAND_H_
20+
21+void mt_seed(unsigned long s);
22+unsigned long mt_randi();
23+double mt_randd();
24+
25+#endif
A RD_Map_Editor/source/net_connection.cpp +219-0 View file
@@ -0,0 +1,219 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#include "main.h"
19+#include "net_connection.h"
20+
21+/*
22+RME Server-Client Split Roadmap:
23+
24+1. Server Project (New Linux-based project)
25+ - Core Components:
26+ * OTBM file loader (port from RME)
27+ * SPR/DAT loaders
28+ * items.otb handler
29+ * Network message handler
30+ * Live editing protocol
31+ * Client session management
32+ * Map change broadcasting
33+ * Undo/Redo synchronization
34+
35+ - Required Features:
36+ * Headless operation (no GUI)
37+ * Multi-client support
38+ * File change monitoring
39+ * Backup system
40+ * Change validation
41+ * Permission system
42+ * Map locking mechanism
43+ * Auto-save functionality
44+
45+2. RME Client Modifications:
46+ - Remove:
47+ * LiveServer class
48+ * Server-side packet handlers
49+ * Host/server creation UI
50+ * Local map saving (server handles this)
51+
52+ - Modify:
53+ * NetworkMessage class (client-only packets)
54+ * LiveClient to handle all server communication
55+ * Editor class to work in client-only mode
56+ * GUI to reflect client-only status
57+ * ActionQueue to forward all changes to server
58+
59+3. Protocol Updates:
60+ - New Packets:
61+ * Client authentication
62+ * Map region requests
63+ * Change proposals
64+ * Lock requests
65+ * Client synchronization
66+ * Server commands
67+
68+ - Security:
69+ * Implement proper encryption
70+ * Add checksum validation
71+ * Session management
72+ * Anti-tampering measures
73+
74+4. Data Flow:
75+ Server: Client:
76+ [OTBM] <-> [Server] <---> [RME Client] <-> [GUI]
77+ [items.otb] ^ ^
78+ [spr/dat] | |
79+ +----------------+
80+ Network Protocol
81+
82+Implementation Priority:
83+1. Create basic server project structure
84+2. Port core file handlers to server
85+3. Implement basic client-server protocol
86+4. Remove server code from RME
87+5. Add security features
88+6. Implement advanced features
89+7. Testing and optimization
90+
91+Note: This requires significant restructuring of the RME codebase
92+and careful handling of backwards compatibility for offline editing.
93+*/
94+
95+NetworkMessage::NetworkMessage() {
96+ clear();
97+}
98+
99+void NetworkMessage::clear() {
100+ buffer.resize(4);
101+ position = 4;
102+ size = 0;
103+}
104+
105+void NetworkMessage::expand(const size_t length) {
106+ if (position + length >= buffer.size()) {
107+ buffer.resize(position + length + 1);
108+ }
109+ size += length;
110+}
111+
112+template <>
113+std::string NetworkMessage::read<std::string>() {
114+ const uint16_t length = read<uint16_t>();
115+
116+ // Check if we have enough data for the string
117+ if (position + length > buffer.size()) {
118+ throw std::runtime_error("Buffer underflow - string length exceeds remaining buffer size");
119+ }
120+
121+ char* strBuffer = reinterpret_cast<char*>(&buffer[position]);
122+ position += length;
123+ return std::string(strBuffer, length);
124+}
125+
126+template <>
127+Position NetworkMessage::read<Position>() {
128+ Position position;
129+ position.x = read<uint16_t>();
130+ position.y = read<uint16_t>();
131+ position.z = read<uint8_t>();
132+ return position;
133+}
134+
135+template <>
136+void NetworkMessage::write<std::string>(const std::string& value) {
137+ const size_t length = value.length();
138+ write<uint16_t>(length);
139+
140+ expand(length);
141+ memcpy(&buffer[position], &value[0], length);
142+ position += length;
143+}
144+
145+template <>
146+void NetworkMessage::write<Position>(const Position& value) {
147+ write<uint16_t>(value.x);
148+ write<uint16_t>(value.y);
149+ write<uint8_t>(value.z);
150+}
151+
152+// NetworkConnection
153+NetworkConnection::NetworkConnection() :
154+ service(nullptr), thread(), stopped(false) {
155+ //
156+}
157+
158+NetworkConnection::~NetworkConnection() {
159+ stop();
160+}
161+
162+NetworkConnection& NetworkConnection::getInstance() {
163+ static NetworkConnection connection;
164+ return connection;
165+}
166+
167+bool NetworkConnection::start() {
168+ if (thread.joinable()) {
169+ if (stopped) {
170+ return false;
171+ }
172+ return true;
173+ }
174+
175+ stopped = false;
176+ if (!service) {
177+ service = new boost::asio::io_context;
178+ }
179+
180+ thread = std::thread([this]() -> void {
181+ boost::asio::io_context& serviceRef = *service;
182+ // Create a work guard to keep the context alive even when there are no pending handlers
183+ boost::asio::executor_work_guard<boost::asio::io_context::executor_type> work =
184+ boost::asio::make_work_guard(serviceRef);
185+
186+ try {
187+ while (!stopped) {
188+ // Run one handler at a time
189+ serviceRef.run_one();
190+
191+ // Instead of reset, just check if we should continue
192+ if (serviceRef.stopped() && !stopped) {
193+ // If the service stopped but we didn't request it, restart it
194+ serviceRef.restart();
195+ }
196+ }
197+ } catch (std::exception& e) {
198+ std::cout << e.what() << std::endl;
199+ }
200+ });
201+ return true;
202+}
203+
204+void NetworkConnection::stop() {
205+ if (!service) {
206+ return;
207+ }
208+
209+ service->stop();
210+ stopped = true;
211+ thread.join();
212+
213+ delete service;
214+ service = nullptr;
215+}
216+
217+boost::asio::io_context& NetworkConnection::get_service() {
218+ return *service;
219+}
A RD_Map_Editor/source/net_connection.h +90-0 View file
@@ -0,0 +1,90 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef _RME_NET_CONNECTION_H_
19+#define _RME_NET_CONNECTION_H_
20+
21+#include "position.h"
22+
23+#include <string>
24+#include <vector>
25+#include <cstdint>
26+#include <thread>
27+#include <mutex>
28+
29+struct NetworkMessage {
30+ NetworkMessage();
31+
32+ void clear();
33+ void expand(const size_t length);
34+
35+ //
36+ template <typename T>
37+ T read() {
38+ // Check if we have enough data left to read
39+ if (position + sizeof(T) > buffer.size()) {
40+ throw std::runtime_error("Buffer underflow - attempted to read past buffer end");
41+ }
42+ T& value = *reinterpret_cast<T*>(&buffer[position]);
43+ position += sizeof(T);
44+ return value;
45+ }
46+
47+ template <typename T>
48+ void write(const T& value) {
49+ expand(sizeof(T));
50+ memcpy(&buffer[position], &value, sizeof(T));
51+ position += sizeof(T);
52+ }
53+
54+ //
55+ std::vector<uint8_t> buffer;
56+ size_t position;
57+ size_t size;
58+};
59+
60+template <>
61+std::string NetworkMessage::read<std::string>();
62+template <>
63+Position NetworkMessage::read<Position>();
64+template <>
65+void NetworkMessage::write<std::string>(const std::string& value);
66+template <>
67+void NetworkMessage::write<Position>(const Position& value);
68+
69+class NetworkConnection {
70+private:
71+ NetworkConnection();
72+ NetworkConnection(const NetworkConnection& copy) = delete;
73+
74+public:
75+ ~NetworkConnection();
76+
77+ static NetworkConnection& getInstance();
78+
79+ bool start();
80+ void stop();
81+
82+ boost::asio::io_context& get_service();
83+
84+private:
85+ boost::asio::io_context* service;
86+ std::thread thread;
87+ bool stopped;
88+};
89+
90+#endif
A RD_Map_Editor/source/numbertextctrl.cpp +114-0 View file
@@ -0,0 +1,114 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#include "main.h"
19+#include "numbertextctrl.h"
20+
21+BEGIN_EVENT_TABLE(NumberTextCtrl, wxTextCtrl)
22+EVT_KILL_FOCUS(NumberTextCtrl::OnKillFocus)
23+EVT_TEXT_ENTER(wxID_ANY, NumberTextCtrl::OnTextEnter)
24+END_EVENT_TABLE()
25+
26+NumberTextCtrl::NumberTextCtrl(wxWindow* parent, wxWindowID id, long value, long minvalue, long maxvalue, const wxPoint& pos, const wxSize& sz, long style, const wxString& name) :
27+ wxTextCtrl(parent, id, (wxString() << value), pos, sz, style, wxTextValidator(wxFILTER_NUMERIC), name),
28+ minval(minvalue), maxval(maxvalue), lastval(value) {
29+ ////
30+}
31+
32+NumberTextCtrl::NumberTextCtrl(wxWindow* parent, wxWindowID id, long value, long minvalue, long maxvalue, long style, const wxString& name, const wxPoint& pos, const wxSize& sz) :
33+ wxTextCtrl(parent, id, (wxString() << value), pos, sz, style, wxTextValidator(wxFILTER_NUMERIC), name),
34+ minval(minvalue), maxval(maxvalue), lastval(value) {
35+ ////
36+}
37+
38+NumberTextCtrl::~NumberTextCtrl() {
39+ ////
40+}
41+
42+void NumberTextCtrl::OnKillFocus(wxFocusEvent& evt) {
43+ CheckRange();
44+ evt.Skip();
45+}
46+
47+void NumberTextCtrl::OnTextEnter(wxCommandEvent& evt) {
48+ CheckRange();
49+}
50+
51+void NumberTextCtrl::SetIntValue(long value) {
52+ wxString sv;
53+ sv << value;
54+ // Will generate events
55+ SetValue(sv);
56+}
57+
58+long NumberTextCtrl::GetIntValue() {
59+ long l;
60+ if (GetValue().ToLong(&l)) {
61+ return l;
62+ }
63+ return 0;
64+}
65+
66+void NumberTextCtrl::SetMinValue(long value) {
67+ if (value == minval) {
68+ return;
69+ }
70+ minval = value;
71+ CheckRange();
72+}
73+
74+void NumberTextCtrl::SetMaxValue(long value) {
75+ if (value == maxval) {
76+ return;
77+ }
78+ maxval = value;
79+ CheckRange();
80+}
81+
82+void NumberTextCtrl::CheckRange() {
83+ wxString text = GetValue();
84+ wxString ntext;
85+
86+ for (size_t s = 0; s < text.size(); ++s) {
87+ if (text[s] >= '0' && text[s] <= '9') {
88+ ntext.Append(text[s]);
89+ }
90+ }
91+
92+ // Check that value is in range
93+ long v;
94+ if (ntext.size() != 0 && ntext.ToLong(&v)) {
95+ if (v < minval) {
96+ v = minval;
97+ } else if (v > maxval) {
98+ v = maxval;
99+ }
100+
101+ ntext.clear();
102+ ntext << v;
103+ lastval = v;
104+ } else {
105+ ntext.clear();
106+ ntext << lastval;
107+ }
108+
109+ // Check if there was any change
110+ if (ntext != text) {
111+ // ChangeValue doesn't generate events
112+ ChangeValue(ntext);
113+ }
114+}
A RD_Map_Editor/source/numbertextctrl.h +44-0 View file
@@ -0,0 +1,44 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef _RME_NUMBER_TEXT_CTRL_H_
19+#define _RME_NUMBER_TEXT_CTRL_H_
20+
21+// Text ctrl that only allows number input
22+class NumberTextCtrl : public wxTextCtrl {
23+public:
24+ NumberTextCtrl(wxWindow* parent, wxWindowID id = wxID_ANY, long value = 0, long minvalue = 0, long maxvalue = 100, const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxDefaultSize, long style = 0, const wxString& name = wxTextCtrlNameStr);
25+ NumberTextCtrl(wxWindow* parent, wxWindowID id = wxID_ANY, long value = 0, long minvalue = 0, long maxvalue = 100, long style = 0, const wxString& name = wxTextCtrlNameStr, const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxDefaultSize);
26+ ~NumberTextCtrl();
27+
28+ void OnKillFocus(wxFocusEvent&);
29+ void OnTextEnter(wxCommandEvent&);
30+
31+ long GetIntValue();
32+ void SetIntValue(long value);
33+
34+ void SetMinValue(long value);
35+ void SetMaxValue(long value);
36+
37+protected:
38+ void CheckRange();
39+
40+ long minval, maxval, lastval;
41+ DECLARE_EVENT_TABLE();
42+};
43+
44+#endif
A RD_Map_Editor/source/old_properties_window.h +107-0 View file
@@ -0,0 +1,107 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef RME_OLD_PROPERTIES_WINDOW_H_
19+#define RME_OLD_PROPERTIES_WINDOW_H_
20+
21+#include "main.h"
22+
23+#include "common_windows.h"
24+
25+class ContainerItemButton;
26+class ContainerItemPopupMenu;
27+class MapWindow;
28+
29+class OldPropertiesWindow : public ObjectPropertiesWindowBase {
30+public:
31+ OldPropertiesWindow(wxWindow* parent, const Map* map, const Tile* tile, Item* item, wxPoint = wxDefaultPosition);
32+ OldPropertiesWindow(wxWindow* parent, const Map* map, const Tile* tile, Creature* creature, wxPoint = wxDefaultPosition);
33+ OldPropertiesWindow(wxWindow* parent, const Map* map, const Tile* tile, Spawn* spawn, wxPoint = wxDefaultPosition);
34+ virtual ~OldPropertiesWindow();
35+
36+ void OnFocusChange(wxFocusEvent&);
37+ void OnChar(wxKeyEvent& evt);
38+ void OnKeyDown(wxKeyEvent& evt);
39+ void OnTextEnter(wxCommandEvent& evt);
40+
41+ void OnClickOK(wxCommandEvent&);
42+ void OnClickCancel(wxCommandEvent&);
43+ void OnClose(wxCloseEvent& evt);
44+
45+ void Update();
46+
47+ // Non-modal methods
48+ static OldPropertiesWindow* getInstance() { return instance; }
49+ static void destroyInstance() {
50+ if (instance) {
51+ instance->Destroy();
52+ instance = nullptr;
53+ }
54+ }
55+ static bool isActive() { return instance != nullptr; }
56+
57+ void CommitChanges();
58+
59+protected:
60+ // Singleton instance for non-modal use
61+ static OldPropertiesWindow* instance;
62+
63+ // item
64+ wxSpinCtrl* count_field;
65+ wxSpinCtrl* action_id_field;
66+ wxSpinCtrl* unique_id_field;
67+ wxSpinCtrl* door_id_field;
68+ wxSpinCtrl* tier_field;
69+ wxChoice* depot_id_field;
70+ wxChoice* splash_type_field;
71+ wxTextCtrl* text_field;
72+ wxTextCtrl* description_field;
73+
74+ // teleport
75+ wxSpinCtrl* x_field;
76+ wxSpinCtrl* y_field;
77+ wxSpinCtrl* z_field;
78+
79+ // podium
80+ wxCheckBox* show_outfit;
81+ wxCheckBox* show_mount;
82+ wxCheckBox* show_platform;
83+ wxSpinCtrl* look_type;
84+ wxSpinCtrl* look_head;
85+ wxSpinCtrl* look_body;
86+ wxSpinCtrl* look_legs;
87+ wxSpinCtrl* look_feet;
88+ wxSpinCtrl* look_addon;
89+ wxSpinCtrl* look_mount;
90+ wxSpinCtrl* look_mounthead;
91+ wxSpinCtrl* look_mountbody;
92+ wxSpinCtrl* look_mountlegs;
93+ wxSpinCtrl* look_mountfeet;
94+
95+ // podium and creature
96+ wxChoice* direction_field;
97+
98+ // container
99+ std::vector<ContainerItemButton*> container_items;
100+
101+ friend class ContainerItemButton;
102+ friend class ContainerItemPopupMenu;
103+
104+ DECLARE_EVENT_TABLE();
105+};
106+
107+#endif
A RD_Map_Editor/source/otmapgen.h +241-0 View file
@@ -0,0 +1,241 @@
1+//////////////////////////////////////////////////////////////////////
2+// This file is part of Remere's Map Editor
3+//////////////////////////////////////////////////////////////////////
4+// Remere's Map Editor is free software: you can redistribute it and/or modify
5+// it under the terms of the GNU General Public License as published by
6+// the Free Software Foundation, either version 3 of the License, or
7+// (at your option) any later version.
8+//
9+// Remere's Map Editor is distributed in the hope that it will be useful,
10+// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+// GNU General Public License for more details.
13+//
14+// You should have received a copy of the GNU General Public License
15+// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+//////////////////////////////////////////////////////////////////////
17+
18+#ifndef RME_OTMAPGEN_H_
19+#define RME_OTMAPGEN_H_
20+
21+#include "main.h"
22+#include <vector>
23+#include <string>
24+#include <map>
25+#include <random>
26+
27+// Forward declarations
28+class BaseMap;
29+class Tile;
30+
31+// Terrain layer configuration for multiple ground types
32+struct TerrainLayer {
33+ std::string name;
34+ std::string brush_name; // Name of brush from grounds.xml
35+ uint16_t item_id; // Primary item ID for this layer
36+ double height_min = 0.0; // Minimum height for this terrain
37+ double height_max = 1.0; // Maximum height for this terrain
38+ double moisture_min = -1.0; // Minimum moisture for this terrain
39+ double moisture_max = 1.0; // Maximum moisture for this terrain
40+ double noise_scale = 1.0; // Scale factor for noise sampling
41+ double coverage = 1.0; // Coverage probability (0.0 to 1.0)
42+ bool use_borders = true; // Whether to apply borders from brush
43+ bool enabled = true; // Whether this layer is active
44+ int z_order = 1000; // Rendering order (higher = on top)
45+};
46+
47+struct GenerationConfig {
48+ std::string seed;
49+ int width = 256;
50+ int height = 256;
51+ std::string version = "10.98";
52+ bool terrain_only = false;
53+
54+ // Generation parameters
55+ double noise_increment = 1.0;
56+ double island_distance_decrement = 0.92;
57+ double island_distance_exponent = 0.25;
58+ int cave_depth = 20;
59+ double cave_roughness = 0.45;
60+ double cave_chance = 0.09;
61+ bool sand_biome = true;
62+ bool euclidean = false;
63+ bool smooth_coastline = true;
64+ bool add_caves = true;
65+ int water_level = 7; // Changed to match Tibia coordinates (7 = ground level)
66+ double exponent = 1.4;
67+ double linear = 6.0;
68+ std::string mountain_type = "MOUNTAIN";
69+
70+ // Configurable terrain layers instead of hardcoded items
71+ std::vector<TerrainLayer> terrain_layers;
72+
73+ // Cave configuration
74+ std::string cave_brush_name = "cave";
75+ uint16_t cave_item_id = 351; // Default cave floor from grounds.xml
76+
77+ // Water configuration
78+ std::string water_brush_name = "sea";
79+ uint16_t water_item_id = 4608; // Default water from grounds.xml
80+
81+ // Frequency weights for noise generation
82+ struct FrequencyWeight {
83+ double frequency;
84+ double weight;
85+ };
86+
87+ std::vector<FrequencyWeight> frequencies = {
88+ {1.0, 0.3}, {2.0, 0.2}, {4.0, 0.2}, {8.0, 0.125},
89+ {16.0, 0.1}, {32.0, 0.05}, {64.0, 0.0025}
90+ };
91+
92+ // Initialize with default terrain layers
93+ void initializeDefaultLayers() {
94+ terrain_layers.clear();
95+
96+ // Water layer (lowest)
97+ TerrainLayer water;
98+ water.name = "Water";
99+ water.brush_name = "sea";
100+ water.item_id = 4608;
101+ water.height_min = -1.0;
102+ water.height_max = 0.0;
103+ water.moisture_min = -1.0;
104+ water.moisture_max = 1.0;
105+ water.noise_scale = 1.0;
106+ water.coverage = 1.0;
107+ water.use_borders = true;
108+ water.z_order = 6000;
109+ terrain_layers.push_back(water);
110+
111+ // Grass layer (main land)
112+ TerrainLayer grass;
113+ grass.name = "Grass";
114+ grass.brush_name = "grass";
115+ grass.item_id = 4526;
116+ grass.height_min = 0.0;
117+ grass.height_max = 0.7;
118+ grass.moisture_min = -0.5;
119+ grass.moisture_max = 1.0;
120+ grass.noise_scale = 1.0;
121+ grass.coverage = 1.0;
122+ grass.use_borders = true;
123+ grass.z_order = 3500;
124+ terrain_layers.push_back(grass);
125+
126+ // Sand layer (dry areas)
127+ TerrainLayer sand;
128+ sand.name = "Sand";
129+ sand.brush_name = "sand";
130+ sand.item_id = 231;
131+ sand.height_min = 0.0;
132+ sand.height_max = 0.6;
133+ sand.moisture_min = -1.0;
134+ sand.moisture_max = -0.6;
135+ sand.noise_scale = 1.5;
136+ sand.coverage = 1.0;
137+ sand.use_borders = true;
138+ sand.z_order = 3400;
139+ sand.enabled = sand_biome;
140+ terrain_layers.push_back(sand);
141+
142+ // Mountain layer (high elevation)
143+ TerrainLayer mountain;
144+ mountain.name = "Mountain";
145+ mountain.brush_name = "mountain";
146+ mountain.item_id = 919; // From grounds.xml mountain brush
147+ mountain.height_min = 0.7;
148+ mountain.height_max = 1.0;
149+ mountain.moisture_min = -1.0;
150+ mountain.moisture_max = 1.0;
151+ mountain.noise_scale = 0.8;
152+ mountain.coverage = 1.0;
153+ mountain.use_borders = true;
154+ mountain.z_order = 9900;
155+ terrain_layers.push_back(mountain);
156+ }
157+};
158+
159+class SimplexNoise {
160+public:
161+ SimplexNoise(unsigned int seed = 0);
162+
163+ double noise(double x, double y);
164+ double fractal(double x, double y, const std::vector<GenerationConfig::FrequencyWeight>& frequencies);
165+
166+private:
167+ static const int SIMPLEX[64][4];
168+ static const double F2, G2;
169+
170+ int perm[512];
171+ int permMod12[512];
172+
173+ void initializePermutation(unsigned int seed);
174+ double dot(const int g[], double x, double y);
175+ int fastfloor(double x);
176+};
177+
178+class OTMapGenerator {
179+public:
180+ OTMapGenerator();
181+ ~OTMapGenerator();
182+
183+ // Main generation function
184+ bool generateMap(BaseMap* map, const GenerationConfig& config);
185+
186+ // Preview generation
187+ std::vector<std::vector<uint16_t>> generateLayers(const GenerationConfig& config);
188+
189+ // Core generation methods
190+ std::vector<std::vector<double>> generateHeightMap(const GenerationConfig& config);
191+ std::vector<std::vector<double>> generateMoistureMap(const GenerationConfig& config);
192+ std::vector<std::vector<uint16_t>> generateTerrainLayer(const std::vector<std::vector<double>>& heightMap,
193+ const std::vector<std::vector<double>>& moistureMap,
194+ const GenerationConfig& config);
195+
196+ // Helper methods for multi-floor generation
197+ void fillColumn(std::vector<std::vector<std::vector<uint16_t>>>& layers,
198+ int x, int y, int elevation, uint16_t surfaceTileId,
199+ const GenerationConfig& config);
200+ uint16_t getTerrainTileId(double height, double moisture, const GenerationConfig& config);
201+ const TerrainLayer* selectTerrainLayer(double height, double moisture, const GenerationConfig& config);
202+
203+private:
204+ SimplexNoise* noise_generator;
205+ std::mt19937 rng;
206+
207+ // Cave generation
208+ std::vector<std::vector<uint16_t>> generateCaveLayer(const GenerationConfig& config);
209+
210+ // Utility functions
211+ double getDistance(int x, int y, int centerX, int centerY, bool euclidean = false);
212+ double smoothstep(double edge0, double edge1, double x);
213+ void seedRandom(const std::string& seed);
214+
215+ // Border generation (integrate with brush system)
216+ void generateBorders(BaseMap* map, const GenerationConfig& config);
217+ void addBordersToTile(BaseMap* map, Tile* tile, int x, int y, int z);
218+
219+ // Decoration placement
220+ void addClutter(BaseMap* map, const GenerationConfig& config);
221+ void placeTreesAndVegetation(BaseMap* map, Tile* tile, uint16_t groundId);
222+ void placeStones(BaseMap* map, Tile* tile, uint16_t groundId);
223+ void placeCaveDecorations(BaseMap* map, Tile* tile);
224+};
225+
226+// Helper functions for tile creation and manipulation
227+namespace OTMapGenUtils {
228+ Tile* getOrCreateTile(BaseMap* map, int x, int y, int z);
229+ void setGroundTile(Tile* tile, uint16_t itemId);
230+ void addDecoration(Tile* tile, uint16_t itemId);
231+ bool isWaterTile(uint16_t itemId);
232+ bool isLandTile(uint16_t itemId);
233+ bool isMountainTile(uint16_t itemId);
234+
235+ // Brush system integration
236+ std::vector<std::string> getAvailableBrushes();
237+ uint16_t getPrimaryItemFromBrush(const std::string& brushName);
238+ bool applyBrushToTile(BaseMap* map, Tile* tile, const std::string& brushName, int x, int y, int z);
239+}
240+
241+#endif
Top