2012-06-29 16:44:26 +02:00
//////////////////////////////////////////////////////////////////////
// This file is part of Remere's Map Editor
//////////////////////////////////////////////////////////////////////
2020-07-30 11:42:28 -03:00
// Remere's Map Editor is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Remere's Map Editor is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//////////////////////////////////////////////////////////////////////
2012-06-29 16:44:26 +02:00
# include "main.h"
# include "editor.h"
# include "materials.h"
# include "map.h"
# include "complexitem.h"
# include "settings.h"
# include "gui.h"
# include "map_display.h"
# include "brush.h"
# include "ground_brush.h"
# include "wall_brush.h"
# include "table_brush.h"
# include "carpet_brush.h"
# include "waypoint_brush.h"
# include "house_exit_brush.h"
# include "doodad_brush.h"
2021-05-25 00:29:12 -03:00
# include "monster_brush.h"
# include "npc_brush.h"
# include "spawn_monster_brush.h"
# include "spawn_npc_brush.h"
2012-06-29 16:44:26 +02:00
# include "live_server.h"
# include "live_client.h"
# include "live_action.h"
2023-10-09 19:12:16 -07:00
Editor : : Editor ( CopyBuffer & copybuffer ) :
2014-01-22 20:16:17 +01:00
live_server ( nullptr ) ,
2014-01-23 21:06:52 -02:00
live_client ( nullptr ) ,
2023-10-15 18:51:57 -03:00
actionQueue ( newd < ActionQueue > ( * this ) ) ,
2012-06-29 16:44:26 +02:00
selection ( * this ) ,
copybuffer ( copybuffer ) ,
2023-10-09 19:12:16 -07:00
replace_brush ( nullptr ) {
2012-06-29 16:44:26 +02:00
wxString error ;
wxArrayString warnings ;
bool ok = true ;
2012-07-05 17:32:36 +02:00
2016-09-29 20:37:43 -03:00
ClientVersionID defaultVersion = ClientVersionID ( g_settings . getInteger ( Config : : DEFAULT_CLIENT_VERSION ) ) ;
2023-10-09 19:12:16 -07:00
if ( defaultVersion = = CLIENT_VERSION_NONE ) {
2012-07-01 13:41:59 +02:00
defaultVersion = ClientVersion : : getLatestVersion ( ) - > getID ( ) ;
2023-10-09 19:12:16 -07:00
}
2015-12-06 11:42:37 -03:00
2023-10-09 19:12:16 -07:00
if ( g_gui . GetCurrentVersionID ( ) ! = defaultVersion ) {
if ( g_gui . CloseAllEditors ( ) ) {
2016-09-29 20:30:54 -03:00
ok = g_gui . LoadVersion ( defaultVersion , error , warnings ) ;
2016-11-05 15:28:14 +01:00
g_gui . PopupDialog ( " Error " , error , wxOK ) ;
g_gui . ListDialog ( " Warnings " , warnings ) ;
2012-06-29 16:44:26 +02:00
} else {
throw std : : runtime_error ( " All maps of different versions were not closed. " ) ;
}
}
2023-10-09 19:12:16 -07:00
if ( ! ok ) {
2012-06-29 16:44:26 +02:00
throw std : : runtime_error ( " Couldn't load client version " ) ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
MapVersion version ;
2016-09-29 20:30:54 -03:00
version . otbm = g_gui . GetCurrentVersion ( ) . getPrefferedMapVersionID ( ) ;
version . client = g_gui . GetCurrentVersionID ( ) ;
2012-06-29 16:44:26 +02:00
map . convert ( version ) ;
map . height = 2048 ;
map . width = 2048 ;
static int unnamed_counter = 0 ;
std : : string sname = " Untitled- " + i2s ( + + unnamed_counter ) ;
map . name = sname + " .otbm " ;
2021-05-25 00:29:12 -03:00
map . spawnmonsterfile = sname + " -monster.xml " ;
map . spawnnpcfile = sname + " -npc.xml " ;
2012-06-29 16:44:26 +02:00
map . housefile = sname + " -house.xml " ;
map . description = " No map description available. " ;
map . unnamed = true ;
map . doChange ( ) ;
}
2023-10-09 19:12:16 -07:00
Editor : : Editor ( CopyBuffer & copybuffer , const FileName & fn ) :
2014-01-22 20:16:17 +01:00
live_server ( nullptr ) ,
2014-01-23 21:06:52 -02:00
live_client ( nullptr ) ,
2023-10-15 18:51:57 -03:00
actionQueue ( newd < ActionQueue > ( * this ) ) ,
2012-06-29 16:44:26 +02:00
selection ( * this ) ,
copybuffer ( copybuffer ) ,
2023-10-09 19:12:16 -07:00
replace_brush ( nullptr ) {
2012-07-04 16:47:29 +02:00
MapVersion ver ;
2023-10-09 19:12:16 -07:00
if ( ! IOMapOTBM : : getVersionInfo ( fn , ver ) ) {
2016-11-05 15:28:14 +01:00
// g_gui.PopupDialog("Error", "Could not open file \"" + fn.GetFullPath() + "\".", wxOK);
2012-07-04 17:05:30 +02:00
throw std : : runtime_error ( " Could not open file \" " + nstr ( fn . GetFullPath ( ) ) + " \" . \n This is not a valid OTBM file or it does not exist. " ) ;
2012-06-29 16:44:26 +02:00
}
/*
if ( ver < CLIENT_VERSION_760 ) {
2016-11-05 15:28:14 +01:00
long b = g_gui . PopupDialog ( " Error " , " Unsupported Client Version (pre 7.6), do you want to try to load the map anyways? " , wxYES | wxNO ) ;
2012-06-29 16:44:26 +02:00
if ( b = = wxID_NO ) {
valid_state = false ;
return ;
}
}
*/
bool success = true ;
2023-10-09 19:12:16 -07:00
if ( g_gui . GetCurrentVersionID ( ) ! = ver . client ) {
2012-06-29 16:44:26 +02:00
wxString error ;
wxArrayString warnings ;
2023-10-09 19:12:16 -07:00
if ( g_gui . CloseAllEditors ( ) ) {
2016-09-29 20:30:54 -03:00
success = g_gui . LoadVersion ( ver . client , error , warnings ) ;
2023-10-09 19:12:16 -07:00
if ( ! success ) {
2016-11-05 15:28:14 +01:00
g_gui . PopupDialog ( " Error " , error , wxOK ) ;
2023-10-09 19:12:16 -07:00
} else {
2016-11-05 15:28:14 +01:00
g_gui . ListDialog ( " Warnings " , warnings ) ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
} else {
throw std : : runtime_error ( " All maps of different versions were not closed. " ) ;
}
}
2023-10-09 19:12:16 -07:00
if ( success ) {
2012-07-04 17:00:14 +02:00
ScopedLoadingBar LoadingBar ( " Loading OTBM map... " ) ;
2012-07-04 16:47:29 +02:00
success = map . open ( nstr ( fn . GetFullPath ( ) ) ) ;
2012-07-01 19:06:30 +02:00
/* TODO
2015-12-06 11:42:37 -03:00
if ( success & & ver . client = = CLIENT_VERSION_854_BAD ) {
2016-11-05 15:28:14 +01:00
int ok = g_gui . PopupDialog ( " Incorrect OTB " , " This map has been saved with an incorrect OTB version, do you want to convert it to the new OTB version? \n \n If you are not sure, click Yes. " , wxYES | wxNO ) ;
2016-09-29 19:24:45 -03:00
2012-06-29 16:44:26 +02:00
if ( ok = = wxID_YES ) {
ver . client = CLIENT_VERSION_854 ;
map . convert ( ver ) ;
}
}
2012-07-01 13:41:59 +02:00
*/
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
Editor : : Editor ( CopyBuffer & copybuffer , LiveClient * client ) :
2014-01-22 20:16:17 +01:00
live_server ( nullptr ) ,
2012-06-29 16:44:26 +02:00
live_client ( client ) ,
2023-10-15 18:51:57 -03:00
actionQueue ( newd < NetworkedActionQueue > ( * this ) ) ,
2012-06-29 16:44:26 +02:00
selection ( * this ) ,
copybuffer ( copybuffer ) ,
2023-10-09 19:12:16 -07:00
replace_brush ( nullptr ) {
2012-06-29 16:44:26 +02:00
;
}
2023-10-09 19:12:16 -07:00
Editor : : ~ Editor ( ) {
if ( IsLive ( ) ) {
2012-06-29 16:44:26 +02:00
CloseLiveServer ( ) ;
2014-02-21 13:55:09 +01:00
}
2012-06-29 16:44:26 +02:00
UnnamedRenderingLock ( ) ;
selection . clear ( ) ;
}
2023-10-09 19:12:16 -07:00
Action * Editor : : createAction ( ActionIdentifier type ) {
2023-10-09 23:02:37 -03:00
return actionQueue - > createAction ( type ) ;
}
2023-10-09 19:12:16 -07:00
Action * Editor : : createAction ( BatchAction * parent ) {
2023-10-09 23:02:37 -03:00
return actionQueue - > createAction ( parent ) ;
}
2023-10-09 19:12:16 -07:00
BatchAction * Editor : : createBatch ( ActionIdentifier type ) {
2023-10-09 23:02:37 -03:00
return actionQueue - > createBatch ( type ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : addBatch ( BatchAction * action , int stacking_delay ) {
2012-06-29 16:44:26 +02:00
actionQueue - > addBatch ( action , stacking_delay ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : addAction ( Action * action , int stacking_delay ) {
2012-06-29 16:44:26 +02:00
actionQueue - > addAction ( action , stacking_delay ) ;
2023-10-09 23:02:37 -03:00
}
2023-10-09 19:12:16 -07:00
bool Editor : : canUndo ( ) const {
2023-10-09 23:02:37 -03:00
return actionQueue - > canUndo ( ) ;
}
2023-10-09 19:12:16 -07:00
bool Editor : : canRedo ( ) const {
2023-10-09 23:02:37 -03:00
return actionQueue - > canRedo ( ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : undo ( int indexes ) {
if ( indexes < = 0 | | ! actionQueue - > canUndo ( ) ) {
2023-10-09 23:02:37 -03:00
return ;
2023-10-09 19:12:16 -07:00
}
2023-10-09 23:02:37 -03:00
2023-10-09 19:12:16 -07:00
while ( indexes > 0 ) {
if ( ! actionQueue - > undo ( ) ) {
2023-10-09 23:02:37 -03:00
break ;
2023-10-09 19:12:16 -07:00
}
2023-10-09 23:02:37 -03:00
indexes - - ;
}
g_gui . UpdateActions ( ) ;
g_gui . RefreshView ( ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : redo ( int indexes ) {
if ( indexes < = 0 | | ! actionQueue - > canRedo ( ) ) {
2023-10-09 23:02:37 -03:00
return ;
2023-10-09 19:12:16 -07:00
}
2023-10-09 23:02:37 -03:00
2023-10-09 19:12:16 -07:00
while ( indexes > 0 ) {
if ( ! actionQueue - > redo ( ) ) {
2023-10-09 23:02:37 -03:00
break ;
2023-10-09 19:12:16 -07:00
}
2023-10-09 23:02:37 -03:00
indexes - - ;
}
g_gui . UpdateActions ( ) ;
g_gui . RefreshView ( ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : updateActions ( ) {
2023-10-09 23:02:37 -03:00
actionQueue - > generateLabels ( ) ;
2016-09-29 20:30:54 -03:00
g_gui . UpdateMenus ( ) ;
2023-10-09 23:02:37 -03:00
g_gui . UpdateActions ( ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : resetActionsTimer ( ) {
2023-10-09 23:02:37 -03:00
actionQueue - > resetTimer ( ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : clearActions ( ) {
2023-10-09 23:02:37 -03:00
actionQueue - > clear ( ) ;
g_gui . UpdateActions ( ) ;
}
2023-10-09 19:12:16 -07:00
bool Editor : : hasChanges ( ) const {
if ( map . hasChanged ( ) ) {
if ( map . getTileCount ( ) = = 0 ) {
2023-10-09 23:02:37 -03:00
return actionQueue - > hasChanges ( ) ;
}
return true ;
}
return false ;
}
2023-10-09 19:12:16 -07:00
void Editor : : clearChanges ( ) {
2023-10-09 23:02:37 -03:00
map . clearChanges ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void Editor : : saveMap ( FileName filename , bool showdialog ) {
2014-01-21 16:09:35 -02:00
std : : string savefile = filename . GetFullPath ( ) . mb_str ( wxConvUTF8 ) . data ( ) ;
2012-07-04 21:51:12 +02:00
bool save_as = false ;
bool save_otgz = false ;
2023-10-09 19:12:16 -07:00
if ( savefile . empty ( ) ) {
2012-06-29 16:44:26 +02:00
savefile = map . filename ;
2016-09-29 19:24:45 -03:00
2012-07-04 21:51:12 +02:00
FileName c1 ( wxstr ( savefile ) ) ;
FileName c2 ( wxstr ( map . filename ) ) ;
save_as = c1 ! = c2 ;
2012-06-29 16:44:26 +02:00
}
2012-07-04 21:51:12 +02:00
// If not named yet, propagate the file name to the auxilliary files
2023-10-09 19:12:16 -07:00
if ( map . unnamed ) {
2012-06-29 16:44:26 +02:00
FileName _name ( filename ) ;
2016-11-05 15:28:14 +01:00
_name . SetExt ( " xml " ) ;
2012-06-29 16:44:26 +02:00
2021-05-25 00:29:12 -03:00
_name . SetName ( filename . GetName ( ) + " -monster " ) ;
map . spawnmonsterfile = nstr ( _name . GetFullName ( ) ) ;
_name . SetName ( filename . GetName ( ) + " -npc " ) ;
map . spawnnpcfile = nstr ( _name . GetFullName ( ) ) ;
2016-11-05 15:28:14 +01:00
_name . SetName ( filename . GetName ( ) + " -house " ) ;
2012-06-29 16:44:26 +02:00
map . housefile = nstr ( _name . GetFullName ( ) ) ;
2012-07-04 21:51:12 +02:00
map . unnamed = false ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 19:24:45 -03:00
2012-06-29 16:44:26 +02:00
// File object to convert between local paths etc.
FileName converter ;
converter . Assign ( wxstr ( savefile ) ) ;
std : : string map_path = nstr ( converter . GetPath ( wxPATH_GET_SEPARATOR | wxPATH_GET_VOLUME ) ) ;
// Make temporary backups
2023-10-09 19:12:16 -07:00
// converter.Assign(wxstr(savefile));
2021-05-25 00:29:12 -03:00
std : : string backup_otbm , backup_house , backup_spawn , backup_spawn_npc ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( converter . GetExt ( ) = = " otgz " ) {
2012-07-04 21:51:12 +02:00
save_otgz = true ;
2023-10-09 19:12:16 -07:00
if ( converter . FileExists ( ) ) {
2012-07-04 21:51:12 +02:00
backup_otbm = map_path + nstr ( converter . GetName ( ) ) + " .otgz~ " ;
std : : remove ( backup_otbm . c_str ( ) ) ;
std : : rename ( savefile . c_str ( ) , backup_otbm . c_str ( ) ) ;
}
2015-12-06 11:42:37 -03:00
} else {
2023-10-09 19:12:16 -07:00
if ( converter . FileExists ( ) ) {
2012-07-04 21:51:12 +02:00
backup_otbm = map_path + nstr ( converter . GetName ( ) ) + " .otbm~ " ;
std : : remove ( backup_otbm . c_str ( ) ) ;
std : : rename ( savefile . c_str ( ) , backup_otbm . c_str ( ) ) ;
}
2012-06-29 16:44:26 +02:00
2012-07-04 21:51:12 +02:00
converter . SetFullName ( wxstr ( map . housefile ) ) ;
2023-10-09 19:12:16 -07:00
if ( converter . FileExists ( ) ) {
2012-07-04 21:51:12 +02:00
backup_house = map_path + nstr ( converter . GetName ( ) ) + " .xml~ " ;
std : : remove ( backup_house . c_str ( ) ) ;
std : : rename ( ( map_path + map . housefile ) . c_str ( ) , backup_house . c_str ( ) ) ;
}
2021-05-25 00:29:12 -03:00
converter . SetFullName ( wxstr ( map . spawnmonsterfile ) ) ;
2023-10-09 19:12:16 -07:00
if ( converter . FileExists ( ) ) {
2012-07-04 21:51:12 +02:00
backup_spawn = map_path + nstr ( converter . GetName ( ) ) + " .xml~ " ;
std : : remove ( backup_spawn . c_str ( ) ) ;
2021-05-25 00:29:12 -03:00
std : : rename ( ( map_path + map . spawnmonsterfile ) . c_str ( ) , backup_spawn . c_str ( ) ) ;
}
converter . SetFullName ( wxstr ( map . spawnnpcfile ) ) ;
2023-10-09 19:12:16 -07:00
if ( converter . FileExists ( ) ) {
2021-05-25 00:29:12 -03:00
backup_spawn_npc = map_path + nstr ( converter . GetName ( ) ) + " .xml~ " ;
std : : remove ( backup_spawn_npc . c_str ( ) ) ;
std : : rename ( ( map_path + map . spawnnpcfile ) . c_str ( ) , backup_spawn_npc . c_str ( ) ) ;
2012-07-04 21:51:12 +02:00
}
2012-06-29 16:44:26 +02:00
}
// Save the map
{
2016-09-29 20:30:54 -03:00
std : : string n = nstr ( g_gui . GetLocalDataDirectory ( ) ) + " .saving.txt " ;
2012-06-29 16:44:26 +02:00
std : : ofstream f ( n . c_str ( ) , std : : ios : : trunc | std : : ios : : out ) ;
2023-10-09 19:12:16 -07:00
f < < backup_otbm < < std : : endl
< < backup_house < < std : : endl
< < backup_spawn < < std : : endl
< < backup_spawn_npc < < std : : endl ;
2012-06-29 16:44:26 +02:00
}
{
2012-07-04 21:51:12 +02:00
// Set up the Map paths
2012-06-29 16:44:26 +02:00
wxFileName fn = wxstr ( savefile ) ;
map . filename = fn . GetFullPath ( ) . mb_str ( wxConvUTF8 ) ;
map . name = fn . GetFullName ( ) . mb_str ( wxConvUTF8 ) ;
2023-10-09 19:12:16 -07:00
if ( showdialog ) {
2016-09-29 20:30:54 -03:00
g_gui . CreateLoadBar ( " Saving OTBM map... " ) ;
2023-10-09 19:12:16 -07:00
}
2016-09-29 19:24:45 -03:00
2012-07-04 21:51:12 +02:00
// Perform the actual save
IOMapOTBM mapsaver ( map . getVersion ( ) ) ;
2012-07-04 16:47:29 +02:00
bool success = mapsaver . saveMap ( map , fn ) ;
2012-07-04 21:51:12 +02:00
2023-10-09 19:12:16 -07:00
if ( showdialog ) {
2016-09-29 20:30:54 -03:00
g_gui . DestroyLoadBar ( ) ;
2023-10-09 19:12:16 -07:00
}
2012-07-04 21:51:12 +02:00
// Check for errors...
2023-10-09 19:12:16 -07:00
if ( ! success ) {
2012-07-04 21:51:12 +02:00
// Rename the temporary backup files back to their previous names
2023-10-09 19:12:16 -07:00
if ( ! backup_otbm . empty ( ) ) {
2012-06-29 16:44:26 +02:00
converter . SetFullName ( wxstr ( savefile ) ) ;
std : : string otbm_filename = map_path + nstr ( converter . GetName ( ) ) ;
2012-07-04 21:51:12 +02:00
std : : rename ( backup_otbm . c_str ( ) , std : : string ( otbm_filename + ( save_otgz ? " .otgz " : " .otbm " ) ) . c_str ( ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( ! backup_house . empty ( ) ) {
2012-06-29 16:44:26 +02:00
converter . SetFullName ( wxstr ( map . housefile ) ) ;
std : : string house_filename = map_path + nstr ( converter . GetName ( ) ) ;
std : : rename ( backup_house . c_str ( ) , std : : string ( house_filename + " .xml " ) . c_str ( ) ) ;
}
2023-10-09 19:12:16 -07:00
if ( ! backup_spawn . empty ( ) ) {
2021-05-25 00:29:12 -03:00
converter . SetFullName ( wxstr ( map . spawnmonsterfile ) ) ;
2012-06-29 16:44:26 +02:00
std : : string spawn_filename = map_path + nstr ( converter . GetName ( ) ) ;
std : : rename ( backup_spawn . c_str ( ) , std : : string ( spawn_filename + " .xml " ) . c_str ( ) ) ;
}
2012-07-04 21:51:12 +02:00
2023-10-09 19:12:16 -07:00
if ( ! backup_spawn_npc . empty ( ) ) {
2021-05-25 00:29:12 -03:00
converter . SetFullName ( wxstr ( map . spawnnpcfile ) ) ;
std : : string spawnnpc_filename = map_path + nstr ( converter . GetName ( ) ) ;
std : : rename ( backup_spawn_npc . c_str ( ) , std : : string ( spawnnpc_filename + " .xml " ) . c_str ( ) ) ;
}
2012-07-04 21:51:12 +02:00
// Display the error
2016-11-05 15:28:14 +01:00
g_gui . PopupDialog ( " Error " , " Could not save, unable to open target for writing. " , wxOK ) ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 19:24:45 -03:00
2012-06-29 16:44:26 +02:00
// Remove temporary save runfile
{
2016-09-29 20:30:54 -03:00
std : : string n = nstr ( g_gui . GetLocalDataDirectory ( ) ) + " .saving.txt " ;
2012-06-29 16:44:26 +02:00
std : : remove ( n . c_str ( ) ) ;
}
// If failure, don't run the rest of the function
2023-10-09 19:12:16 -07:00
if ( ! success ) {
2012-06-29 16:44:26 +02:00
return ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
}
2016-09-29 19:24:45 -03:00
2012-06-29 16:44:26 +02:00
// Move to permanent backup
2023-10-09 19:12:16 -07:00
if ( ! save_as & & g_settings . getInteger ( Config : : ALWAYS_MAKE_BACKUP ) ) {
2012-06-29 16:44:26 +02:00
// Move temporary backups to their proper files
2014-01-22 20:16:17 +01:00
time_t t = time ( nullptr ) ;
2012-06-29 16:44:26 +02:00
tm * current_time = localtime ( & t ) ;
ASSERT ( current_time ) ;
std : : ostringstream date ;
date < < ( 1900 + current_time - > tm_year ) ;
2023-10-09 19:12:16 -07:00
if ( current_time - > tm_mon < 9 ) {
date < < " - "
< < " 0 " < < current_time - > tm_mon + 1 ;
} else {
date < < " - " < < current_time - > tm_mon + 1 ;
}
2012-06-29 16:44:26 +02:00
date < < " - " < < current_time - > tm_mday ;
date < < " - " < < current_time - > tm_hour ;
date < < " - " < < current_time - > tm_min ;
date < < " - " < < current_time - > tm_sec ;
2023-10-09 19:12:16 -07:00
if ( ! backup_otbm . empty ( ) ) {
2012-06-29 16:44:26 +02:00
converter . SetFullName ( wxstr ( savefile ) ) ;
std : : string otbm_filename = map_path + nstr ( converter . GetName ( ) ) ;
2012-07-04 21:51:12 +02:00
std : : rename ( backup_otbm . c_str ( ) , std : : string ( otbm_filename + " . " + date . str ( ) + ( save_otgz ? " .otgz " : " .otbm " ) ) . c_str ( ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( ! backup_house . empty ( ) ) {
2012-06-29 16:44:26 +02:00
converter . SetFullName ( wxstr ( map . housefile ) ) ;
std : : string house_filename = map_path + nstr ( converter . GetName ( ) ) ;
std : : rename ( backup_house . c_str ( ) , std : : string ( house_filename + " . " + date . str ( ) + " .xml " ) . c_str ( ) ) ;
}
2023-10-09 19:12:16 -07:00
if ( ! backup_spawn . empty ( ) ) {
2021-05-25 00:29:12 -03:00
converter . SetFullName ( wxstr ( map . spawnmonsterfile ) ) ;
2012-06-29 16:44:26 +02:00
std : : string spawn_filename = map_path + nstr ( converter . GetName ( ) ) ;
std : : rename ( backup_spawn . c_str ( ) , std : : string ( spawn_filename + " . " + date . str ( ) + " .xml " ) . c_str ( ) ) ;
}
2023-09-08 03:04:02 -03:00
2023-10-09 19:12:16 -07:00
if ( ! backup_spawn_npc . empty ( ) ) {
2021-05-25 00:29:12 -03:00
converter . SetFullName ( wxstr ( map . spawnnpcfile ) ) ;
std : : string spawnnpc_filename = map_path + nstr ( converter . GetName ( ) ) ;
std : : rename ( backup_spawn_npc . c_str ( ) , std : : string ( spawnnpc_filename + " . " + date . str ( ) + " .xml " ) . c_str ( ) ) ;
}
2015-12-06 11:42:37 -03:00
} else {
2012-06-29 16:44:26 +02:00
// Delete the temporary files
std : : remove ( backup_otbm . c_str ( ) ) ;
std : : remove ( backup_house . c_str ( ) ) ;
std : : remove ( backup_spawn . c_str ( ) ) ;
2021-05-25 00:29:12 -03:00
std : : remove ( backup_spawn_npc . c_str ( ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
clearChanges ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
bool Editor : : importMiniMap ( FileName filename , int import , int import_x_offset , int import_y_offset , int import_z_offset ) {
2012-06-29 16:44:26 +02:00
return false ;
}
2023-10-09 19:12:16 -07:00
bool Editor : : importMap ( FileName filename , int import_x_offset , int import_y_offset , int import_z_offset , ImportType house_import_type , ImportType spawn_import_type , ImportType spawn_npc_import_type ) {
2012-07-04 21:51:12 +02:00
selection . clear ( ) ;
2012-06-29 16:44:26 +02:00
actionQueue - > clear ( ) ;
Map imported_map ;
2012-07-04 16:47:29 +02:00
bool loaded = imported_map . open ( nstr ( filename . GetFullPath ( ) ) ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( ! loaded ) {
2016-11-05 15:28:14 +01:00
g_gui . PopupDialog ( " Error " , " Error loading map! \n " + imported_map . getError ( ) , wxOK | wxICON_INFORMATION ) ;
2012-06-29 16:44:26 +02:00
return false ;
}
2016-11-05 15:28:14 +01:00
g_gui . ListDialog ( " Warning " , imported_map . getWarnings ( ) ) ;
2012-06-29 16:44:26 +02:00
2022-04-03 03:10:34 +02:00
Position offset ( import_x_offset , import_y_offset , import_z_offset ) ;
2012-06-29 16:44:26 +02:00
bool resizemap = false ;
bool resize_asked = false ;
int newsize_x = map . getWidth ( ) , newsize_y = map . getHeight ( ) ;
int discarded_tiles = 0 ;
2016-11-05 15:28:14 +01:00
g_gui . CreateLoadBar ( " Merging maps... " ) ;
2012-06-29 16:44:26 +02:00
std : : map < uint32_t , uint32_t > town_id_map ;
std : : map < uint32_t , uint32_t > house_id_map ;
2023-10-09 19:12:16 -07:00
if ( house_import_type ! = IMPORT_DONT ) {
2023-10-15 18:51:57 -03:00
for ( TownMap : : iterator tit = imported_map . towns - > begin ( ) ; tit ! = imported_map . towns - > end ( ) ; ) {
auto imported_town = tit - > second ;
auto current_town = map . towns - > getTown ( imported_town - > getID ( ) ) ;
2012-06-29 16:44:26 +02:00
Position oldexit = imported_town - > getTemplePosition ( ) ;
Position newexit = oldexit + offset ;
2023-10-09 19:12:16 -07:00
if ( newexit . isValid ( ) ) {
2012-06-29 16:44:26 +02:00
imported_town - > setTemplePosition ( newexit ) ;
}
2023-10-09 19:12:16 -07:00
switch ( house_import_type ) {
2012-06-29 16:44:26 +02:00
case IMPORT_MERGE : {
town_id_map [ imported_town - > getID ( ) ] = imported_town - > getID ( ) ;
2023-10-09 19:12:16 -07:00
if ( current_town ) {
2012-06-29 16:44:26 +02:00
+ + tit ;
continue ;
}
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
case IMPORT_SMART_MERGE : {
2023-10-09 19:12:16 -07:00
if ( current_town ) {
2012-06-29 16:44:26 +02:00
// Compare and insert/merge depending on parameters
2023-10-09 19:12:16 -07:00
if ( current_town - > getName ( ) = = imported_town - > getName ( ) & & current_town - > getID ( ) = = imported_town - > getID ( ) ) {
2012-06-29 16:44:26 +02:00
// Just add to map
town_id_map [ imported_town - > getID ( ) ] = current_town - > getID ( ) ;
+ + tit ;
continue ;
} else {
// Conflict! Find a newd id and replace old
2023-10-15 18:51:57 -03:00
uint32_t new_id = map . towns - > getEmptyID ( ) ;
2012-06-29 16:44:26 +02:00
imported_town - > setID ( new_id ) ;
town_id_map [ imported_town - > getID ( ) ] = new_id ;
}
} else {
town_id_map [ imported_town - > getID ( ) ] = imported_town - > getID ( ) ;
}
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
case IMPORT_INSERT : {
// Find a newd id and replace old
2023-10-15 18:51:57 -03:00
uint32_t new_id = map . towns - > getEmptyID ( ) ;
2012-06-29 16:44:26 +02:00
imported_town - > setID ( new_id ) ;
town_id_map [ imported_town - > getID ( ) ] = new_id ;
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
case IMPORT_DONT : {
+ + tit ;
continue ; // Should never happend..?
2015-12-06 11:42:37 -03:00
break ; // Continue or break ?
}
2012-06-29 16:44:26 +02:00
}
2023-10-15 18:51:57 -03:00
map . towns - > addTown ( imported_town ) ;
2012-06-29 16:44:26 +02:00
# ifdef __VISUALC__ // C++0x compliance to some degree :)
2023-10-15 18:51:57 -03:00
tit = imported_map . towns - > erase ( tit ) ;
2012-06-29 16:44:26 +02:00
# else // Bulky, slow way
TownMap : : iterator tmp_iter = tit ;
+ + tmp_iter ;
uint32_t next_key = 0 ;
2023-10-09 19:12:16 -07:00
if ( tmp_iter ! = imported_map . towns . end ( ) ) {
2012-06-29 16:44:26 +02:00
next_key = tmp_iter - > first ;
}
imported_map . towns . erase ( tit ) ;
2023-10-09 19:12:16 -07:00
if ( next_key ! = 0 ) {
2012-06-29 16:44:26 +02:00
tit = imported_map . towns . find ( next_key ) ;
} else {
tit = imported_map . towns . end ( ) ;
}
# endif
}
2015-12-06 11:42:37 -03:00
2023-10-09 19:12:16 -07:00
for ( HouseMap : : iterator hit = imported_map . houses . begin ( ) ; hit ! = imported_map . houses . end ( ) ; ) {
2012-06-29 16:44:26 +02:00
House * imported_house = hit - > second ;
House * current_house = map . houses . getHouse ( imported_house - > id ) ;
imported_house - > townid = town_id_map [ imported_house - > townid ] ;
2023-10-09 19:12:16 -07:00
const Position & oldexit = imported_house - > getExit ( ) ;
2014-01-22 20:16:17 +01:00
imported_house - > setExit ( nullptr , Position ( ) ) ; // Reset it
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
switch ( house_import_type ) {
2012-06-29 16:44:26 +02:00
case IMPORT_MERGE : {
house_id_map [ imported_house - > id ] = imported_house - > id ;
2023-10-09 19:12:16 -07:00
if ( current_house ) {
2012-06-29 16:44:26 +02:00
+ + hit ;
Position newexit = oldexit + offset ;
2023-10-09 19:12:16 -07:00
if ( newexit . isValid ( ) ) {
current_house - > setExit ( & map , newexit ) ;
}
2012-06-29 16:44:26 +02:00
continue ;
}
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
case IMPORT_SMART_MERGE : {
2023-10-09 19:12:16 -07:00
if ( current_house ) {
2012-06-29 16:44:26 +02:00
// Compare and insert/merge depending on parameters
2023-10-09 19:12:16 -07:00
if ( current_house - > name = = imported_house - > name & & current_house - > townid = = imported_house - > townid ) {
2012-06-29 16:44:26 +02:00
// Just add to map
house_id_map [ imported_house - > id ] = current_house - > id ;
+ + hit ;
Position newexit = oldexit + offset ;
2023-10-09 19:12:16 -07:00
if ( newexit . isValid ( ) ) {
imported_house - > setExit ( & map , newexit ) ;
}
2012-06-29 16:44:26 +02:00
continue ;
} else {
// Conflict! Find a newd id and replace old
uint32_t new_id = map . houses . getEmptyID ( ) ;
house_id_map [ imported_house - > id ] = new_id ;
imported_house - > id = new_id ;
}
} else {
house_id_map [ imported_house - > id ] = imported_house - > id ;
}
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
case IMPORT_INSERT : {
// Find a newd id and replace old
uint32_t new_id = map . houses . getEmptyID ( ) ;
house_id_map [ imported_house - > id ] = new_id ;
imported_house - > id = new_id ;
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
case IMPORT_DONT : {
+ + hit ;
Position newexit = oldexit + offset ;
2023-10-09 19:12:16 -07:00
if ( newexit . isValid ( ) ) {
imported_house - > setExit ( & map , newexit ) ;
}
continue ; // Should never happend..?
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
}
Position newexit = oldexit + offset ;
2023-10-09 19:12:16 -07:00
if ( newexit . isValid ( ) ) {
imported_house - > setExit ( & map , newexit ) ;
}
2012-06-29 16:44:26 +02:00
map . houses . addHouse ( imported_house ) ;
# ifdef __VISUALC__ // C++0x compliance to some degree :)
hit = imported_map . houses . erase ( hit ) ;
# else // Bulky, slow way
HouseMap : : iterator tmp_iter = hit ;
+ + tmp_iter ;
uint32_t next_key = 0 ;
2023-10-09 19:12:16 -07:00
if ( tmp_iter ! = imported_map . houses . end ( ) ) {
2012-06-29 16:44:26 +02:00
next_key = tmp_iter - > first ;
}
imported_map . houses . erase ( hit ) ;
2023-10-09 19:12:16 -07:00
if ( next_key ! = 0 ) {
2012-06-29 16:44:26 +02:00
hit = imported_map . houses . find ( next_key ) ;
} else {
hit = imported_map . houses . end ( ) ;
}
# endif
}
}
2021-05-25 00:29:12 -03:00
// Monster spawn import
2023-10-15 18:51:57 -03:00
std : : map < Position , std : : shared_ptr < SpawnMonster > > spawn_monster_map ;
2023-10-09 19:12:16 -07:00
if ( spawn_import_type ! = IMPORT_DONT ) {
for ( SpawnNpcPositionList : : iterator siter = imported_map . spawnsMonster . begin ( ) ; siter ! = imported_map . spawnsMonster . end ( ) ; ) {
2021-05-25 00:29:12 -03:00
Position oldSpawnMonsterPos = * siter ;
Position newSpawnMonsterPos = * siter + offset ;
2023-10-09 19:12:16 -07:00
switch ( spawn_import_type ) {
2012-06-29 16:44:26 +02:00
case IMPORT_SMART_MERGE :
case IMPORT_INSERT :
2015-12-06 11:42:37 -03:00
case IMPORT_MERGE : {
2021-05-25 00:29:12 -03:00
Tile * imported_tile = imported_map . getTile ( oldSpawnMonsterPos ) ;
2023-10-09 19:12:16 -07:00
if ( imported_tile ) {
2021-05-25 00:29:12 -03:00
ASSERT ( imported_tile - > spawnMonster ) ;
spawn_monster_map [ newSpawnMonsterPos ] = imported_tile - > spawnMonster ;
SpawnNpcPositionList : : iterator next = siter ;
bool cont = true ;
Position next_spawn_monster ;
+ + next ;
2023-10-09 19:12:16 -07:00
if ( next = = imported_map . spawnsMonster . end ( ) ) {
2021-05-25 00:29:12 -03:00
cont = false ;
2023-10-09 19:12:16 -07:00
} else {
2021-05-25 00:29:12 -03:00
next_spawn_monster = * next ;
2023-10-09 19:12:16 -07:00
}
2021-05-25 00:29:12 -03:00
imported_map . spawnsMonster . erase ( siter ) ;
2023-10-09 19:12:16 -07:00
if ( cont ) {
2021-05-25 00:29:12 -03:00
siter = imported_map . spawnsMonster . find ( next_spawn_monster ) ;
2023-10-09 19:12:16 -07:00
} else {
2021-05-25 00:29:12 -03:00
siter = imported_map . spawnsMonster . end ( ) ;
2023-10-09 19:12:16 -07:00
}
2021-05-25 00:29:12 -03:00
}
break ;
}
case IMPORT_DONT : {
+ + siter ;
break ;
}
}
}
}
2012-06-29 16:44:26 +02:00
2021-05-25 00:29:12 -03:00
// Npc spawn import
std : : map < Position , SpawnNpc * > spawn_npc_map ;
2023-10-09 19:12:16 -07:00
if ( spawn_npc_import_type ! = IMPORT_DONT ) {
for ( SpawnNpcPositionList : : iterator siter = imported_map . spawnsNpc . begin ( ) ; siter ! = imported_map . spawnsNpc . end ( ) ; ) {
2021-05-25 00:29:12 -03:00
Position oldSpawnNpcPos = * siter ;
Position newSpawnNpcPos = * siter + offset ;
2023-10-09 19:12:16 -07:00
switch ( spawn_npc_import_type ) {
2021-05-25 00:29:12 -03:00
case IMPORT_SMART_MERGE :
case IMPORT_INSERT :
case IMPORT_MERGE : {
Tile * importedTile = imported_map . getTile ( oldSpawnNpcPos ) ;
2023-10-09 19:12:16 -07:00
if ( importedTile ) {
2021-05-25 00:29:12 -03:00
ASSERT ( importedTile - > spawnNpc ) ;
spawn_npc_map [ newSpawnNpcPos ] = importedTile - > spawnNpc ;
SpawnNpcPositionList : : iterator next = siter ;
2012-06-29 16:44:26 +02:00
bool cont = true ;
2021-05-25 00:29:12 -03:00
Position next_spawn_npc ;
2012-06-29 16:44:26 +02:00
+ + next ;
2023-10-09 19:12:16 -07:00
if ( next = = imported_map . spawnsNpc . end ( ) ) {
2012-06-29 16:44:26 +02:00
cont = false ;
2023-10-09 19:12:16 -07:00
} else {
2021-05-25 00:29:12 -03:00
next_spawn_npc = * next ;
2023-10-09 19:12:16 -07:00
}
2021-05-25 00:29:12 -03:00
imported_map . spawnsNpc . erase ( siter ) ;
2023-10-09 19:12:16 -07:00
if ( cont ) {
2021-05-25 00:29:12 -03:00
siter = imported_map . spawnsNpc . find ( next_spawn_npc ) ;
2023-10-09 19:12:16 -07:00
} else {
2021-05-25 00:29:12 -03:00
siter = imported_map . spawnsNpc . end ( ) ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
}
2015-12-06 11:42:37 -03:00
break ;
}
case IMPORT_DONT : {
2012-06-29 16:44:26 +02:00
+ + siter ;
2015-12-06 11:42:37 -03:00
break ;
}
2012-06-29 16:44:26 +02:00
}
}
}
// Plain merge of waypoints, very simple! :)
2023-10-09 19:12:16 -07:00
for ( WaypointMap : : iterator iter = imported_map . waypoints . begin ( ) ; iter ! = imported_map . waypoints . end ( ) ; + + iter ) {
2012-06-29 16:44:26 +02:00
iter - > second - > pos + = offset ;
}
map . waypoints . waypoints . insert ( imported_map . waypoints . begin ( ) , imported_map . waypoints . end ( ) ) ;
imported_map . waypoints . waypoints . clear ( ) ;
uint64_t tiles_merged = 0 ;
uint64_t tiles_to_import = imported_map . tilecount ;
2023-10-09 19:12:16 -07:00
for ( MapIterator mit = imported_map . begin ( ) ; mit ! = imported_map . end ( ) ; + + mit ) {
if ( tiles_merged % 8092 = = 0 ) {
2016-09-29 20:30:54 -03:00
g_gui . SetLoadDone ( int ( 100.0 * tiles_merged / tiles_to_import ) ) ;
2012-06-29 16:44:26 +02:00
}
+ + tiles_merged ;
Tile * import_tile = ( * mit ) - > get ( ) ;
Position new_pos = import_tile - > getPosition ( ) + offset ;
2023-10-09 19:12:16 -07:00
if ( ! new_pos . isValid ( ) ) {
2012-06-29 16:44:26 +02:00
+ + discarded_tiles ;
continue ;
}
2023-10-09 19:12:16 -07:00
if ( ! resizemap & & ( new_pos . x > map . getWidth ( ) | | new_pos . y > map . getHeight ( ) ) ) {
if ( resize_asked ) {
2012-06-29 16:44:26 +02:00
+ + discarded_tiles ;
continue ;
} else {
resize_asked = true ;
2016-11-05 15:28:14 +01:00
int ret = g_gui . PopupDialog ( " Collision " , " The imported tiles are outside the current map scope. Do you want to resize the map? (Else additional tiles will be removed) " , wxYES | wxNO ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( ret = = wxID_YES ) {
2012-06-29 16:44:26 +02:00
// ...
resizemap = true ;
} else {
+ + discarded_tiles ;
continue ;
}
}
}
2023-10-09 19:12:16 -07:00
if ( new_pos . x > newsize_x ) {
2012-06-29 16:44:26 +02:00
newsize_x = new_pos . x ;
}
2023-10-09 19:12:16 -07:00
if ( new_pos . y > newsize_y ) {
2012-06-29 16:44:26 +02:00
newsize_y = new_pos . y ;
}
2014-01-22 20:16:17 +01:00
imported_map . setTile ( import_tile - > getPosition ( ) , nullptr ) ;
2012-06-29 16:44:26 +02:00
TileLocation * location = map . createTileL ( new_pos ) ;
// Check if we should update any houses
int new_houseid = house_id_map [ import_tile - > getHouseID ( ) ] ;
House * house = map . houses . getHouse ( new_houseid ) ;
2023-10-09 19:12:16 -07:00
if ( import_tile - > isHouseTile ( ) & & house_import_type ! = IMPORT_DONT & & house ) {
2012-06-29 16:44:26 +02:00
// We need to notify houses of the tile moving
house - > removeTile ( import_tile ) ;
import_tile - > setLocation ( location ) ;
house - > addTile ( import_tile ) ;
} else {
import_tile - > setLocation ( location ) ;
}
2023-10-09 19:12:16 -07:00
if ( offset ! = Position ( 0 , 0 , 0 ) ) {
for ( ItemVector : : iterator iter = import_tile - > items . begin ( ) ; iter ! = import_tile - > items . end ( ) ; + + iter ) {
2012-06-29 16:44:26 +02:00
Item * item = * iter ;
2023-10-09 19:12:16 -07:00
if ( Teleport * teleport = dynamic_cast < Teleport * > ( item ) ) {
2012-06-29 16:44:26 +02:00
teleport - > setDestination ( teleport - > getDestination ( ) + offset ) ;
}
}
}
Tile * old_tile = map . getTile ( new_pos ) ;
2023-10-09 19:12:16 -07:00
if ( old_tile ) {
2021-05-25 00:29:12 -03:00
map . removeSpawnMonster ( old_tile ) ;
2012-06-29 16:44:26 +02:00
}
2021-05-25 00:29:12 -03:00
import_tile - > spawnMonster = nullptr ;
2012-06-29 16:44:26 +02:00
map . setTile ( new_pos , import_tile , true ) ;
}
2023-10-15 18:51:57 -03:00
for ( std : : map < Position , std : : shared_ptr < SpawnMonster > > : : iterator spawn_monster_iter = spawn_monster_map . begin ( ) ; spawn_monster_iter ! = spawn_monster_map . end ( ) ; + + spawn_monster_iter ) {
2021-05-25 00:29:12 -03:00
Position pos = spawn_monster_iter - > first ;
2012-06-29 16:44:26 +02:00
TileLocation * location = map . createTileL ( pos ) ;
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! tile ) {
2012-06-29 16:44:26 +02:00
tile = map . allocator ( location ) ;
map . setTile ( pos , tile ) ;
2023-10-09 19:12:16 -07:00
} else if ( tile - > spawnMonster ) {
2021-05-25 00:29:12 -03:00
map . removeSpawnMonsterInternal ( tile ) ;
2012-06-29 16:44:26 +02:00
}
2021-05-25 00:29:12 -03:00
tile - > spawnMonster = spawn_monster_iter - > second ;
2012-06-29 16:44:26 +02:00
2021-05-25 00:29:12 -03:00
map . addSpawnMonster ( tile ) ;
}
2023-10-09 19:12:16 -07:00
for ( std : : map < Position , SpawnNpc * > : : iterator spawn_npc_iter = spawn_npc_map . begin ( ) ; spawn_npc_iter ! = spawn_npc_map . end ( ) ; + + spawn_npc_iter ) {
2021-05-25 00:29:12 -03:00
Position pos = spawn_npc_iter - > first ;
TileLocation * location = map . createTileL ( pos ) ;
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! tile ) {
2021-05-25 00:29:12 -03:00
tile = map . allocator ( location ) ;
map . setTile ( pos , tile ) ;
2023-10-09 19:12:16 -07:00
} else if ( tile - > spawnNpc ) {
2021-05-25 00:29:12 -03:00
map . removeSpawnNpcInternal ( tile ) ;
delete tile - > spawnNpc ;
}
tile - > spawnNpc = spawn_npc_iter - > second ;
map . addSpawnNpc ( tile ) ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 20:30:54 -03:00
g_gui . DestroyLoadBar ( ) ;
2012-06-29 16:44:26 +02:00
map . setWidth ( newsize_x ) ;
map . setHeight ( newsize_y ) ;
2016-11-05 15:28:14 +01:00
g_gui . PopupDialog ( " Success " , " Map imported successfully, " + i2ws ( discarded_tiles ) + " tiles were discarded as invalid. " , wxOK ) ;
2016-09-29 19:24:45 -03:00
2016-09-29 20:30:54 -03:00
g_gui . RefreshPalettes ( ) ;
g_gui . FitViewToMap ( ) ;
2012-06-29 16:44:26 +02:00
return true ;
}
2023-10-09 19:12:16 -07:00
void Editor : : borderizeSelection ( ) {
if ( selection . empty ( ) ) {
2016-11-05 15:28:14 +01:00
g_gui . SetStatusText ( " No items selected. Can't borderize. " ) ;
2023-10-09 23:02:37 -03:00
return ;
2012-06-29 16:44:26 +02:00
}
Action * action = actionQueue - > createAction ( ACTION_BORDERIZE ) ;
2023-10-09 19:12:16 -07:00
for ( const Tile * tile : selection ) {
2023-10-09 23:02:37 -03:00
Tile * new_tile = tile - > deepCopy ( map ) ;
new_tile - > borderize ( & map ) ;
new_tile - > select ( ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
addAction ( action ) ;
2023-10-09 23:02:37 -03:00
updateActions ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void Editor : : borderizeMap ( bool showdialog ) {
if ( showdialog ) {
2016-11-05 15:28:14 +01:00
g_gui . CreateLoadBar ( " Borderizing map... " ) ;
2012-06-29 16:44:26 +02:00
}
uint64_t tiles_done = 0 ;
2023-10-09 19:12:16 -07:00
for ( TileLocation * tileLocation : map ) {
if ( showdialog & & tiles_done % 4096 = = 0 ) {
2016-09-29 20:30:54 -03:00
g_gui . SetLoadDone ( static_cast < int32_t > ( tiles_done / double ( map . tilecount ) * 100.0 ) ) ;
2012-06-29 16:44:26 +02:00
}
2014-03-02 22:08:22 +01:00
Tile * tile = tileLocation - > get ( ) ;
2012-06-29 16:44:26 +02:00
ASSERT ( tile ) ;
2014-03-02 22:08:22 +01:00
2012-06-29 16:44:26 +02:00
tile - > borderize ( & map ) ;
2014-03-02 22:08:22 +01:00
+ + tiles_done ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( showdialog ) {
2016-09-29 20:30:54 -03:00
g_gui . DestroyLoadBar ( ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
void Editor : : randomizeSelection ( ) {
if ( selection . empty ( ) ) {
2016-11-05 15:28:14 +01:00
g_gui . SetStatusText ( " No items selected. Can't randomize. " ) ;
2023-10-09 23:02:37 -03:00
return ;
2012-06-29 16:44:26 +02:00
}
Action * action = actionQueue - > createAction ( ACTION_RANDOMIZE ) ;
2023-10-09 19:12:16 -07:00
for ( const Tile * tile : selection ) {
2023-10-09 23:02:37 -03:00
Tile * new_tile = tile - > deepCopy ( map ) ;
GroundBrush * brush = new_tile - > getGroundBrush ( ) ;
2023-10-09 19:12:16 -07:00
if ( brush & & brush - > isReRandomizable ( ) ) {
2023-10-09 23:02:37 -03:00
brush - > draw ( & map , new_tile , nullptr ) ;
Item * old_ground = tile - > ground ;
Item * new_ground = new_tile - > ground ;
2023-10-09 19:12:16 -07:00
if ( old_ground & & new_ground ) {
2023-10-09 23:02:37 -03:00
new_ground - > setActionID ( old_ground - > getActionID ( ) ) ;
new_ground - > setUniqueID ( old_ground - > getUniqueID ( ) ) ;
2012-06-29 16:44:26 +02:00
}
2014-03-02 22:08:22 +01:00
2023-10-09 23:02:37 -03:00
new_tile - > select ( ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
addAction ( action ) ;
2023-10-09 23:02:37 -03:00
updateActions ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void Editor : : randomizeMap ( bool showdialog ) {
if ( showdialog ) {
2016-11-05 15:28:14 +01:00
g_gui . CreateLoadBar ( " Randomizing map... " ) ;
2012-06-29 16:44:26 +02:00
}
uint64_t tiles_done = 0 ;
2023-10-09 19:12:16 -07:00
for ( TileLocation * tileLocation : map ) {
if ( showdialog & & tiles_done % 4096 = = 0 ) {
2016-09-29 20:30:54 -03:00
g_gui . SetLoadDone ( static_cast < int32_t > ( tiles_done / double ( map . tilecount ) * 100.0 ) ) ;
2012-06-29 16:44:26 +02:00
}
2014-03-02 22:08:22 +01:00
Tile * tile = tileLocation - > get ( ) ;
2012-06-29 16:44:26 +02:00
ASSERT ( tile ) ;
2014-03-02 22:08:22 +01:00
GroundBrush * groundBrush = tile - > getGroundBrush ( ) ;
2023-10-09 19:12:16 -07:00
if ( groundBrush ) {
2014-03-02 22:08:22 +01:00
Item * oldGround = tile - > ground ;
uint16_t actionId , uniqueId ;
2023-10-09 19:12:16 -07:00
if ( oldGround ) {
2014-03-02 22:08:22 +01:00
actionId = oldGround - > getActionID ( ) ;
uniqueId = oldGround - > getUniqueID ( ) ;
} else {
actionId = 0 ;
uniqueId = 0 ;
}
groundBrush - > draw ( & map , tile , nullptr ) ;
Item * newGround = tile - > ground ;
2023-10-09 19:12:16 -07:00
if ( newGround ) {
2014-03-02 22:08:22 +01:00
newGround - > setActionID ( actionId ) ;
newGround - > setUniqueID ( uniqueId ) ;
2012-06-29 16:44:26 +02:00
}
tile - > update ( ) ;
}
2014-03-02 22:08:22 +01:00
+ + tiles_done ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( showdialog ) {
2016-09-29 20:30:54 -03:00
g_gui . DestroyLoadBar ( ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
void Editor : : clearInvalidHouseTiles ( bool showdialog ) {
if ( showdialog ) {
2016-11-05 15:28:14 +01:00
g_gui . CreateLoadBar ( " Clearing invalid house tiles... " ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
Houses & houses = map . houses ;
2012-06-29 16:44:26 +02:00
HouseMap : : iterator iter = houses . begin ( ) ;
2023-10-09 19:12:16 -07:00
while ( iter ! = houses . end ( ) ) {
2012-06-29 16:44:26 +02:00
House * h = iter - > second ;
2023-10-15 18:51:57 -03:00
if ( map . towns - > getTown ( h - > townid ) = = nullptr ) {
2012-06-29 16:44:26 +02:00
# ifdef __VISUALC__ // C++0x compliance to some degree :)
iter = houses . erase ( iter ) ;
# else // Bulky, slow way
HouseMap : : iterator tmp_iter = iter ;
+ + tmp_iter ;
uint32_t next_key = 0 ;
2023-10-09 19:12:16 -07:00
if ( tmp_iter ! = houses . end ( ) ) {
2012-06-29 16:44:26 +02:00
next_key = tmp_iter - > first ;
}
houses . erase ( iter ) ;
2023-10-09 19:12:16 -07:00
if ( next_key ! = 0 ) {
2012-06-29 16:44:26 +02:00
iter = houses . find ( next_key ) ;
} else {
iter = houses . end ( ) ;
}
# endif
} else {
+ + iter ;
}
}
uint64_t tiles_done = 0 ;
2023-10-09 19:12:16 -07:00
for ( MapIterator map_iter = map . begin ( ) ; map_iter ! = map . end ( ) ; + + map_iter ) {
if ( showdialog & & tiles_done % 4096 = = 0 ) {
2016-09-29 20:30:54 -03:00
g_gui . SetLoadDone ( int ( tiles_done / double ( map . tilecount ) * 100.0 ) ) ;
2012-06-29 16:44:26 +02:00
}
Tile * tile = ( * map_iter ) - > get ( ) ;
ASSERT ( tile ) ;
2023-10-09 19:12:16 -07:00
if ( tile - > isHouseTile ( ) ) {
if ( houses . getHouse ( tile - > getHouseID ( ) ) = = nullptr ) {
2014-01-22 20:16:17 +01:00
tile - > setHouse ( nullptr ) ;
2012-06-29 16:44:26 +02:00
}
}
2014-01-20 03:04:59 +01:00
+ + tiles_done ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( showdialog ) {
2016-09-29 20:30:54 -03:00
g_gui . DestroyLoadBar ( ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
void Editor : : clearModifiedTileState ( bool showdialog ) {
if ( showdialog ) {
2016-11-05 15:28:14 +01:00
g_gui . CreateLoadBar ( " Clearing modified state from all tiles... " ) ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 19:24:45 -03:00
2012-06-29 16:44:26 +02:00
uint64_t tiles_done = 0 ;
2023-10-09 19:12:16 -07:00
for ( MapIterator map_iter = map . begin ( ) ; map_iter ! = map . end ( ) ; + + map_iter ) {
if ( showdialog & & tiles_done % 4096 = = 0 ) {
2016-09-29 20:30:54 -03:00
g_gui . SetLoadDone ( int ( tiles_done / double ( map . tilecount ) * 100.0 ) ) ;
2012-06-29 16:44:26 +02:00
}
Tile * tile = ( * map_iter ) - > get ( ) ;
ASSERT ( tile ) ;
tile - > unmodify ( ) ;
2014-01-20 03:04:59 +01:00
+ + tiles_done ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( showdialog ) {
2016-09-29 20:30:54 -03:00
g_gui . DestroyLoadBar ( ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
void Editor : : moveSelection ( const Position & offset ) {
if ( ! CanEdit ( ) | | ! hasSelection ( ) ) {
2023-10-09 23:02:37 -03:00
return ;
}
2012-06-29 16:44:26 +02:00
2023-10-09 23:02:37 -03:00
bool borderize = false ;
int drag_threshold = g_settings . getInteger ( Config : : BORDERIZE_DRAG_THRESHOLD ) ;
bool create_borders = g_settings . getInteger ( Config : : USE_AUTOMAGIC )
& & g_settings . getInteger ( Config : : BORDERIZE_DRAG ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 23:02:37 -03:00
TileSet storage ;
BatchAction * batch_action = actionQueue - > createBatch ( ACTION_MOVE ) ;
Action * action = actionQueue - > createAction ( batch_action ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 23:02:37 -03:00
// Update the tiles with the new positions
2023-10-09 19:12:16 -07:00
for ( Tile * tile : selection ) {
2023-10-09 23:02:37 -03:00
Tile * new_tile = tile - > deepCopy ( map ) ;
Tile * storage_tile = map . allocator ( tile - > getLocation ( ) ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 23:02:37 -03:00
ItemVector selected_items = new_tile - > popSelectedItems ( ) ;
2023-10-09 19:12:16 -07:00
for ( Item * item : selected_items ) {
2023-10-09 23:02:37 -03:00
storage_tile - > addItem ( item ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
2021-05-25 00:29:12 -03:00
// Move monster spawns
2023-10-09 19:12:16 -07:00
if ( new_tile - > spawnMonster & & new_tile - > spawnMonster - > isSelected ( ) ) {
2023-10-09 23:02:37 -03:00
storage_tile - > spawnMonster = new_tile - > spawnMonster ;
new_tile - > spawnMonster = nullptr ;
2021-05-25 00:29:12 -03:00
}
// Move monster
2023-10-09 19:12:16 -07:00
if ( new_tile - > monster & & new_tile - > monster - > isSelected ( ) ) {
2023-10-09 23:02:37 -03:00
storage_tile - > monster = new_tile - > monster ;
new_tile - > monster = nullptr ;
2012-06-29 16:44:26 +02:00
}
2021-05-25 00:29:12 -03:00
// Move npc
2023-10-09 19:12:16 -07:00
if ( new_tile - > npc & & new_tile - > npc - > isSelected ( ) ) {
2023-10-09 23:02:37 -03:00
storage_tile - > npc = new_tile - > npc ;
new_tile - > npc = nullptr ;
2021-05-25 00:29:12 -03:00
}
// Move npc spawns
2023-10-09 19:12:16 -07:00
if ( new_tile - > spawnNpc & & new_tile - > spawnNpc - > isSelected ( ) ) {
2023-10-09 23:02:37 -03:00
storage_tile - > spawnNpc = new_tile - > spawnNpc ;
new_tile - > spawnNpc = nullptr ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( storage_tile - > ground ) {
2023-10-09 23:02:37 -03:00
storage_tile - > house_id = new_tile - > house_id ;
new_tile - > house_id = 0 ;
storage_tile - > setMapFlags ( new_tile - > getMapFlags ( ) ) ;
new_tile - > setMapFlags ( TILESTATE_NONE ) ;
borderize = true ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
storage . insert ( storage_tile ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
batch_action - > addAndCommitAction ( action ) ;
// Remove old borders (and create some new?)
2023-10-09 19:12:16 -07:00
if ( create_borders & & selection . size ( ) < static_cast < size_t > ( drag_threshold ) ) {
2023-10-09 23:02:37 -03:00
action = actionQueue - > createAction ( batch_action ) ;
2012-06-29 16:44:26 +02:00
TileList borderize_tiles ;
// Go through all modified (selected) tiles (might be slow)
2023-10-09 19:12:16 -07:00
for ( const Tile * tile : storage ) {
const Position & pos = tile - > getPosition ( ) ;
2012-06-29 16:44:26 +02:00
// Go through all neighbours
Tile * t ;
2023-10-09 19:12:16 -07:00
t = map . getTile ( pos . x , pos . y , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x - 1 , pos . y - 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x , pos . y - 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x + 1 , pos . y - 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x - 1 , pos . y , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x + 1 , pos . y , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x - 1 , pos . y + 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x , pos . y + 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
t = map . getTile ( pos . x + 1 , pos . y + 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
}
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
2012-06-29 16:44:26 +02:00
// Remove duplicates
borderize_tiles . sort ( ) ;
borderize_tiles . unique ( ) ;
2023-10-09 23:02:37 -03:00
// Create borders
2023-10-09 19:12:16 -07:00
for ( const Tile * tile : borderize_tiles ) {
2023-10-09 23:02:37 -03:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2023-10-09 19:12:16 -07:00
if ( borderize ) {
2023-10-09 23:02:37 -03:00
new_tile - > borderize ( & map ) ;
}
2012-06-29 16:44:26 +02:00
new_tile - > wallize ( & map ) ;
new_tile - > tableize ( & map ) ;
new_tile - > carpetize ( & map ) ;
2023-10-09 19:12:16 -07:00
if ( tile - > ground & & tile - > ground - > isSelected ( ) ) {
2023-10-09 23:02:37 -03:00
new_tile - > selectGround ( ) ;
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
batch_action - > addAndCommitAction ( action ) ;
2012-06-29 16:44:26 +02:00
}
// New action for adding the destination tiles
2023-10-09 23:02:37 -03:00
action = actionQueue - > createAction ( batch_action ) ;
2023-10-09 19:12:16 -07:00
for ( Tile * tile : storage ) {
const Position & old_pos = tile - > getPosition ( ) ;
2023-10-09 23:02:37 -03:00
Position new_pos = old_pos - offset ;
2023-10-09 19:12:16 -07:00
if ( new_pos . z < rme : : MapMinLayer & & new_pos . z > rme : : MapMaxLayer ) {
2012-06-29 16:44:26 +02:00
delete tile ;
continue ;
}
2023-10-09 23:02:37 -03:00
2012-06-29 16:44:26 +02:00
TileLocation * location = map . createTileL ( new_pos ) ;
Tile * old_dest_tile = location - > get ( ) ;
2014-01-22 20:16:17 +01:00
Tile * new_dest_tile = nullptr ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( ! tile - > ground | | g_settings . getInteger ( Config : : MERGE_MOVE ) ) {
2012-06-29 16:44:26 +02:00
// Move items
2023-10-09 19:12:16 -07:00
if ( old_dest_tile ) {
2012-06-29 16:44:26 +02:00
new_dest_tile = old_dest_tile - > deepCopy ( map ) ;
} else {
new_dest_tile = map . allocator ( location ) ;
}
new_dest_tile - > merge ( tile ) ;
delete tile ;
} else {
// Replace tile instead of just merge
tile - > setLocation ( location ) ;
new_dest_tile = tile ;
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_dest_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
batch_action - > addAndCommitAction ( action ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( create_borders & & selection . size ( ) < static_cast < size_t > ( drag_threshold ) ) {
2023-10-09 23:02:37 -03:00
action = actionQueue - > createAction ( batch_action ) ;
2012-06-29 16:44:26 +02:00
TileList borderize_tiles ;
// Go through all modified (selected) tiles (might be slow)
2023-10-09 19:12:16 -07:00
for ( Tile * tile : selection ) {
2012-06-29 16:44:26 +02:00
bool add_me = false ; // If this tile is touched
2023-10-09 19:12:16 -07:00
const Position & pos = tile - > getPosition ( ) ;
2012-06-29 16:44:26 +02:00
// Go through all neighbours
Tile * t ;
2023-10-09 19:12:16 -07:00
t = map . getTile ( pos . x - 1 , pos . y - 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x - 1 , pos . y - 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x , pos . y - 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x + 1 , pos . y - 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x - 1 , pos . y , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x + 1 , pos . y , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x - 1 , pos . y + 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x , pos . y + 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
t = map . getTile ( pos . x + 1 , pos . y + 1 , pos . z ) ;
if ( t & & ! t - > isSelected ( ) ) {
borderize_tiles . push_back ( t ) ;
add_me = true ;
}
if ( add_me ) {
2023-10-09 23:02:37 -03:00
borderize_tiles . push_back ( tile ) ;
}
2012-06-29 16:44:26 +02:00
}
2023-10-09 23:02:37 -03:00
2012-06-29 16:44:26 +02:00
// Remove duplicates
borderize_tiles . sort ( ) ;
borderize_tiles . unique ( ) ;
2016-09-29 19:24:45 -03:00
2023-10-09 23:02:37 -03:00
// Create borders
2023-10-09 19:12:16 -07:00
for ( const Tile * tile : borderize_tiles ) {
if ( ! tile | | ! tile - > ground ) {
2023-10-09 23:02:37 -03:00
continue ;
}
2023-10-09 19:12:16 -07:00
if ( tile - > ground - > getGroundBrush ( ) ) {
2023-10-09 23:02:37 -03:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2023-10-09 19:12:16 -07:00
if ( borderize ) {
2023-10-09 23:02:37 -03:00
new_tile - > borderize ( & map ) ;
}
new_tile - > wallize ( & map ) ;
new_tile - > tableize ( & map ) ;
new_tile - > carpetize ( & map ) ;
2023-10-09 19:12:16 -07:00
if ( tile - > ground - > isSelected ( ) ) {
2023-10-09 23:02:37 -03:00
new_tile - > selectGround ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 23:02:37 -03:00
batch_action - > addAndCommitAction ( action ) ;
2012-06-29 16:44:26 +02:00
}
// Store the action for undo
2023-10-09 23:02:37 -03:00
addBatch ( batch_action ) ;
updateActions ( ) ;
2012-06-29 16:44:26 +02:00
selection . updateSelectionCount ( ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : destroySelection ( ) {
if ( selection . size ( ) = = 0 ) {
2016-11-05 15:28:14 +01:00
g_gui . SetStatusText ( " No selected items to delete. " ) ;
2012-06-29 16:44:26 +02:00
} else {
int tile_count = 0 ;
int item_count = 0 ;
PositionList tilestoborder ;
BatchAction * batch = actionQueue - > createBatch ( ACTION_DELETE_TILES ) ;
Action * action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( TileSet : : iterator it = selection . begin ( ) ; it ! = selection . end ( ) ; + + it ) {
2012-06-29 16:44:26 +02:00
tile_count + + ;
Tile * tile = * it ;
Tile * newtile = tile - > deepCopy ( map ) ;
ItemVector tile_selection = newtile - > popSelectedItems ( ) ;
2023-10-09 19:12:16 -07:00
for ( ItemVector : : iterator iit = tile_selection . begin ( ) ; iit ! = tile_selection . end ( ) ; + + iit ) {
2012-06-29 16:44:26 +02:00
+ + item_count ;
// Delete the items from the tile
delete * iit ;
}
2021-05-25 00:29:12 -03:00
// Monster
2023-10-09 19:12:16 -07:00
if ( newtile - > monster & & newtile - > monster - > isSelected ( ) ) {
2021-05-25 00:29:12 -03:00
newtile - > monster = nullptr ;
}
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( newtile - > spawnMonster & & newtile - > spawnMonster - > isSelected ( ) ) {
2021-05-25 00:29:12 -03:00
newtile - > spawnMonster = nullptr ;
}
// Npc
2023-10-09 19:12:16 -07:00
if ( newtile - > npc & & newtile - > npc - > isSelected ( ) ) {
2021-05-25 00:29:12 -03:00
delete newtile - > npc ;
newtile - > npc = nullptr ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( newtile - > spawnNpc & & newtile - > spawnNpc - > isSelected ( ) ) {
2021-05-25 00:29:12 -03:00
delete newtile - > spawnNpc ;
newtile - > spawnNpc = nullptr ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_AUTOMAGIC ) ) {
for ( int y = - 1 ; y < = 1 ; y + + ) {
for ( int x = - 1 ; x < = 1 ; x + + ) {
const Position & position = tile - > getPosition ( ) ;
2023-10-09 23:02:37 -03:00
tilestoborder . push_back ( Position ( position . x + x , position . y + y , position . z ) ) ;
2012-06-29 16:44:26 +02:00
}
}
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( newtile ) ) ;
2012-06-29 16:44:26 +02:00
}
batch - > addAndCommitAction ( action ) ;
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_AUTOMAGIC ) ) {
2012-06-29 16:44:26 +02:00
// Remove duplicates
tilestoborder . sort ( ) ;
tilestoborder . unique ( ) ;
action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( PositionList : : iterator it = tilestoborder . begin ( ) ; it ! = tilestoborder . end ( ) ; + + it ) {
2012-06-29 16:44:26 +02:00
TileLocation * location = map . createTileL ( * it ) ;
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
new_tile - > borderize ( & map ) ;
new_tile - > wallize ( & map ) ;
new_tile - > tableize ( & map ) ;
new_tile - > carpetize ( & map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
} else {
Tile * new_tile = map . allocator ( location ) ;
new_tile - > borderize ( & map ) ;
2023-10-09 19:12:16 -07:00
if ( new_tile - > size ( ) ) {
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
} else {
delete new_tile ;
}
}
}
batch - > addAndCommitAction ( action ) ;
}
addBatch ( batch ) ;
2023-10-09 23:02:37 -03:00
updateActions ( ) ;
2012-06-29 16:44:26 +02:00
wxString ss ;
2023-10-09 19:12:16 -07:00
ss < < " Deleted " < < tile_count < < " tile " < < ( tile_count > 1 ? " s " : " " ) < < " ( " < < item_count < < " item " < < ( item_count > 1 ? " s " : " " ) < < " ) " ;
2016-09-29 20:30:54 -03:00
g_gui . SetStatusText ( ss ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
// Macro to avoid useless code repetition
void doSurroundingBorders ( DoodadBrush * doodad_brush , PositionList & tilestoborder , Tile * buffer_tile , Tile * new_tile ) {
if ( doodad_brush - > doNewBorders ( ) & & g_settings . getInteger ( Config : : USE_AUTOMAGIC ) ) {
const Position & position = new_tile - > getPosition ( ) ;
2023-10-09 23:02:37 -03:00
tilestoborder . push_back ( Position ( position ) ) ;
2023-10-09 19:12:16 -07:00
if ( buffer_tile - > hasGround ( ) ) {
for ( int y = - 1 ; y < = 1 ; y + + ) {
for ( int x = - 1 ; x < = 1 ; x + + ) {
2023-10-09 23:02:37 -03:00
tilestoborder . push_back ( Position ( position . x + x , position . y + y , position . z ) ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
} else if ( buffer_tile - > hasWall ( ) ) {
tilestoborder . push_back ( Position ( position . x , position . y - 1 , position . z ) ) ;
tilestoborder . push_back ( Position ( position . x - 1 , position . y , position . z ) ) ;
tilestoborder . push_back ( Position ( position . x + 1 , position . y , position . z ) ) ;
tilestoborder . push_back ( Position ( position . x , position . y + 1 , position . z ) ) ;
2012-06-29 16:44:26 +02:00
}
}
}
2023-10-09 19:12:16 -07:00
void removeDuplicateWalls ( Tile * buffer , Tile * tile ) {
2023-10-09 23:02:37 -03:00
if ( ! buffer | | buffer - > items . empty ( ) | | ! tile | | tile - > items . empty ( ) ) {
return ;
}
2023-10-09 19:12:16 -07:00
for ( const Item * item : buffer - > items ) {
if ( item ) {
2023-10-09 23:02:37 -03:00
WallBrush * brush = item - > getWallBrush ( ) ;
2023-10-09 19:12:16 -07:00
if ( brush ) {
2023-10-09 23:02:37 -03:00
tile - > cleanWalls ( brush ) ;
}
2012-06-29 16:44:26 +02:00
}
}
}
2023-10-09 19:12:16 -07:00
void Editor : : drawInternal ( Position offset , bool alt , bool dodraw ) {
if ( ! CanEdit ( ) ) {
2023-10-09 23:02:37 -03:00
return ;
}
2016-09-29 20:30:54 -03:00
Brush * brush = g_gui . GetCurrentBrush ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! brush ) {
2016-11-12 10:30:06 -03:00
return ;
2023-10-09 23:02:37 -03:00
}
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( brush - > isDoodad ( ) ) {
2016-11-12 10:30:06 -03:00
BatchAction * batch = actionQueue - > createBatch ( ACTION_DRAW ) ;
2012-06-29 16:44:26 +02:00
Action * action = actionQueue - > createAction ( batch ) ;
2016-09-29 20:30:54 -03:00
BaseMap * buffer_map = g_gui . doodad_buffer_map ;
2012-06-29 16:44:26 +02:00
Position delta_pos = offset - Position ( 0x8000 , 0x8000 , 0x8 ) ;
PositionList tilestoborder ;
2023-10-09 19:12:16 -07:00
for ( MapIterator it = buffer_map - > begin ( ) ; it ! = buffer_map - > end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
Tile * buffer_tile = ( * it ) - > get ( ) ;
2012-06-29 16:44:26 +02:00
Position pos = buffer_tile - > getPosition ( ) + delta_pos ;
2023-10-09 19:12:16 -07:00
if ( ! pos . isValid ( ) ) {
2012-06-29 16:44:26 +02:00
continue ;
}
2016-09-29 19:24:45 -03:00
2012-06-29 16:44:26 +02:00
TileLocation * location = map . createTileL ( pos ) ;
Tile * tile = location - > get ( ) ;
2016-11-12 10:30:06 -03:00
DoodadBrush * doodad_brush = brush - > asDoodad ( ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( doodad_brush - > placeOnBlocking ( ) | | alt ) {
if ( tile ) {
2012-06-29 16:44:26 +02:00
bool place = true ;
2023-10-09 19:12:16 -07:00
if ( ! doodad_brush - > placeOnDuplicate ( ) & & ! alt ) {
for ( ItemVector : : const_iterator iter = tile - > items . begin ( ) ; iter ! = tile - > items . end ( ) ; + + iter ) {
if ( doodad_brush - > ownsItem ( * iter ) ) {
2012-06-29 16:44:26 +02:00
place = false ;
break ;
}
}
}
2023-10-09 19:12:16 -07:00
if ( place ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
removeDuplicateWalls ( buffer_tile , new_tile ) ;
doSurroundingBorders ( doodad_brush , tilestoborder , buffer_tile , new_tile ) ;
new_tile - > merge ( buffer_tile ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
} else {
Tile * new_tile = map . allocator ( location ) ;
removeDuplicateWalls ( buffer_tile , new_tile ) ;
doSurroundingBorders ( doodad_brush , tilestoborder , buffer_tile , new_tile ) ;
new_tile - > merge ( buffer_tile ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
} else {
2023-10-09 19:12:16 -07:00
if ( tile & & ! tile - > isBlocking ( ) ) {
2012-06-29 16:44:26 +02:00
bool place = true ;
2023-10-09 19:12:16 -07:00
if ( ! doodad_brush - > placeOnDuplicate ( ) & & ! alt ) {
for ( ItemVector : : const_iterator iter = tile - > items . begin ( ) ; iter ! = tile - > items . end ( ) ; + + iter ) {
if ( doodad_brush - > ownsItem ( * iter ) ) {
2012-06-29 16:44:26 +02:00
place = false ;
break ;
}
}
}
2023-10-09 19:12:16 -07:00
if ( place ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
removeDuplicateWalls ( buffer_tile , new_tile ) ;
doSurroundingBorders ( doodad_brush , tilestoborder , buffer_tile , new_tile ) ;
new_tile - > merge ( buffer_tile ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
}
}
batch - > addAndCommitAction ( action ) ;
2023-10-09 19:12:16 -07:00
if ( tilestoborder . size ( ) > 0 ) {
2012-06-29 16:44:26 +02:00
Action * action = actionQueue - > createAction ( batch ) ;
// Remove duplicates
tilestoborder . sort ( ) ;
tilestoborder . unique ( ) ;
2023-10-09 19:12:16 -07:00
for ( PositionList : : const_iterator it = tilestoborder . begin ( ) ; it ! = tilestoborder . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
Tile * tile = map . getTile ( * it ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2016-11-12 10:30:06 -03:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2012-06-29 16:44:26 +02:00
new_tile - > borderize ( & map ) ;
new_tile - > wallize ( & map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
batch - > addAndCommitAction ( action ) ;
}
2016-11-12 10:30:06 -03:00
addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isHouseExit ( ) ) {
2016-11-12 10:30:06 -03:00
HouseExitBrush * house_exit_brush = brush - > asHouseExit ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! house_exit_brush - > canDraw ( & map , offset ) ) {
2016-11-12 10:30:06 -03:00
return ;
2023-10-09 19:12:16 -07:00
}
2016-11-12 10:30:06 -03:00
2012-06-29 16:44:26 +02:00
House * house = map . houses . getHouse ( house_exit_brush - > getHouseID ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( ! house ) {
2012-06-29 16:44:26 +02:00
return ;
2023-10-09 19:12:16 -07:00
}
2016-11-12 10:30:06 -03:00
BatchAction * batch = actionQueue - > createBatch ( ACTION_DRAW ) ;
2012-06-29 16:44:26 +02:00
Action * action = actionQueue - > createAction ( batch ) ;
2016-11-12 10:30:06 -03:00
action - > addChange ( Change : : Create ( house , offset ) ) ;
batch - > addAndCommitAction ( action ) ;
addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isWaypoint ( ) ) {
2016-11-12 10:30:06 -03:00
WaypointBrush * waypoint_brush = brush - > asWaypoint ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! waypoint_brush - > canDraw ( & map , offset ) ) {
2012-06-29 16:44:26 +02:00
return ;
2023-10-09 19:12:16 -07:00
}
2016-11-12 10:30:06 -03:00
Waypoint * waypoint = map . waypoints . getWaypoint ( waypoint_brush - > getWaypoint ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( ! waypoint | | waypoint - > pos = = offset ) {
2016-11-12 10:30:06 -03:00
return ;
2023-10-09 19:12:16 -07:00
}
2016-11-12 10:30:06 -03:00
BatchAction * batch = actionQueue - > createBatch ( ACTION_DRAW ) ;
Action * action = actionQueue - > createAction ( batch ) ;
action - > addChange ( Change : : Create ( waypoint , offset ) ) ;
2012-06-29 16:44:26 +02:00
batch - > addAndCommitAction ( action ) ;
2016-11-12 10:30:06 -03:00
addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isWall ( ) ) {
2023-10-09 23:02:37 -03:00
BatchAction * batch = actionQueue - > createBatch ( dodraw ? ACTION_DRAW : ACTION_ERASE ) ;
2012-06-29 16:44:26 +02:00
Action * action = actionQueue - > createAction ( batch ) ;
// This will only occur with a size 0, when clicking on a tile (not drawing)
2016-11-12 10:30:06 -03:00
Tile * tile = map . getTile ( offset ) ;
2014-01-22 20:16:17 +01:00
Tile * new_tile = nullptr ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2016-11-12 10:30:06 -03:00
new_tile = tile - > deepCopy ( map ) ;
2012-06-29 16:44:26 +02:00
} else {
new_tile = map . allocator ( map . createTileL ( offset ) ) ;
}
2016-11-12 10:30:06 -03:00
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
2012-06-29 16:44:26 +02:00
bool b = true ;
2016-11-12 10:30:06 -03:00
brush - > asWall ( ) - > draw ( & map , new_tile , & b ) ;
2012-06-29 16:44:26 +02:00
} else {
2016-11-12 10:30:06 -03:00
brush - > asWall ( ) - > undraw ( & map , new_tile ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
batch - > addAndCommitAction ( action ) ;
2016-11-12 10:30:06 -03:00
addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isSpawnMonster ( ) | | brush - > isMonster ( ) ) {
2023-10-09 23:02:37 -03:00
BatchAction * batch = actionQueue - > createBatch ( dodraw ? ACTION_DRAW : ACTION_ERASE ) ;
2021-05-25 00:29:12 -03:00
Action * action = actionQueue - > createAction ( batch ) ;
Tile * tile = map . getTile ( offset ) ;
Tile * new_tile = nullptr ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2021-05-25 00:29:12 -03:00
new_tile = tile - > deepCopy ( map ) ;
} else {
new_tile = map . allocator ( map . createTileL ( offset ) ) ;
}
int param ;
2023-10-09 19:12:16 -07:00
if ( brush - > isMonster ( ) ) {
2021-05-25 00:29:12 -03:00
param = g_gui . GetSpawnMonsterTime ( ) ;
} else {
param = g_gui . GetBrushSize ( ) ;
}
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
2021-05-25 00:29:12 -03:00
brush - > draw ( & map , new_tile , & param ) ;
} else {
brush - > undraw ( & map , new_tile ) ;
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2021-05-25 00:29:12 -03:00
batch - > addAndCommitAction ( action ) ;
addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isSpawnNpc ( ) | | brush - > isNpc ( ) ) {
2016-11-12 10:30:06 -03:00
BatchAction * batch = actionQueue - > createBatch ( ACTION_DRAW ) ;
2012-06-29 16:44:26 +02:00
Action * action = actionQueue - > createAction ( batch ) ;
2016-11-12 10:30:06 -03:00
Tile * tile = map . getTile ( offset ) ;
2014-01-22 20:16:17 +01:00
Tile * new_tile = nullptr ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2016-11-12 10:30:06 -03:00
new_tile = tile - > deepCopy ( map ) ;
2012-06-29 16:44:26 +02:00
} else {
new_tile = map . allocator ( map . createTileL ( offset ) ) ;
}
int param ;
2023-10-09 19:12:16 -07:00
if ( brush - > isNpc ( ) ) {
2021-05-25 00:29:12 -03:00
param = g_gui . GetSpawnNpcTime ( ) ;
2012-06-29 16:44:26 +02:00
} else {
2016-09-29 20:30:54 -03:00
param = g_gui . GetBrushSize ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
2012-06-29 16:44:26 +02:00
brush - > draw ( & map , new_tile , & param ) ;
} else {
brush - > undraw ( & map , new_tile ) ;
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
batch - > addAndCommitAction ( action ) ;
2016-11-12 10:30:06 -03:00
addBatch ( batch , 2 ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
void Editor : : drawInternal ( const PositionVector & tilestodraw , bool alt , bool dodraw ) {
if ( ! CanEdit ( ) ) {
2023-10-09 23:02:37 -03:00
return ;
}
2016-09-29 20:30:54 -03:00
Brush * brush = g_gui . GetCurrentBrush ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! brush ) {
2016-11-12 10:30:06 -03:00
return ;
2023-10-09 23:02:37 -03:00
}
2012-06-29 16:44:26 +02:00
2016-11-12 10:30:06 -03:00
# ifdef __DEBUG__
2023-10-09 19:12:16 -07:00
if ( brush - > isGround ( ) | | brush - > isWall ( ) ) {
2012-06-29 16:44:26 +02:00
// Wrong function, end call
return ;
}
# endif
2016-11-12 10:30:06 -03:00
2023-10-09 23:02:37 -03:00
Action * action = actionQueue - > createAction ( dodraw ? ACTION_DRAW : ACTION_ERASE ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( brush - > isOptionalBorder ( ) ) {
2012-06-29 16:44:26 +02:00
// We actually need to do borders, but on the same tiles we draw to
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
brush - > draw ( & map , new_tile ) ;
new_tile - > borderize ( & map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2023-10-09 19:12:16 -07:00
} else if ( ! dodraw & & tile - > hasOptionalBorder ( ) ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
brush - > undraw ( & map , new_tile ) ;
new_tile - > borderize ( & map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
brush - > draw ( & map , new_tile ) ;
new_tile - > borderize ( & map ) ;
2023-10-09 19:12:16 -07:00
if ( new_tile - > size ( ) = = 0 ) {
2012-06-29 16:44:26 +02:00
delete new_tile ;
continue ;
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
} else {
2020-07-30 11:42:28 -03:00
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
2012-06-29 16:44:26 +02:00
brush - > draw ( & map , new_tile , & alt ) ;
} else {
brush - > undraw ( & map , new_tile ) ;
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
brush - > draw ( & map , new_tile , & alt ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
}
addAction ( action , 2 ) ;
}
2023-10-09 19:12:16 -07:00
void Editor : : drawInternal ( const PositionVector & tilestodraw , PositionVector & tilestoborder , bool alt , bool dodraw ) {
if ( ! CanEdit ( ) ) {
2023-10-09 23:02:37 -03:00
return ;
}
2016-09-29 20:30:54 -03:00
Brush * brush = g_gui . GetCurrentBrush ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! brush ) {
2016-11-12 10:30:06 -03:00
return ;
2023-10-09 23:02:37 -03:00
}
2016-11-12 10:30:06 -03:00
2023-10-09 19:12:16 -07:00
if ( brush - > isGround ( ) | | brush - > isEraser ( ) ) {
2023-10-09 23:02:37 -03:00
ActionIdentifier identifier = ( dodraw & & ! brush - > isEraser ( ) ) ? ACTION_DRAW : ACTION_ERASE ;
BatchAction * batch = actionQueue - > createBatch ( identifier ) ;
2012-06-29 16:44:26 +02:00
Action * action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_AUTOMAGIC ) ) {
2012-06-29 16:44:26 +02:00
new_tile - > cleanBorders ( ) ;
}
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
if ( brush - > isGround ( ) & & alt ) {
2012-06-29 16:44:26 +02:00
std : : pair < bool , GroundBrush * > param ;
2023-10-09 19:12:16 -07:00
if ( replace_brush ) {
2012-06-29 16:44:26 +02:00
param . first = false ;
param . second = replace_brush ;
} else {
param . first = true ;
2014-01-22 20:16:17 +01:00
param . second = nullptr ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile , & param ) ;
2012-06-29 16:44:26 +02:00
} else {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile , nullptr ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
} else {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > undraw ( & map , new_tile ) ;
2016-11-12 10:30:06 -03:00
tilestoborder . push_back ( * it ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
2023-10-09 19:12:16 -07:00
if ( brush - > isGround ( ) & & alt ) {
2012-06-29 16:44:26 +02:00
std : : pair < bool , GroundBrush * > param ;
2023-10-09 19:12:16 -07:00
if ( replace_brush ) {
2012-06-29 16:44:26 +02:00
param . first = false ;
param . second = replace_brush ;
} else {
param . first = true ;
2014-01-22 20:16:17 +01:00
param . second = nullptr ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile , & param ) ;
2012-06-29 16:44:26 +02:00
} else {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile , nullptr ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
// Commit changes to map
batch - > addAndCommitAction ( action ) ;
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_AUTOMAGIC ) ) {
2012-06-29 16:44:26 +02:00
// Do borders!
action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestoborder . begin ( ) ; it ! = tilestoborder . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2023-10-09 19:12:16 -07:00
if ( brush - > isEraser ( ) ) {
2012-06-29 16:44:26 +02:00
new_tile - > wallize ( & map ) ;
new_tile - > tableize ( & map ) ;
new_tile - > carpetize ( & map ) ;
}
new_tile - > borderize ( & map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
} else {
Tile * new_tile = map . allocator ( location ) ;
2023-10-09 19:12:16 -07:00
if ( brush - > isEraser ( ) ) {
2012-06-29 16:44:26 +02:00
// There are no carpets/tables/walls on empty tiles...
2023-10-09 19:12:16 -07:00
// new_tile->wallize(map);
// new_tile->tableize(map);
// new_tile->carpetize(map);
2012-06-29 16:44:26 +02:00
}
new_tile - > borderize ( & map ) ;
2023-10-09 19:12:16 -07:00
if ( new_tile - > size ( ) > 0 ) {
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
} else {
delete new_tile ;
}
}
}
batch - > addAndCommitAction ( action ) ;
}
addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isTable ( ) | | brush - > isCarpet ( ) ) {
2012-06-29 16:44:26 +02:00
BatchAction * batch = actionQueue - > createBatch ( ACTION_DRAW ) ;
Action * action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile , nullptr ) ;
2023-10-09 19:12:16 -07:00
} else {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > undraw ( & map , new_tile ) ;
2023-10-09 19:12:16 -07:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile , nullptr ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
// Commit changes to map
batch - > addAndCommitAction ( action ) ;
// Do borders!
action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestoborder . begin ( ) ; it ! = tilestoborder . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
Tile * tile = map . getTile ( * it ) ;
2023-10-09 19:12:16 -07:00
if ( brush - > isTable ( ) ) {
if ( tile & & tile - > hasTable ( ) ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
new_tile - > tableize ( & map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
} else if ( brush - > isCarpet ( ) ) {
if ( tile & & tile - > hasCarpet ( ) ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
new_tile - > carpetize ( & map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
}
batch - > addAndCommitAction ( action ) ;
addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isWall ( ) ) {
2012-06-29 16:44:26 +02:00
BatchAction * batch = actionQueue - > createBatch ( ACTION_DRAW ) ;
Action * action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
if ( alt & & dodraw ) {
2012-06-29 16:44:26 +02:00
// This is exempt from USE_AUTOMAGIC
2016-09-29 20:30:54 -03:00
g_gui . doodad_buffer_map - > clear ( ) ;
BaseMap * draw_map = g_gui . doodad_buffer_map ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2016-11-12 10:30:06 -03:00
new_tile - > cleanWalls ( brush - > isWall ( ) ) ;
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( draw_map , new_tile ) ;
2016-11-12 10:30:06 -03:00
draw_map - > setTile ( * it , new_tile , true ) ;
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( draw_map , new_tile ) ;
2016-11-12 10:30:06 -03:00
draw_map - > setTile ( * it , new_tile , true ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2012-06-29 16:44:26 +02:00
// Get the correct tiles from the draw map instead of the editor map
2016-11-12 10:30:06 -03:00
Tile * tile = draw_map - > getTile ( * it ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
tile - > wallize ( draw_map ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
draw_map - > clear ( false ) ;
// Commit
batch - > addAndCommitAction ( action ) ;
} else {
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
// Wall cleaning is exempt from automagic
2016-11-12 10:30:06 -03:00
new_tile - > cleanWalls ( brush - > isWall ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile ) ;
2023-10-09 19:12:16 -07:00
} else {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > undraw ( & map , new_tile ) ;
2023-10-09 19:12:16 -07:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
// Commit changes to map
batch - > addAndCommitAction ( action ) ;
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_AUTOMAGIC ) ) {
2012-06-29 16:44:26 +02:00
// Do borders!
action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestoborder . begin ( ) ; it ! = tilestoborder . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
Tile * tile = map . getTile ( * it ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
new_tile - > wallize ( & map ) ;
2023-10-09 19:12:16 -07:00
// if(*tile == *new_tile) delete new_tile;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
batch - > addAndCommitAction ( action ) ;
}
}
actionQueue - > addBatch ( batch , 2 ) ;
2023-10-09 19:12:16 -07:00
} else if ( brush - > isDoor ( ) ) {
2012-06-29 16:44:26 +02:00
BatchAction * batch = actionQueue - > createBatch ( ACTION_DRAW ) ;
Action * action = actionQueue - > createAction ( batch ) ;
2016-11-12 10:30:06 -03:00
DoorBrush * door_brush = brush - > asDoor ( ) ;
2012-06-29 16:44:26 +02:00
// Loop is kind of redundant since there will only ever be one index.
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
// Wall cleaning is exempt from automagic
2023-10-09 19:12:16 -07:00
if ( brush - > isWall ( ) ) {
2016-12-02 22:01:48 -03:00
new_tile - > cleanWalls ( brush - > asWall ( ) ) ;
2023-10-09 19:12:16 -07:00
}
if ( dodraw ) {
2012-06-29 16:44:26 +02:00
door_brush - > draw ( & map , new_tile , & alt ) ;
2023-10-09 19:12:16 -07:00
} else {
2012-06-29 16:44:26 +02:00
door_brush - > undraw ( & map , new_tile ) ;
2023-10-09 19:12:16 -07:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
door_brush - > draw ( & map , new_tile , & alt ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
// Commit changes to map
batch - > addAndCommitAction ( action ) ;
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_AUTOMAGIC ) ) {
2012-06-29 16:44:26 +02:00
// Do borders!
action = actionQueue - > createAction ( batch ) ;
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestoborder . begin ( ) ; it ! = tilestoborder . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
Tile * tile = map . getTile ( * it ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
new_tile - > wallize ( & map ) ;
2023-10-09 19:12:16 -07:00
// if(*tile == *new_tile) delete new_tile;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
batch - > addAndCommitAction ( action ) ;
}
addBatch ( batch , 2 ) ;
} else {
Action * action = actionQueue - > createAction ( ACTION_DRAW ) ;
2023-10-09 19:12:16 -07:00
for ( PositionVector : : const_iterator it = tilestodraw . begin ( ) ; it ! = tilestodraw . end ( ) ; + + it ) {
2016-11-12 10:30:06 -03:00
TileLocation * location = map . createTileL ( * it ) ;
2012-06-29 16:44:26 +02:00
Tile * tile = location - > get ( ) ;
2023-10-09 19:12:16 -07:00
if ( tile ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = tile - > deepCopy ( map ) ;
2023-10-09 19:12:16 -07:00
if ( dodraw ) {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile ) ;
2023-10-09 19:12:16 -07:00
} else {
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > undraw ( & map , new_tile ) ;
2023-10-09 19:12:16 -07:00
}
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2023-10-09 19:12:16 -07:00
} else if ( dodraw ) {
2012-06-29 16:44:26 +02:00
Tile * new_tile = map . allocator ( location ) ;
2016-09-29 20:30:54 -03:00
g_gui . GetCurrentBrush ( ) - > draw ( & map , new_tile ) ;
2023-10-15 18:51:57 -03:00
action - > addChange ( newd < Change > ( new_tile ) ) ;
2012-06-29 16:44:26 +02:00
}
}
addAction ( action , 2 ) ;
}
}
///////////////////////////////////////////////////////////////////////////////
// Live!
2023-10-09 19:12:16 -07:00
bool Editor : : IsLiveClient ( ) const {
2014-01-22 20:16:17 +01:00
return live_client ! = nullptr ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
bool Editor : : IsLiveServer ( ) const {
2014-01-22 20:16:17 +01:00
return live_server ! = nullptr ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
bool Editor : : IsLive ( ) const {
2012-06-29 16:44:26 +02:00
return IsLiveClient ( ) | | IsLiveServer ( ) ;
}
2023-10-09 19:12:16 -07:00
bool Editor : : IsLocal ( ) const {
2012-06-29 16:44:26 +02:00
return ! IsLive ( ) ;
}
2023-10-09 19:12:16 -07:00
LiveClient * Editor : : GetLiveClient ( ) const {
2012-06-29 16:44:26 +02:00
return live_client ;
}
2023-10-15 18:51:57 -03:00
std : : shared_ptr < LiveServer > Editor : : GetLiveServer ( ) const {
2012-06-29 16:44:26 +02:00
return live_server ;
}
2023-10-09 19:12:16 -07:00
LiveSocket & Editor : : GetLive ( ) const {
if ( live_server ) {
2012-06-29 16:44:26 +02:00
return * live_server ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
return * live_client ;
}
2014-02-21 13:55:09 +01:00
2023-10-15 18:51:57 -03:00
std : : shared_ptr < LiveServer > Editor : : StartLiveServer ( ) {
2016-09-29 19:24:45 -03:00
ASSERT ( IsLocal ( ) ) ;
2023-10-15 18:51:57 -03:00
live_server = newd < LiveServer > ( * this ) ;
2014-02-21 13:55:09 +01:00
2023-10-15 18:51:57 -03:00
actionQueue = newd < NetworkedActionQueue > ( * this ) ;
2014-02-21 13:55:09 +01:00
2012-06-29 16:44:26 +02:00
return live_server ;
}
2023-10-09 19:12:16 -07:00
void Editor : : BroadcastNodes ( DirtyList & dirtyList ) {
if ( IsLiveClient ( ) ) {
2014-02-21 13:55:09 +01:00
live_client - > sendChanges ( dirtyList ) ;
} else {
live_server - > broadcastNodes ( dirtyList ) ;
}
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void Editor : : CloseLiveServer ( ) {
2012-06-29 16:44:26 +02:00
ASSERT ( IsLive ( ) ) ;
2023-10-09 19:12:16 -07:00
if ( live_client ) {
2014-02-21 13:55:09 +01:00
live_client - > close ( ) ;
2012-06-29 16:44:26 +02:00
2014-02-21 13:55:09 +01:00
delete live_client ;
2014-01-22 20:16:17 +01:00
live_client = nullptr ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 19:24:45 -03:00
2023-10-09 19:12:16 -07:00
if ( live_server ) {
2014-02-21 13:55:09 +01:00
live_server - > close ( ) ;
2014-01-22 20:16:17 +01:00
live_server = nullptr ;
2012-06-29 16:44:26 +02:00
2023-10-15 18:51:57 -03:00
actionQueue = newd < ActionQueue > ( * this ) ;
2012-06-29 16:44:26 +02:00
}
2014-02-21 13:55:09 +01:00
2023-10-09 19:12:16 -07:00
NetworkConnection & connection = NetworkConnection : : getInstance ( ) ;
2014-02-21 13:55:09 +01:00
connection . stop ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void Editor : : QueryNode ( int ndx , int ndy , bool underground ) {
2012-06-29 16:44:26 +02:00
ASSERT ( live_client ) ;
2014-02-21 13:55:09 +01:00
live_client - > queryNode ( ndx , ndy , underground ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void Editor : : SendNodeRequests ( ) {
if ( live_client ) {
2014-02-21 13:55:09 +01:00
live_client - > sendNodeRequests ( ) ;
2012-06-29 16:44:26 +02:00
}
}