tile_map_editor.cpp 158 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948
  1. /*************************************************************************/
  2. /* tile_map_editor.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "tile_map_editor.h"
  31. #include "tiles_editor_plugin.h"
  32. #include "editor/editor_resource_preview.h"
  33. #include "editor/editor_scale.h"
  34. #include "editor/plugins/canvas_item_editor_plugin.h"
  35. #include "scene/gui/center_container.h"
  36. #include "scene/gui/split_container.h"
  37. #include "core/input/input.h"
  38. #include "core/math/geometry_2d.h"
  39. #include "core/os/keyboard.h"
  40. void TileMapEditorTilesPlugin::_notification(int p_what) {
  41. switch (p_what) {
  42. case NOTIFICATION_ENTER_TREE:
  43. case NOTIFICATION_THEME_CHANGED:
  44. select_tool_button->set_icon(get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
  45. paint_tool_button->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
  46. line_tool_button->set_icon(get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons")));
  47. rect_tool_button->set_icon(get_theme_icon(SNAME("Rectangle"), SNAME("EditorIcons")));
  48. bucket_tool_button->set_icon(get_theme_icon(SNAME("Bucket"), SNAME("EditorIcons")));
  49. picker_button->set_icon(get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
  50. erase_button->set_icon(get_theme_icon(SNAME("Eraser"), SNAME("EditorIcons")));
  51. missing_atlas_texture_icon = get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons"));
  52. break;
  53. case NOTIFICATION_VISIBILITY_CHANGED:
  54. _stop_dragging();
  55. break;
  56. }
  57. }
  58. void TileMapEditorTilesPlugin::tile_set_changed() {
  59. _update_fix_selected_and_hovered();
  60. _update_tile_set_sources_list();
  61. _update_bottom_panel();
  62. }
  63. void TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled(bool p_pressed) {
  64. scatter_spinbox->set_editable(p_pressed);
  65. }
  66. void TileMapEditorTilesPlugin::_on_scattering_spinbox_changed(double p_value) {
  67. scattering = p_value;
  68. }
  69. void TileMapEditorTilesPlugin::_update_toolbar() {
  70. // Stop draggig if needed.
  71. _stop_dragging();
  72. // Hide all settings.
  73. for (int i = 0; i < tools_settings->get_child_count(); i++) {
  74. Object::cast_to<CanvasItem>(tools_settings->get_child(i))->hide();
  75. }
  76. // Show only the correct settings.
  77. if (tool_buttons_group->get_pressed_button() == select_tool_button) {
  78. } else if (tool_buttons_group->get_pressed_button() == paint_tool_button) {
  79. tools_settings_vsep->show();
  80. picker_button->show();
  81. erase_button->show();
  82. tools_settings_vsep_2->show();
  83. random_tile_checkbox->show();
  84. scatter_label->show();
  85. scatter_spinbox->show();
  86. } else if (tool_buttons_group->get_pressed_button() == line_tool_button) {
  87. tools_settings_vsep->show();
  88. picker_button->show();
  89. erase_button->show();
  90. tools_settings_vsep_2->show();
  91. random_tile_checkbox->show();
  92. scatter_label->show();
  93. scatter_spinbox->show();
  94. } else if (tool_buttons_group->get_pressed_button() == rect_tool_button) {
  95. tools_settings_vsep->show();
  96. picker_button->show();
  97. erase_button->show();
  98. tools_settings_vsep_2->show();
  99. random_tile_checkbox->show();
  100. scatter_label->show();
  101. scatter_spinbox->show();
  102. } else if (tool_buttons_group->get_pressed_button() == bucket_tool_button) {
  103. tools_settings_vsep->show();
  104. picker_button->show();
  105. erase_button->show();
  106. tools_settings_vsep_2->show();
  107. bucket_continuous_checkbox->show();
  108. random_tile_checkbox->show();
  109. scatter_label->show();
  110. scatter_spinbox->show();
  111. }
  112. }
  113. Control *TileMapEditorTilesPlugin::get_toolbar() const {
  114. return toolbar;
  115. }
  116. void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
  117. // Update the sources.
  118. int old_current = sources_list->get_current();
  119. sources_list->clear();
  120. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  121. if (!tile_map) {
  122. return;
  123. }
  124. Ref<TileSet> tile_set = tile_map->get_tileset();
  125. if (!tile_set.is_valid()) {
  126. return;
  127. }
  128. for (int i = 0; i < tile_set->get_source_count(); i++) {
  129. int source_id = tile_set->get_source_id(i);
  130. TileSetSource *source = *tile_set->get_source(source_id);
  131. Ref<Texture2D> texture;
  132. String item_text;
  133. // Atlas source.
  134. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  135. if (atlas_source) {
  136. texture = atlas_source->get_texture();
  137. if (texture.is_valid()) {
  138. item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id);
  139. } else {
  140. item_text = vformat("No Texture Atlas Source (ID: %d)", source_id);
  141. }
  142. }
  143. // Scene collection source.
  144. TileSetScenesCollectionSource *scene_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
  145. if (scene_collection_source) {
  146. texture = get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
  147. item_text = vformat(TTR("Scene Collection Source (ID: %d)"), source_id);
  148. }
  149. // Use default if not valid.
  150. if (item_text.is_empty()) {
  151. item_text = vformat(TTR("Unknown Type Source (ID: %d)"), source_id);
  152. }
  153. if (!texture.is_valid()) {
  154. texture = missing_atlas_texture_icon;
  155. }
  156. sources_list->add_item(item_text, texture);
  157. sources_list->set_item_metadata(i, source_id);
  158. }
  159. if (sources_list->get_item_count() > 0) {
  160. if (old_current > 0) {
  161. // Keep the current selected item if needed.
  162. sources_list->set_current(CLAMP(old_current, 0, sources_list->get_item_count() - 1));
  163. } else {
  164. sources_list->set_current(0);
  165. }
  166. sources_list->emit_signal(SNAME("item_selected"), sources_list->get_current());
  167. }
  168. // Synchronize
  169. TilesEditor::get_singleton()->set_sources_lists_current(sources_list->get_current());
  170. }
  171. void TileMapEditorTilesPlugin::_update_bottom_panel() {
  172. // Update the atlas display.
  173. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  174. if (!tile_map) {
  175. return;
  176. }
  177. Ref<TileSet> tile_set = tile_map->get_tileset();
  178. if (!tile_set.is_valid()) {
  179. return;
  180. }
  181. int source_index = sources_list->get_current();
  182. if (source_index >= 0 && source_index < sources_list->get_item_count()) {
  183. atlas_sources_split_container->show();
  184. missing_source_label->hide();
  185. int source_id = sources_list->get_item_metadata(source_index);
  186. TileSetSource *source = *tile_set->get_source(source_id);
  187. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  188. TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
  189. if (atlas_source) {
  190. tile_atlas_view->show();
  191. scene_tiles_list->hide();
  192. invalid_source_label->hide();
  193. _update_atlas_view();
  194. } else if (scenes_collection_source) {
  195. tile_atlas_view->hide();
  196. scene_tiles_list->show();
  197. invalid_source_label->hide();
  198. _update_scenes_collection_view();
  199. } else {
  200. tile_atlas_view->hide();
  201. scene_tiles_list->hide();
  202. invalid_source_label->show();
  203. }
  204. } else {
  205. atlas_sources_split_container->hide();
  206. missing_source_label->show();
  207. tile_atlas_view->hide();
  208. scene_tiles_list->hide();
  209. invalid_source_label->hide();
  210. }
  211. }
  212. void TileMapEditorTilesPlugin::_update_atlas_view() {
  213. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  214. if (!tile_map) {
  215. return;
  216. }
  217. Ref<TileSet> tile_set = tile_map->get_tileset();
  218. if (!tile_set.is_valid()) {
  219. return;
  220. }
  221. int source_id = sources_list->get_item_metadata(sources_list->get_current());
  222. TileSetSource *source = *tile_set->get_source(source_id);
  223. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  224. ERR_FAIL_COND(!atlas_source);
  225. tile_atlas_view->set_atlas_source(*tile_map->get_tileset(), atlas_source, source_id);
  226. TilesEditor::get_singleton()->synchronize_atlas_view(tile_atlas_view);
  227. tile_atlas_control->update();
  228. }
  229. void TileMapEditorTilesPlugin::_update_scenes_collection_view() {
  230. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  231. if (!tile_map) {
  232. return;
  233. }
  234. Ref<TileSet> tile_set = tile_map->get_tileset();
  235. if (!tile_set.is_valid()) {
  236. return;
  237. }
  238. int source_id = sources_list->get_item_metadata(sources_list->get_current());
  239. TileSetSource *source = *tile_set->get_source(source_id);
  240. TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
  241. ERR_FAIL_COND(!scenes_collection_source);
  242. // Clear the list.
  243. scene_tiles_list->clear();
  244. // Rebuild the list.
  245. for (int i = 0; i < scenes_collection_source->get_scene_tiles_count(); i++) {
  246. int scene_id = scenes_collection_source->get_scene_tile_id(i);
  247. Ref<PackedScene> scene = scenes_collection_source->get_scene_tile_scene(scene_id);
  248. int item_index = 0;
  249. if (scene.is_valid()) {
  250. item_index = scene_tiles_list->add_item(vformat("%s (Path: %s, ID: %d)", scene->get_path().get_file().get_basename(), scene->get_path(), scene_id));
  251. Variant udata = i;
  252. EditorResourcePreview::get_singleton()->queue_edited_resource_preview(scene, this, "_scene_thumbnail_done", udata);
  253. } else {
  254. item_index = scene_tiles_list->add_item(TTR("Tile with Invalid Scene"), get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons")));
  255. }
  256. scene_tiles_list->set_item_metadata(item_index, scene_id);
  257. // Check if in selection.
  258. if (tile_set_selection.has(TileMapCell(source_id, Vector2i(), scene_id))) {
  259. scene_tiles_list->select(item_index, false);
  260. }
  261. }
  262. // Icon size update.
  263. int int_size = int(EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size")) * EDSCALE;
  264. scene_tiles_list->set_fixed_icon_size(Vector2(int_size, int_size));
  265. }
  266. void TileMapEditorTilesPlugin::_scene_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud) {
  267. int index = p_ud;
  268. if (index >= 0 && index < scene_tiles_list->get_item_count()) {
  269. scene_tiles_list->set_item_icon(index, p_preview);
  270. }
  271. }
  272. void TileMapEditorTilesPlugin::_scenes_list_multi_selected(int p_index, bool p_selected) {
  273. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  274. if (!tile_map) {
  275. return;
  276. }
  277. Ref<TileSet> tile_set = tile_map->get_tileset();
  278. if (!tile_set.is_valid()) {
  279. return;
  280. }
  281. // Add or remove the Tile form the selection.
  282. int scene_id = scene_tiles_list->get_item_metadata(p_index);
  283. int source_id = sources_list->get_item_metadata(sources_list->get_current());
  284. TileSetSource *source = *tile_set->get_source(source_id);
  285. TileSetScenesCollectionSource *scenes_collection_source = Object::cast_to<TileSetScenesCollectionSource>(source);
  286. ERR_FAIL_COND(!scenes_collection_source);
  287. TileMapCell selected = TileMapCell(source_id, Vector2i(), scene_id);
  288. // Clear the selection if shift is not pressed.
  289. if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
  290. tile_set_selection.clear();
  291. }
  292. if (p_selected) {
  293. tile_set_selection.insert(selected);
  294. } else {
  295. if (tile_set_selection.has(selected)) {
  296. tile_set_selection.erase(selected);
  297. }
  298. }
  299. _update_selection_pattern_from_tileset_selection();
  300. }
  301. void TileMapEditorTilesPlugin::_scenes_list_nothing_selected() {
  302. scene_tiles_list->deselect_all();
  303. tile_set_selection.clear();
  304. tile_map_selection.clear();
  305. selection_pattern->clear();
  306. _update_selection_pattern_from_tileset_selection();
  307. }
  308. bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
  309. if (!is_visible_in_tree()) {
  310. // If the bottom editor is not visible, we ignore inputs.
  311. return false;
  312. }
  313. if (CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT) {
  314. return false;
  315. }
  316. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  317. if (!tile_map) {
  318. return false;
  319. }
  320. if (tile_map_layer < 0) {
  321. return false;
  322. }
  323. ERR_FAIL_INDEX_V(tile_map_layer, tile_map->get_layers_count(), false);
  324. Ref<TileSet> tile_set = tile_map->get_tileset();
  325. if (!tile_set.is_valid()) {
  326. return false;
  327. }
  328. // Shortcuts
  329. if (ED_IS_SHORTCUT("tiles_editor/cut", p_event) || ED_IS_SHORTCUT("tiles_editor/copy", p_event)) {
  330. // Fill in the clipboard.
  331. if (!tile_map_selection.is_empty()) {
  332. memdelete(tile_map_clipboard);
  333. TypedArray<Vector2i> coords_array;
  334. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  335. coords_array.push_back(E->get());
  336. }
  337. tile_map_clipboard = tile_map->get_pattern(tile_map_layer, coords_array);
  338. }
  339. if (ED_IS_SHORTCUT("tiles_editor/cut", p_event)) {
  340. // Delete selected tiles.
  341. if (!tile_map_selection.is_empty()) {
  342. undo_redo->create_action(TTR("Delete tiles"));
  343. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  344. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->get(), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
  345. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->get(), tile_map->get_cell_source_id(tile_map_layer, E->get()), tile_map->get_cell_atlas_coords(tile_map_layer, E->get()), tile_map->get_cell_alternative_tile(tile_map_layer, E->get()));
  346. }
  347. undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  348. tile_map_selection.clear();
  349. undo_redo->add_do_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  350. undo_redo->commit_action();
  351. }
  352. }
  353. return true;
  354. }
  355. if (ED_IS_SHORTCUT("tiles_editor/paste", p_event)) {
  356. if (drag_type == DRAG_TYPE_NONE) {
  357. drag_type = DRAG_TYPE_CLIPBOARD_PASTE;
  358. }
  359. CanvasItemEditor::get_singleton()->update_viewport();
  360. return true;
  361. }
  362. if (ED_IS_SHORTCUT("tiles_editor/cancel", p_event)) {
  363. if (drag_type == DRAG_TYPE_CLIPBOARD_PASTE) {
  364. drag_type = DRAG_TYPE_NONE;
  365. CanvasItemEditor::get_singleton()->update_viewport();
  366. return true;
  367. }
  368. }
  369. if (ED_IS_SHORTCUT("tiles_editor/delete", p_event)) {
  370. // Delete selected tiles.
  371. if (!tile_map_selection.is_empty()) {
  372. undo_redo->create_action(TTR("Delete tiles"));
  373. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  374. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E->get(), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
  375. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E->get(), tile_map->get_cell_source_id(tile_map_layer, E->get()), tile_map->get_cell_atlas_coords(tile_map_layer, E->get()), tile_map->get_cell_alternative_tile(tile_map_layer, E->get()));
  376. }
  377. undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  378. tile_map_selection.clear();
  379. undo_redo->add_do_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  380. undo_redo->commit_action();
  381. }
  382. return true;
  383. }
  384. Ref<InputEventMouseMotion> mm = p_event;
  385. if (mm.is_valid()) {
  386. has_mouse = true;
  387. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  388. Vector2 mpos = xform.affine_inverse().xform(mm->get_position());
  389. switch (drag_type) {
  390. case DRAG_TYPE_PAINT: {
  391. Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, drag_last_mouse_pos, mpos);
  392. for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
  393. if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
  394. continue;
  395. }
  396. Vector2i coords = E.key;
  397. if (!drag_modified.has(coords)) {
  398. drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
  399. }
  400. tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  401. }
  402. _fix_invalid_tiles_in_tile_map_selection();
  403. } break;
  404. case DRAG_TYPE_BUCKET: {
  405. Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(drag_last_mouse_pos), tile_map->world_to_map(mpos));
  406. for (int i = 0; i < line.size(); i++) {
  407. if (!drag_modified.has(line[i])) {
  408. Map<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_continuous_checkbox->is_pressed());
  409. for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
  410. if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
  411. continue;
  412. }
  413. Vector2i coords = E.key;
  414. if (!drag_modified.has(coords)) {
  415. drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
  416. }
  417. tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  418. }
  419. }
  420. }
  421. _fix_invalid_tiles_in_tile_map_selection();
  422. } break;
  423. default:
  424. break;
  425. }
  426. drag_last_mouse_pos = mpos;
  427. CanvasItemEditor::get_singleton()->update_viewport();
  428. return true;
  429. }
  430. Ref<InputEventMouseButton> mb = p_event;
  431. if (mb.is_valid()) {
  432. has_mouse = true;
  433. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  434. Vector2 mpos = xform.affine_inverse().xform(mb->get_position());
  435. if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
  436. if (mb->is_pressed()) {
  437. // Pressed
  438. if (drag_type == DRAG_TYPE_CLIPBOARD_PASTE) {
  439. // Do nothing.
  440. } else if (tool_buttons_group->get_pressed_button() == select_tool_button) {
  441. drag_start_mouse_pos = mpos;
  442. if (tile_map_selection.has(tile_map->world_to_map(drag_start_mouse_pos)) && !mb->is_shift_pressed()) {
  443. // Move the selection
  444. _update_selection_pattern_from_tilemap_selection(); // Make sure the pattern is up to date before moving.
  445. drag_type = DRAG_TYPE_MOVE;
  446. drag_modified.clear();
  447. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  448. Vector2i coords = E->get();
  449. drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
  450. tile_map->set_cell(tile_map_layer, coords, TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
  451. }
  452. } else {
  453. // Select tiles
  454. drag_type = DRAG_TYPE_SELECT;
  455. }
  456. } else {
  457. // Check if we are picking a tile.
  458. if (picker_button->is_pressed()) {
  459. drag_type = DRAG_TYPE_PICK;
  460. drag_start_mouse_pos = mpos;
  461. } else {
  462. // Paint otherwise.
  463. if (tool_buttons_group->get_pressed_button() == paint_tool_button) {
  464. drag_type = DRAG_TYPE_PAINT;
  465. drag_start_mouse_pos = mpos;
  466. drag_modified.clear();
  467. Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, mpos, mpos);
  468. for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
  469. if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
  470. continue;
  471. }
  472. Vector2i coords = E.key;
  473. if (!drag_modified.has(coords)) {
  474. drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
  475. }
  476. tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  477. }
  478. _fix_invalid_tiles_in_tile_map_selection();
  479. } else if (tool_buttons_group->get_pressed_button() == line_tool_button) {
  480. drag_type = DRAG_TYPE_LINE;
  481. drag_start_mouse_pos = mpos;
  482. drag_modified.clear();
  483. } else if (tool_buttons_group->get_pressed_button() == rect_tool_button) {
  484. drag_type = DRAG_TYPE_RECT;
  485. drag_start_mouse_pos = mpos;
  486. drag_modified.clear();
  487. } else if (tool_buttons_group->get_pressed_button() == bucket_tool_button) {
  488. drag_type = DRAG_TYPE_BUCKET;
  489. drag_start_mouse_pos = mpos;
  490. drag_modified.clear();
  491. Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(drag_last_mouse_pos), tile_map->world_to_map(mpos));
  492. for (int i = 0; i < line.size(); i++) {
  493. if (!drag_modified.has(line[i])) {
  494. Map<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_continuous_checkbox->is_pressed());
  495. for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
  496. if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
  497. continue;
  498. }
  499. Vector2i coords = E.key;
  500. if (!drag_modified.has(coords)) {
  501. drag_modified.insert(coords, tile_map->get_cell(tile_map_layer, coords));
  502. }
  503. tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  504. }
  505. }
  506. }
  507. _fix_invalid_tiles_in_tile_map_selection();
  508. }
  509. }
  510. }
  511. } else {
  512. // Released
  513. _stop_dragging();
  514. }
  515. CanvasItemEditor::get_singleton()->update_viewport();
  516. return true;
  517. }
  518. drag_last_mouse_pos = mpos;
  519. }
  520. return false;
  521. }
  522. void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_overlay) {
  523. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  524. if (!tile_map) {
  525. return;
  526. }
  527. if (tile_map_layer < 0) {
  528. return;
  529. }
  530. ERR_FAIL_INDEX(tile_map_layer, tile_map->get_layers_count());
  531. Ref<TileSet> tile_set = tile_map->get_tileset();
  532. if (!tile_set.is_valid()) {
  533. return;
  534. }
  535. if (!tile_map->is_visible_in_tree()) {
  536. return;
  537. }
  538. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  539. Vector2i tile_shape_size = tile_set->get_tile_size();
  540. // Draw the selection.
  541. if (is_visible_in_tree() && tool_buttons_group->get_pressed_button() == select_tool_button) {
  542. // In select mode, we only draw the current selection if we are modifying it (pressing control or shift).
  543. if (drag_type == DRAG_TYPE_MOVE || (drag_type == DRAG_TYPE_SELECT && !Input::get_singleton()->is_key_pressed(KEY_CTRL) && !Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
  544. // Do nothing
  545. } else {
  546. Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color");
  547. Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0);
  548. tile_map->draw_cells_outline(p_overlay, tile_map_selection, selection_color, xform);
  549. }
  550. }
  551. // Handle the preview of the tiles to be placed.
  552. if (is_visible_in_tree() && has_mouse) { // Only if the tilemap editor is opened and the viewport is hovered.
  553. Map<Vector2i, TileMapCell> preview;
  554. Rect2i drawn_grid_rect;
  555. if (drag_type == DRAG_TYPE_PICK) {
  556. // Draw the area being picvked.
  557. Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos) - tile_map->world_to_map(drag_start_mouse_pos)).abs();
  558. rect.size += Vector2i(1, 1);
  559. for (int x = rect.position.x; x < rect.get_end().x; x++) {
  560. for (int y = rect.position.y; y < rect.get_end().y; y++) {
  561. Vector2i coords = Vector2i(x, y);
  562. if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
  563. Transform2D tile_xform;
  564. tile_xform.set_origin(tile_map->map_to_world(coords));
  565. tile_xform.set_scale(tile_shape_size);
  566. tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0), false);
  567. }
  568. }
  569. }
  570. } else if (drag_type == DRAG_TYPE_SELECT) {
  571. // Draw the area being selected.
  572. Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos) - tile_map->world_to_map(drag_start_mouse_pos)).abs();
  573. rect.size += Vector2i(1, 1);
  574. Set<Vector2i> to_draw;
  575. for (int x = rect.position.x; x < rect.get_end().x; x++) {
  576. for (int y = rect.position.y; y < rect.get_end().y; y++) {
  577. Vector2i coords = Vector2i(x, y);
  578. if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
  579. to_draw.insert(coords);
  580. }
  581. }
  582. }
  583. tile_map->draw_cells_outline(p_overlay, to_draw, Color(1.0, 1.0, 1.0), xform);
  584. } else if (drag_type == DRAG_TYPE_MOVE) {
  585. // Preview when moving.
  586. Vector2i top_left;
  587. if (!tile_map_selection.is_empty()) {
  588. top_left = tile_map_selection.front()->get();
  589. }
  590. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  591. top_left = top_left.min(E->get());
  592. }
  593. Vector2i offset = drag_start_mouse_pos - tile_map->map_to_world(top_left);
  594. offset = tile_map->world_to_map(drag_last_mouse_pos - offset) - tile_map->world_to_map(drag_start_mouse_pos - offset);
  595. TypedArray<Vector2i> selection_used_cells = selection_pattern->get_used_cells();
  596. for (int i = 0; i < selection_used_cells.size(); i++) {
  597. Vector2i coords = tile_map->map_pattern(offset + top_left, selection_used_cells[i], selection_pattern);
  598. preview[coords] = TileMapCell(selection_pattern->get_cell_source_id(selection_used_cells[i]), selection_pattern->get_cell_atlas_coords(selection_used_cells[i]), selection_pattern->get_cell_alternative_tile(selection_used_cells[i]));
  599. }
  600. } else if (drag_type == DRAG_TYPE_CLIPBOARD_PASTE) {
  601. // Preview when pasting.
  602. Vector2 mouse_offset = (Vector2(tile_map_clipboard->get_size()) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size();
  603. TypedArray<Vector2i> clipboard_used_cells = tile_map_clipboard->get_used_cells();
  604. for (int i = 0; i < clipboard_used_cells.size(); i++) {
  605. Vector2i coords = tile_map->map_pattern(tile_map->world_to_map(drag_last_mouse_pos - mouse_offset), clipboard_used_cells[i], tile_map_clipboard);
  606. preview[coords] = TileMapCell(tile_map_clipboard->get_cell_source_id(clipboard_used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(clipboard_used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(clipboard_used_cells[i]));
  607. }
  608. } else if (!picker_button->is_pressed()) {
  609. bool expand_grid = false;
  610. if (tool_buttons_group->get_pressed_button() == paint_tool_button && drag_type == DRAG_TYPE_NONE) {
  611. // Preview for a single pattern.
  612. preview = _draw_line(drag_last_mouse_pos, drag_last_mouse_pos, drag_last_mouse_pos);
  613. expand_grid = true;
  614. } else if (tool_buttons_group->get_pressed_button() == line_tool_button) {
  615. if (drag_type == DRAG_TYPE_NONE) {
  616. // Preview for a single pattern.
  617. preview = _draw_line(drag_last_mouse_pos, drag_last_mouse_pos, drag_last_mouse_pos);
  618. expand_grid = true;
  619. } else if (drag_type == DRAG_TYPE_LINE) {
  620. // Preview for a line pattern.
  621. preview = _draw_line(drag_start_mouse_pos, drag_start_mouse_pos, drag_last_mouse_pos);
  622. expand_grid = true;
  623. }
  624. } else if (tool_buttons_group->get_pressed_button() == rect_tool_button && drag_type == DRAG_TYPE_RECT) {
  625. // Preview for a line pattern.
  626. preview = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos));
  627. expand_grid = true;
  628. } else if (tool_buttons_group->get_pressed_button() == bucket_tool_button && drag_type == DRAG_TYPE_NONE) {
  629. // Preview for a line pattern.
  630. preview = _draw_bucket_fill(tile_map->world_to_map(drag_last_mouse_pos), bucket_continuous_checkbox->is_pressed());
  631. }
  632. // Expand the grid if needed
  633. if (expand_grid && !preview.is_empty()) {
  634. drawn_grid_rect = Rect2i(preview.front()->key(), Vector2i(1, 1));
  635. for (const KeyValue<Vector2i, TileMapCell> &E : preview) {
  636. drawn_grid_rect.expand_to(E.key);
  637. }
  638. }
  639. }
  640. if (!preview.is_empty()) {
  641. const int fading = 5;
  642. // Draw the lines of the grid behind the preview.
  643. bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid");
  644. if (display_grid) {
  645. Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color");
  646. if (drawn_grid_rect.size.x > 0 && drawn_grid_rect.size.y > 0) {
  647. drawn_grid_rect = drawn_grid_rect.grow(fading);
  648. for (int x = drawn_grid_rect.position.x; x < (drawn_grid_rect.position.x + drawn_grid_rect.size.x); x++) {
  649. for (int y = drawn_grid_rect.position.y; y < (drawn_grid_rect.position.y + drawn_grid_rect.size.y); y++) {
  650. Vector2i pos_in_rect = Vector2i(x, y) - drawn_grid_rect.position;
  651. // Fade out the border of the grid.
  652. float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f);
  653. float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f);
  654. float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f);
  655. float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f);
  656. float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
  657. Transform2D tile_xform;
  658. tile_xform.set_origin(tile_map->map_to_world(Vector2(x, y)));
  659. tile_xform.set_scale(tile_shape_size);
  660. Color color = grid_color;
  661. color.a = color.a * opacity;
  662. tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, false);
  663. }
  664. }
  665. }
  666. }
  667. // Draw the preview.
  668. for (const KeyValue<Vector2i, TileMapCell> &E : preview) {
  669. Transform2D tile_xform;
  670. tile_xform.set_origin(tile_map->map_to_world(E.key));
  671. tile_xform.set_scale(tile_set->get_tile_size());
  672. if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
  673. tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true);
  674. } else {
  675. if (tile_set->has_source(E.value.source_id)) {
  676. TileSetSource *source = *tile_set->get_source(E.value.source_id);
  677. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  678. if (atlas_source) {
  679. // Get tile data.
  680. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E.value.get_atlas_coords(), E.value.alternative_tile));
  681. // Compute the offset
  682. Rect2i source_rect = atlas_source->get_tile_texture_region(E.value.get_atlas_coords());
  683. Vector2i tile_offset = atlas_source->get_tile_effective_texture_offset(E.value.get_atlas_coords(), E.value.alternative_tile);
  684. // Compute the destination rectangle in the CanvasItem.
  685. Rect2 dest_rect;
  686. dest_rect.size = source_rect.size;
  687. bool transpose = tile_data->get_transpose();
  688. if (transpose) {
  689. dest_rect.position = (tile_map->map_to_world(E.key) - Vector2(dest_rect.size.y, dest_rect.size.x) / 2 - tile_offset);
  690. } else {
  691. dest_rect.position = (tile_map->map_to_world(E.key) - dest_rect.size / 2 - tile_offset);
  692. }
  693. dest_rect = xform.xform(dest_rect);
  694. if (tile_data->get_flip_h()) {
  695. dest_rect.size.x = -dest_rect.size.x;
  696. }
  697. if (tile_data->get_flip_v()) {
  698. dest_rect.size.y = -dest_rect.size.y;
  699. }
  700. // Get the tile modulation.
  701. Color modulate = tile_data->get_modulate();
  702. Color self_modulate = tile_map->get_self_modulate();
  703. modulate *= self_modulate;
  704. // Draw the tile.
  705. p_overlay->draw_texture_rect_region(atlas_source->get_texture(), dest_rect, source_rect, modulate * Color(1.0, 1.0, 1.0, 0.5), transpose, tile_set->is_uv_clipping());
  706. } else {
  707. tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true);
  708. }
  709. } else {
  710. tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(0.0, 0.0, 0.0, 0.5), true);
  711. }
  712. }
  713. }
  714. }
  715. }
  716. }
  717. void TileMapEditorTilesPlugin::_mouse_exited_viewport() {
  718. has_mouse = false;
  719. CanvasItemEditor::get_singleton()->update_viewport();
  720. }
  721. TileMapCell TileMapEditorTilesPlugin::_pick_random_tile(const TileMapPattern *p_pattern) {
  722. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  723. if (!tile_map) {
  724. return TileMapCell();
  725. }
  726. Ref<TileSet> tile_set = tile_map->get_tileset();
  727. if (!tile_set.is_valid()) {
  728. return TileMapCell();
  729. }
  730. TypedArray<Vector2i> used_cells = p_pattern->get_used_cells();
  731. double sum = 0.0;
  732. for (int i = 0; i < used_cells.size(); i++) {
  733. int source_id = p_pattern->get_cell_source_id(used_cells[i]);
  734. Vector2i atlas_coords = p_pattern->get_cell_atlas_coords(used_cells[i]);
  735. int alternative_tile = p_pattern->get_cell_alternative_tile(used_cells[i]);
  736. TileSetSource *source = *tile_set->get_source(source_id);
  737. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  738. if (atlas_source) {
  739. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile));
  740. ERR_FAIL_COND_V(!tile_data, TileMapCell());
  741. sum += tile_data->get_probability();
  742. } else {
  743. sum += 1.0;
  744. }
  745. }
  746. double empty_probability = sum * scattering;
  747. double current = 0.0;
  748. double rand = Math::random(0.0, sum + empty_probability);
  749. for (int i = 0; i < used_cells.size(); i++) {
  750. int source_id = p_pattern->get_cell_source_id(used_cells[i]);
  751. Vector2i atlas_coords = p_pattern->get_cell_atlas_coords(used_cells[i]);
  752. int alternative_tile = p_pattern->get_cell_alternative_tile(used_cells[i]);
  753. TileSetSource *source = *tile_set->get_source(source_id);
  754. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  755. if (atlas_source) {
  756. current += Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile))->get_probability();
  757. } else {
  758. current += 1.0;
  759. }
  760. if (current >= rand) {
  761. return TileMapCell(source_id, atlas_coords, alternative_tile);
  762. }
  763. }
  764. return TileMapCell();
  765. }
  766. Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_start_drag_mouse_pos, Vector2 p_from_mouse_pos, Vector2 p_to_mouse_pos) {
  767. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  768. if (!tile_map) {
  769. return Map<Vector2i, TileMapCell>();
  770. }
  771. Ref<TileSet> tile_set = tile_map->get_tileset();
  772. if (!tile_set.is_valid()) {
  773. return Map<Vector2i, TileMapCell>();
  774. }
  775. // Get or create the pattern.
  776. TileMapPattern erase_pattern;
  777. erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
  778. TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
  779. Map<Vector2i, TileMapCell> output;
  780. if (!pattern->is_empty()) {
  781. // Paint the tiles on the tile map.
  782. if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
  783. // Paint a random tile.
  784. Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(p_from_mouse_pos), tile_map->world_to_map(p_to_mouse_pos));
  785. for (int i = 0; i < line.size(); i++) {
  786. output.insert(line[i], _pick_random_tile(pattern));
  787. }
  788. } else {
  789. // Paint the pattern.
  790. // If we paint several tiles, we virtually move the mouse as if it was in the center of the "brush"
  791. Vector2 mouse_offset = (Vector2(pattern->get_size()) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size();
  792. Vector2i last_hovered_cell = tile_map->world_to_map(p_from_mouse_pos - mouse_offset);
  793. Vector2i new_hovered_cell = tile_map->world_to_map(p_to_mouse_pos - mouse_offset);
  794. Vector2i drag_start_cell = tile_map->world_to_map(p_start_drag_mouse_pos - mouse_offset);
  795. TypedArray<Vector2i> used_cells = pattern->get_used_cells();
  796. Vector2i offset = Vector2i(Math::posmod(drag_start_cell.x, pattern->get_size().x), Math::posmod(drag_start_cell.y, pattern->get_size().y)); // Note: no posmodv for Vector2i for now. Meh.s
  797. Vector<Vector2i> line = TileMapEditor::get_line(tile_map, (last_hovered_cell - offset) / pattern->get_size(), (new_hovered_cell - offset) / pattern->get_size());
  798. for (int i = 0; i < line.size(); i++) {
  799. Vector2i top_left = line[i] * pattern->get_size() + offset;
  800. for (int j = 0; j < used_cells.size(); j++) {
  801. Vector2i coords = tile_map->map_pattern(top_left, used_cells[j], pattern);
  802. output.insert(coords, TileMapCell(pattern->get_cell_source_id(used_cells[j]), pattern->get_cell_atlas_coords(used_cells[j]), pattern->get_cell_alternative_tile(used_cells[j])));
  803. }
  804. }
  805. }
  806. }
  807. return output;
  808. }
  809. Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_rect(Vector2i p_start_cell, Vector2i p_end_cell) {
  810. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  811. if (!tile_map) {
  812. return Map<Vector2i, TileMapCell>();
  813. }
  814. Ref<TileSet> tile_set = tile_map->get_tileset();
  815. if (!tile_set.is_valid()) {
  816. return Map<Vector2i, TileMapCell>();
  817. }
  818. // Create the rect to draw.
  819. Rect2i rect = Rect2i(p_start_cell, p_end_cell - p_start_cell).abs();
  820. rect.size += Vector2i(1, 1);
  821. // Get or create the pattern.
  822. TileMapPattern erase_pattern;
  823. erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
  824. TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
  825. Map<Vector2i, TileMapCell> err_output;
  826. ERR_FAIL_COND_V(pattern->is_empty(), err_output);
  827. // Compute the offset to align things to the bottom or right.
  828. bool aligned_right = p_end_cell.x < p_start_cell.x;
  829. bool valigned_bottom = p_end_cell.y < p_start_cell.y;
  830. Vector2i offset = Vector2i(aligned_right ? -(pattern->get_size().x - (rect.get_size().x % pattern->get_size().x)) : 0, valigned_bottom ? -(pattern->get_size().y - (rect.get_size().y % pattern->get_size().y)) : 0);
  831. Map<Vector2i, TileMapCell> output;
  832. if (!pattern->is_empty()) {
  833. if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
  834. // Paint a random tile.
  835. for (int x = 0; x < rect.size.x; x++) {
  836. for (int y = 0; y < rect.size.y; y++) {
  837. Vector2i coords = rect.position + Vector2i(x, y);
  838. output.insert(coords, _pick_random_tile(pattern));
  839. }
  840. }
  841. } else {
  842. // Paint the pattern.
  843. TypedArray<Vector2i> used_cells = pattern->get_used_cells();
  844. for (int x = 0; x <= rect.size.x / pattern->get_size().x; x++) {
  845. for (int y = 0; y <= rect.size.y / pattern->get_size().y; y++) {
  846. Vector2i pattern_coords = rect.position + Vector2i(x, y) * pattern->get_size() + offset;
  847. for (int j = 0; j < used_cells.size(); j++) {
  848. Vector2i coords = pattern_coords + used_cells[j];
  849. if (rect.has_point(coords)) {
  850. output.insert(coords, TileMapCell(pattern->get_cell_source_id(used_cells[j]), pattern->get_cell_atlas_coords(used_cells[j]), pattern->get_cell_alternative_tile(used_cells[j])));
  851. }
  852. }
  853. }
  854. }
  855. }
  856. }
  857. return output;
  858. }
  859. Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i p_coords, bool p_contiguous) {
  860. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  861. if (!tile_map) {
  862. return Map<Vector2i, TileMapCell>();
  863. }
  864. if (tile_map_layer < 0) {
  865. return Map<Vector2i, TileMapCell>();
  866. }
  867. Map<Vector2i, TileMapCell> output;
  868. ERR_FAIL_INDEX_V(tile_map_layer, tile_map->get_layers_count(), output);
  869. Ref<TileSet> tile_set = tile_map->get_tileset();
  870. if (!tile_set.is_valid()) {
  871. return Map<Vector2i, TileMapCell>();
  872. }
  873. // Get or create the pattern.
  874. TileMapPattern erase_pattern;
  875. erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
  876. TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
  877. if (!pattern->is_empty()) {
  878. TileMapCell source = tile_map->get_cell(tile_map_layer, p_coords);
  879. // If we are filling empty tiles, compute the tilemap boundaries.
  880. Rect2i boundaries;
  881. if (source.source_id == TileSet::INVALID_SOURCE) {
  882. boundaries = tile_map->get_used_rect();
  883. }
  884. if (p_contiguous) {
  885. // Replace continuous tiles like the source.
  886. Set<Vector2i> already_checked;
  887. List<Vector2i> to_check;
  888. to_check.push_back(p_coords);
  889. while (!to_check.is_empty()) {
  890. Vector2i coords = to_check.back()->get();
  891. to_check.pop_back();
  892. if (!already_checked.has(coords)) {
  893. if (source.source_id == tile_map->get_cell_source_id(tile_map_layer, coords) &&
  894. source.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) &&
  895. source.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) &&
  896. (source.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
  897. if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
  898. // Paint a random tile.
  899. output.insert(coords, _pick_random_tile(pattern));
  900. } else {
  901. // Paint the pattern.
  902. Vector2i pattern_coords = (coords - p_coords) % pattern->get_size(); // Note: it would be good to have posmodv for Vector2i.
  903. pattern_coords.x = pattern_coords.x < 0 ? pattern_coords.x + pattern->get_size().x : pattern_coords.x;
  904. pattern_coords.y = pattern_coords.y < 0 ? pattern_coords.y + pattern->get_size().y : pattern_coords.y;
  905. if (pattern->has_cell(pattern_coords)) {
  906. output.insert(coords, TileMapCell(pattern->get_cell_source_id(pattern_coords), pattern->get_cell_atlas_coords(pattern_coords), pattern->get_cell_alternative_tile(pattern_coords)));
  907. } else {
  908. output.insert(coords, TileMapCell());
  909. }
  910. }
  911. // Get surrounding tiles (handles different tile shapes).
  912. TypedArray<Vector2i> around = tile_map->get_surrounding_tiles(coords);
  913. for (int i = 0; i < around.size(); i++) {
  914. to_check.push_back(around[i]);
  915. }
  916. }
  917. already_checked.insert(coords);
  918. }
  919. }
  920. } else {
  921. // Replace all tiles like the source.
  922. TypedArray<Vector2i> to_check;
  923. if (source.source_id == TileSet::INVALID_SOURCE) {
  924. Rect2i rect = tile_map->get_used_rect();
  925. if (rect.has_no_area()) {
  926. rect = Rect2i(p_coords, Vector2i(1, 1));
  927. }
  928. for (int x = boundaries.position.x; x < boundaries.get_end().x; x++) {
  929. for (int y = boundaries.position.y; y < boundaries.get_end().y; y++) {
  930. to_check.append(Vector2i(x, y));
  931. }
  932. }
  933. } else {
  934. to_check = tile_map->get_used_cells(tile_map_layer);
  935. }
  936. for (int i = 0; i < to_check.size(); i++) {
  937. Vector2i coords = to_check[i];
  938. if (source.source_id == tile_map->get_cell_source_id(tile_map_layer, coords) &&
  939. source.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) &&
  940. source.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) &&
  941. (source.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
  942. if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
  943. // Paint a random tile.
  944. output.insert(coords, _pick_random_tile(pattern));
  945. } else {
  946. // Paint the pattern.
  947. Vector2i pattern_coords = (coords - p_coords) % pattern->get_size(); // Note: it would be good to have posmodv for Vector2i.
  948. pattern_coords.x = pattern_coords.x < 0 ? pattern_coords.x + pattern->get_size().x : pattern_coords.x;
  949. pattern_coords.y = pattern_coords.y < 0 ? pattern_coords.y + pattern->get_size().y : pattern_coords.y;
  950. if (pattern->has_cell(pattern_coords)) {
  951. output.insert(coords, TileMapCell(pattern->get_cell_source_id(pattern_coords), pattern->get_cell_atlas_coords(pattern_coords), pattern->get_cell_alternative_tile(pattern_coords)));
  952. } else {
  953. output.insert(coords, TileMapCell());
  954. }
  955. }
  956. }
  957. }
  958. }
  959. }
  960. return output;
  961. }
  962. void TileMapEditorTilesPlugin::_stop_dragging() {
  963. if (drag_type == DRAG_TYPE_NONE) {
  964. return;
  965. }
  966. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  967. if (!tile_map) {
  968. return;
  969. }
  970. if (tile_map_layer < 0) {
  971. return;
  972. }
  973. ERR_FAIL_INDEX(tile_map_layer, tile_map->get_layers_count());
  974. Ref<TileSet> tile_set = tile_map->get_tileset();
  975. if (!tile_set.is_valid()) {
  976. return;
  977. }
  978. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  979. Vector2 mpos = xform.affine_inverse().xform(CanvasItemEditor::get_singleton()->get_viewport_control()->get_local_mouse_position());
  980. switch (drag_type) {
  981. case DRAG_TYPE_SELECT: {
  982. undo_redo->create_action(TTR("Change selection"));
  983. undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  984. if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT) && !Input::get_singleton()->is_key_pressed(KEY_CTRL)) {
  985. tile_map_selection.clear();
  986. }
  987. Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos) - tile_map->world_to_map(drag_start_mouse_pos)).abs();
  988. for (int x = rect.position.x; x <= rect.get_end().x; x++) {
  989. for (int y = rect.position.y; y <= rect.get_end().y; y++) {
  990. Vector2i coords = Vector2i(x, y);
  991. if (Input::get_singleton()->is_key_pressed(KEY_CTRL)) {
  992. if (tile_map_selection.has(coords)) {
  993. tile_map_selection.erase(coords);
  994. }
  995. } else {
  996. if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
  997. tile_map_selection.insert(coords);
  998. }
  999. }
  1000. }
  1001. }
  1002. undo_redo->add_do_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  1003. undo_redo->commit_action(false);
  1004. _update_selection_pattern_from_tilemap_selection();
  1005. _update_tileset_selection_from_selection_pattern();
  1006. } break;
  1007. case DRAG_TYPE_MOVE: {
  1008. Vector2i top_left;
  1009. if (!tile_map_selection.is_empty()) {
  1010. top_left = tile_map_selection.front()->get();
  1011. }
  1012. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  1013. top_left = top_left.min(E->get());
  1014. }
  1015. Vector2i offset = drag_start_mouse_pos - tile_map->map_to_world(top_left);
  1016. offset = tile_map->world_to_map(mpos - offset) - tile_map->world_to_map(drag_start_mouse_pos - offset);
  1017. TypedArray<Vector2i> selection_used_cells = selection_pattern->get_used_cells();
  1018. Vector2i coords;
  1019. Map<Vector2i, TileMapCell> cells_undo;
  1020. for (int i = 0; i < selection_used_cells.size(); i++) {
  1021. coords = tile_map->map_pattern(top_left, selection_used_cells[i], selection_pattern);
  1022. cells_undo[coords] = TileMapCell(drag_modified[coords].source_id, drag_modified[coords].get_atlas_coords(), drag_modified[coords].alternative_tile);
  1023. coords = tile_map->map_pattern(top_left + offset, selection_used_cells[i], selection_pattern);
  1024. cells_undo[coords] = TileMapCell(tile_map->get_cell_source_id(tile_map_layer, coords), tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords));
  1025. }
  1026. Map<Vector2i, TileMapCell> cells_do;
  1027. for (int i = 0; i < selection_used_cells.size(); i++) {
  1028. coords = tile_map->map_pattern(top_left, selection_used_cells[i], selection_pattern);
  1029. cells_do[coords] = TileMapCell();
  1030. }
  1031. for (int i = 0; i < selection_used_cells.size(); i++) {
  1032. coords = tile_map->map_pattern(top_left + offset, selection_used_cells[i], selection_pattern);
  1033. cells_do[coords] = TileMapCell(selection_pattern->get_cell_source_id(selection_used_cells[i]), selection_pattern->get_cell_atlas_coords(selection_used_cells[i]), selection_pattern->get_cell_alternative_tile(selection_used_cells[i]));
  1034. }
  1035. undo_redo->create_action(TTR("Move tiles"));
  1036. // Move the tiles.
  1037. for (const KeyValue<Vector2i, TileMapCell> &E : cells_do) {
  1038. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  1039. }
  1040. for (const KeyValue<Vector2i, TileMapCell> &E : cells_undo) {
  1041. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  1042. }
  1043. // Update the selection.
  1044. undo_redo->add_undo_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  1045. tile_map_selection.clear();
  1046. for (int i = 0; i < selection_used_cells.size(); i++) {
  1047. coords = tile_map->map_pattern(top_left + offset, selection_used_cells[i], selection_pattern);
  1048. tile_map_selection.insert(coords);
  1049. }
  1050. undo_redo->add_do_method(this, "_set_tile_map_selection", _get_tile_map_selection());
  1051. undo_redo->commit_action();
  1052. } break;
  1053. case DRAG_TYPE_PICK: {
  1054. Rect2i rect = Rect2i(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos) - tile_map->world_to_map(drag_start_mouse_pos)).abs();
  1055. rect.size += Vector2i(1, 1);
  1056. memdelete(selection_pattern);
  1057. TypedArray<Vector2i> coords_array;
  1058. for (int x = rect.position.x; x < rect.get_end().x; x++) {
  1059. for (int y = rect.position.y; y < rect.get_end().y; y++) {
  1060. Vector2i coords = Vector2i(x, y);
  1061. if (tile_map->get_cell_source_id(tile_map_layer, coords) != TileSet::INVALID_SOURCE) {
  1062. coords_array.push_back(coords);
  1063. }
  1064. }
  1065. }
  1066. selection_pattern = tile_map->get_pattern(tile_map_layer, coords_array);
  1067. if (!selection_pattern->is_empty()) {
  1068. _update_tileset_selection_from_selection_pattern();
  1069. } else {
  1070. _update_selection_pattern_from_tileset_selection();
  1071. }
  1072. picker_button->set_pressed(false);
  1073. } break;
  1074. case DRAG_TYPE_PAINT: {
  1075. undo_redo->create_action(TTR("Paint tiles"));
  1076. for (const KeyValue<Vector2i, TileMapCell> &E : drag_modified) {
  1077. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key));
  1078. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  1079. }
  1080. undo_redo->commit_action(false);
  1081. } break;
  1082. case DRAG_TYPE_LINE: {
  1083. Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, drag_start_mouse_pos, mpos);
  1084. undo_redo->create_action(TTR("Paint tiles"));
  1085. for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
  1086. if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
  1087. continue;
  1088. }
  1089. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  1090. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key));
  1091. }
  1092. undo_redo->commit_action();
  1093. } break;
  1094. case DRAG_TYPE_RECT: {
  1095. Map<Vector2i, TileMapCell> to_draw = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos));
  1096. undo_redo->create_action(TTR("Paint tiles"));
  1097. for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
  1098. if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
  1099. continue;
  1100. }
  1101. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  1102. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key));
  1103. }
  1104. undo_redo->commit_action();
  1105. } break;
  1106. case DRAG_TYPE_BUCKET: {
  1107. undo_redo->create_action(TTR("Paint tiles"));
  1108. for (const KeyValue<Vector2i, TileMapCell> &E : drag_modified) {
  1109. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key));
  1110. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  1111. }
  1112. undo_redo->commit_action(false);
  1113. } break;
  1114. case DRAG_TYPE_CLIPBOARD_PASTE: {
  1115. Vector2 mouse_offset = (Vector2(tile_map_clipboard->get_size()) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size();
  1116. undo_redo->create_action(TTR("Paste tiles"));
  1117. TypedArray<Vector2i> used_cells = tile_map_clipboard->get_used_cells();
  1118. for (int i = 0; i < used_cells.size(); i++) {
  1119. Vector2i coords = tile_map->map_pattern(tile_map->world_to_map(mpos - mouse_offset), used_cells[i], tile_map_clipboard);
  1120. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, coords, tile_map_clipboard->get_cell_source_id(used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(used_cells[i]));
  1121. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, coords, tile_map->get_cell_source_id(tile_map_layer, coords), tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords));
  1122. }
  1123. undo_redo->commit_action();
  1124. } break;
  1125. default:
  1126. break;
  1127. }
  1128. drag_type = DRAG_TYPE_NONE;
  1129. }
  1130. void TileMapEditorTilesPlugin::_update_fix_selected_and_hovered() {
  1131. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1132. if (!tile_map) {
  1133. hovered_tile.source_id = TileSet::INVALID_SOURCE;
  1134. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1135. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1136. tile_set_selection.clear();
  1137. tile_map_selection.clear();
  1138. selection_pattern->clear();
  1139. return;
  1140. }
  1141. Ref<TileSet> tile_set = tile_map->get_tileset();
  1142. if (!tile_set.is_valid()) {
  1143. hovered_tile.source_id = TileSet::INVALID_SOURCE;
  1144. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1145. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1146. tile_set_selection.clear();
  1147. tile_map_selection.clear();
  1148. selection_pattern->clear();
  1149. return;
  1150. }
  1151. int source_index = sources_list->get_current();
  1152. if (source_index < 0 || source_index >= sources_list->get_item_count()) {
  1153. hovered_tile.source_id = TileSet::INVALID_SOURCE;
  1154. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1155. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1156. tile_set_selection.clear();
  1157. tile_map_selection.clear();
  1158. selection_pattern->clear();
  1159. return;
  1160. }
  1161. int source_id = sources_list->get_item_metadata(source_index);
  1162. // Clear hovered if needed.
  1163. if (source_id != hovered_tile.source_id ||
  1164. !tile_set->has_source(hovered_tile.source_id) ||
  1165. !tile_set->get_source(hovered_tile.source_id)->has_tile(hovered_tile.get_atlas_coords()) ||
  1166. !tile_set->get_source(hovered_tile.source_id)->has_alternative_tile(hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile)) {
  1167. hovered_tile.source_id = TileSet::INVALID_SOURCE;
  1168. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1169. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1170. }
  1171. // Selection if needed.
  1172. for (Set<TileMapCell>::Element *E = tile_set_selection.front(); E; E = E->next()) {
  1173. const TileMapCell *selected = &(E->get());
  1174. if (!tile_set->has_source(selected->source_id) ||
  1175. !tile_set->get_source(selected->source_id)->has_tile(selected->get_atlas_coords()) ||
  1176. !tile_set->get_source(selected->source_id)->has_alternative_tile(selected->get_atlas_coords(), selected->alternative_tile)) {
  1177. tile_set_selection.erase(E);
  1178. }
  1179. }
  1180. if (!tile_map_selection.is_empty()) {
  1181. _update_selection_pattern_from_tilemap_selection();
  1182. } else {
  1183. _update_selection_pattern_from_tileset_selection();
  1184. }
  1185. }
  1186. void TileMapEditorTilesPlugin::_fix_invalid_tiles_in_tile_map_selection() {
  1187. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1188. if (!tile_map) {
  1189. return;
  1190. }
  1191. Set<Vector2i> to_remove;
  1192. for (Vector2i selected : tile_map_selection) {
  1193. TileMapCell cell = tile_map->get_cell(tile_map_layer, selected);
  1194. if (cell.source_id == TileSet::INVALID_SOURCE && cell.get_atlas_coords() == TileSetSource::INVALID_ATLAS_COORDS && cell.alternative_tile == TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) {
  1195. to_remove.insert(selected);
  1196. }
  1197. }
  1198. for (Vector2i cell : to_remove) {
  1199. tile_map_selection.erase(cell);
  1200. }
  1201. }
  1202. void TileMapEditorTilesPlugin::_update_selection_pattern_from_tilemap_selection() {
  1203. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1204. if (!tile_map) {
  1205. return;
  1206. }
  1207. ERR_FAIL_INDEX(tile_map_layer, tile_map->get_layers_count());
  1208. memdelete(selection_pattern);
  1209. TypedArray<Vector2i> coords_array;
  1210. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  1211. coords_array.push_back(E->get());
  1212. }
  1213. selection_pattern = tile_map->get_pattern(tile_map_layer, coords_array);
  1214. }
  1215. void TileMapEditorTilesPlugin::_update_selection_pattern_from_tileset_selection() {
  1216. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1217. if (!tile_map) {
  1218. return;
  1219. }
  1220. Ref<TileSet> tile_set = tile_map->get_tileset();
  1221. if (!tile_set.is_valid()) {
  1222. return;
  1223. }
  1224. // Clear the tilemap selection.
  1225. tile_map_selection.clear();
  1226. // Clear the selected pattern.
  1227. selection_pattern->clear();
  1228. // Group per source.
  1229. Map<int, List<const TileMapCell *>> per_source;
  1230. for (Set<TileMapCell>::Element *E = tile_set_selection.front(); E; E = E->next()) {
  1231. per_source[E->get().source_id].push_back(&(E->get()));
  1232. }
  1233. int vertical_offset = 0;
  1234. for (const KeyValue<int, List<const TileMapCell *>> &E_source : per_source) {
  1235. // Per source.
  1236. List<const TileMapCell *> unorganized;
  1237. Rect2i encompassing_rect_coords;
  1238. Map<Vector2i, const TileMapCell *> organized_pattern;
  1239. TileSetSource *source = *tile_set->get_source(E_source.key);
  1240. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  1241. if (atlas_source) {
  1242. // Organize using coordinates.
  1243. for (const TileMapCell *current : E_source.value) {
  1244. if (current->alternative_tile == 0) {
  1245. organized_pattern[current->get_atlas_coords()] = current;
  1246. } else {
  1247. unorganized.push_back(current);
  1248. }
  1249. }
  1250. // Compute the encompassing rect for the organized pattern.
  1251. Map<Vector2i, const TileMapCell *>::Element *E_cell = organized_pattern.front();
  1252. if (E_cell) {
  1253. encompassing_rect_coords = Rect2i(E_cell->key(), Vector2i(1, 1));
  1254. for (; E_cell; E_cell = E_cell->next()) {
  1255. encompassing_rect_coords.expand_to(E_cell->key() + Vector2i(1, 1));
  1256. encompassing_rect_coords.expand_to(E_cell->key());
  1257. }
  1258. }
  1259. } else {
  1260. // Add everything unorganized.
  1261. for (const TileMapCell *cell : E_source.value) {
  1262. unorganized.push_back(cell);
  1263. }
  1264. }
  1265. // Now add everything to the output pattern.
  1266. for (const KeyValue<Vector2i, const TileMapCell *> &E_cell : organized_pattern) {
  1267. selection_pattern->set_cell(E_cell.key - encompassing_rect_coords.position + Vector2i(0, vertical_offset), E_cell.value->source_id, E_cell.value->get_atlas_coords(), E_cell.value->alternative_tile);
  1268. }
  1269. Vector2i organized_size = selection_pattern->get_size();
  1270. int unorganized_index = 0;
  1271. for (const TileMapCell *cell : unorganized) {
  1272. selection_pattern->set_cell(Vector2(organized_size.x + unorganized_index, vertical_offset), cell->source_id, cell->get_atlas_coords(), cell->alternative_tile);
  1273. unorganized_index++;
  1274. }
  1275. vertical_offset += MAX(organized_size.y, 1);
  1276. }
  1277. CanvasItemEditor::get_singleton()->update_viewport();
  1278. }
  1279. void TileMapEditorTilesPlugin::_update_tileset_selection_from_selection_pattern() {
  1280. tile_set_selection.clear();
  1281. TypedArray<Vector2i> used_cells = selection_pattern->get_used_cells();
  1282. for (int i = 0; i < used_cells.size(); i++) {
  1283. Vector2i coords = used_cells[i];
  1284. if (selection_pattern->get_cell_source_id(coords) != TileSet::INVALID_SOURCE) {
  1285. tile_set_selection.insert(TileMapCell(selection_pattern->get_cell_source_id(coords), selection_pattern->get_cell_atlas_coords(coords), selection_pattern->get_cell_alternative_tile(coords)));
  1286. }
  1287. }
  1288. _update_bottom_panel();
  1289. }
  1290. void TileMapEditorTilesPlugin::_tile_atlas_control_draw() {
  1291. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1292. if (!tile_map) {
  1293. return;
  1294. }
  1295. Ref<TileSet> tile_set = tile_map->get_tileset();
  1296. if (!tile_set.is_valid()) {
  1297. return;
  1298. }
  1299. int source_index = sources_list->get_current();
  1300. if (source_index < 0 || source_index >= sources_list->get_item_count()) {
  1301. return;
  1302. }
  1303. int source_id = sources_list->get_item_metadata(source_index);
  1304. if (!tile_set->has_source(source_id)) {
  1305. return;
  1306. }
  1307. TileSetAtlasSource *atlas = Object::cast_to<TileSetAtlasSource>(*tile_set->get_source(source_id));
  1308. if (!atlas) {
  1309. return;
  1310. }
  1311. // Draw the selection.
  1312. Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color");
  1313. Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0);
  1314. for (Set<TileMapCell>::Element *E = tile_set_selection.front(); E; E = E->next()) {
  1315. if (E->get().source_id == source_id && E->get().alternative_tile == 0) {
  1316. for (int frame = 0; frame < atlas->get_tile_animation_frames_count(E->get().get_atlas_coords()); frame++) {
  1317. Color color = selection_color;
  1318. if (frame > 0) {
  1319. color.a *= 0.3;
  1320. }
  1321. tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get().get_atlas_coords(), frame), color, false);
  1322. }
  1323. }
  1324. }
  1325. // Draw the hovered tile.
  1326. if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0 && !tile_set_dragging_selection) {
  1327. for (int frame = 0; frame < atlas->get_tile_animation_frames_count(hovered_tile.get_atlas_coords()); frame++) {
  1328. Color color = Color(1.0, 1.0, 1.0);
  1329. if (frame > 0) {
  1330. color.a *= 0.3;
  1331. }
  1332. tile_atlas_control->draw_rect(atlas->get_tile_texture_region(hovered_tile.get_atlas_coords(), frame), color, false);
  1333. }
  1334. }
  1335. // Draw the selection rect.
  1336. if (tile_set_dragging_selection) {
  1337. Vector2i start_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_set_drag_start_mouse_pos);
  1338. Vector2i end_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position());
  1339. Rect2i region = Rect2i(start_tile, end_tile - start_tile).abs();
  1340. region.size += Vector2i(1, 1);
  1341. Set<Vector2i> to_draw;
  1342. for (int x = region.position.x; x < region.get_end().x; x++) {
  1343. for (int y = region.position.y; y < region.get_end().y; y++) {
  1344. Vector2i tile = atlas->get_tile_at_coords(Vector2i(x, y));
  1345. if (tile != TileSetSource::INVALID_ATLAS_COORDS) {
  1346. to_draw.insert(tile);
  1347. }
  1348. }
  1349. }
  1350. Color selection_rect_color = selection_color.lightened(0.2);
  1351. for (Set<Vector2i>::Element *E = to_draw.front(); E; E = E->next()) {
  1352. tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get()), selection_rect_color, false);
  1353. }
  1354. }
  1355. }
  1356. void TileMapEditorTilesPlugin::_tile_atlas_control_mouse_exited() {
  1357. hovered_tile.source_id = TileSet::INVALID_SOURCE;
  1358. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1359. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1360. tile_set_dragging_selection = false;
  1361. tile_atlas_control->update();
  1362. }
  1363. void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Ref<InputEvent> &p_event) {
  1364. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1365. if (!tile_map) {
  1366. return;
  1367. }
  1368. Ref<TileSet> tile_set = tile_map->get_tileset();
  1369. if (!tile_set.is_valid()) {
  1370. return;
  1371. }
  1372. int source_index = sources_list->get_current();
  1373. if (source_index < 0 || source_index >= sources_list->get_item_count()) {
  1374. return;
  1375. }
  1376. int source_id = sources_list->get_item_metadata(source_index);
  1377. if (!tile_set->has_source(source_id)) {
  1378. return;
  1379. }
  1380. TileSetAtlasSource *atlas = Object::cast_to<TileSetAtlasSource>(*tile_set->get_source(source_id));
  1381. if (!atlas) {
  1382. return;
  1383. }
  1384. // Update the hovered tile
  1385. hovered_tile.source_id = source_id;
  1386. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1387. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1388. Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position());
  1389. if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
  1390. coords = atlas->get_tile_at_coords(coords);
  1391. if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
  1392. hovered_tile.set_atlas_coords(coords);
  1393. hovered_tile.alternative_tile = 0;
  1394. }
  1395. }
  1396. Ref<InputEventMouseMotion> mm = p_event;
  1397. if (mm.is_valid()) {
  1398. tile_atlas_control->update();
  1399. alternative_tiles_control->update();
  1400. }
  1401. Ref<InputEventMouseButton> mb = p_event;
  1402. if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
  1403. if (mb->is_pressed()) { // Pressed
  1404. tile_set_dragging_selection = true;
  1405. tile_set_drag_start_mouse_pos = tile_atlas_control->get_local_mouse_position();
  1406. if (!mb->is_shift_pressed()) {
  1407. tile_set_selection.clear();
  1408. }
  1409. if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile == 0) {
  1410. if (mb->is_shift_pressed() && tile_set_selection.has(TileMapCell(source_id, hovered_tile.get_atlas_coords(), 0))) {
  1411. tile_set_selection.erase(TileMapCell(source_id, hovered_tile.get_atlas_coords(), 0));
  1412. } else {
  1413. tile_set_selection.insert(TileMapCell(source_id, hovered_tile.get_atlas_coords(), 0));
  1414. }
  1415. }
  1416. _update_selection_pattern_from_tileset_selection();
  1417. } else { // Released
  1418. if (tile_set_dragging_selection) {
  1419. if (!mb->is_shift_pressed()) {
  1420. tile_set_selection.clear();
  1421. }
  1422. // Compute the covered area.
  1423. Vector2i start_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_set_drag_start_mouse_pos);
  1424. Vector2i end_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position());
  1425. if (start_tile != TileSetSource::INVALID_ATLAS_COORDS && end_tile != TileSetSource::INVALID_ATLAS_COORDS) {
  1426. Rect2i region = Rect2i(start_tile, end_tile - start_tile).abs();
  1427. region.size += Vector2i(1, 1);
  1428. // To update the selection, we copy the selected/not selected status of the tiles we drag from.
  1429. Vector2i start_coords = atlas->get_tile_at_coords(start_tile);
  1430. if (mb->is_shift_pressed() && start_coords != TileSetSource::INVALID_ATLAS_COORDS && !tile_set_selection.has(TileMapCell(source_id, start_coords, 0))) {
  1431. // Remove from the selection.
  1432. for (int x = region.position.x; x < region.get_end().x; x++) {
  1433. for (int y = region.position.y; y < region.get_end().y; y++) {
  1434. Vector2i tile_coords = atlas->get_tile_at_coords(Vector2i(x, y));
  1435. if (tile_coords != TileSetSource::INVALID_ATLAS_COORDS && tile_set_selection.has(TileMapCell(source_id, tile_coords, 0))) {
  1436. tile_set_selection.erase(TileMapCell(source_id, tile_coords, 0));
  1437. }
  1438. }
  1439. }
  1440. } else {
  1441. // Insert in the selection.
  1442. for (int x = region.position.x; x < region.get_end().x; x++) {
  1443. for (int y = region.position.y; y < region.get_end().y; y++) {
  1444. Vector2i tile_coords = atlas->get_tile_at_coords(Vector2i(x, y));
  1445. if (tile_coords != TileSetSource::INVALID_ATLAS_COORDS) {
  1446. tile_set_selection.insert(TileMapCell(source_id, tile_coords, 0));
  1447. }
  1448. }
  1449. }
  1450. }
  1451. }
  1452. _update_selection_pattern_from_tileset_selection();
  1453. }
  1454. tile_set_dragging_selection = false;
  1455. }
  1456. tile_atlas_control->update();
  1457. }
  1458. }
  1459. void TileMapEditorTilesPlugin::_tile_alternatives_control_draw() {
  1460. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1461. if (!tile_map) {
  1462. return;
  1463. }
  1464. Ref<TileSet> tile_set = tile_map->get_tileset();
  1465. if (!tile_set.is_valid()) {
  1466. return;
  1467. }
  1468. int source_index = sources_list->get_current();
  1469. if (source_index < 0 || source_index >= sources_list->get_item_count()) {
  1470. return;
  1471. }
  1472. int source_id = sources_list->get_item_metadata(source_index);
  1473. if (!tile_set->has_source(source_id)) {
  1474. return;
  1475. }
  1476. TileSetAtlasSource *atlas = Object::cast_to<TileSetAtlasSource>(*tile_set->get_source(source_id));
  1477. if (!atlas) {
  1478. return;
  1479. }
  1480. // Draw the selection.
  1481. for (Set<TileMapCell>::Element *E = tile_set_selection.front(); E; E = E->next()) {
  1482. if (E->get().source_id == source_id && E->get().get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && E->get().alternative_tile > 0) {
  1483. Rect2i rect = tile_atlas_view->get_alternative_tile_rect(E->get().get_atlas_coords(), E->get().alternative_tile);
  1484. if (rect != Rect2i()) {
  1485. alternative_tiles_control->draw_rect(rect, Color(0.2, 0.2, 1.0), false);
  1486. }
  1487. }
  1488. }
  1489. // Draw hovered tile.
  1490. if (hovered_tile.get_atlas_coords() != TileSetSource::INVALID_ATLAS_COORDS && hovered_tile.alternative_tile > 0) {
  1491. Rect2i rect = tile_atlas_view->get_alternative_tile_rect(hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile);
  1492. if (rect != Rect2i()) {
  1493. alternative_tiles_control->draw_rect(rect, Color(1.0, 1.0, 1.0), false);
  1494. }
  1495. }
  1496. }
  1497. void TileMapEditorTilesPlugin::_tile_alternatives_control_mouse_exited() {
  1498. hovered_tile.source_id = TileSet::INVALID_SOURCE;
  1499. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1500. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1501. tile_set_dragging_selection = false;
  1502. alternative_tiles_control->update();
  1503. }
  1504. void TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input(const Ref<InputEvent> &p_event) {
  1505. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  1506. if (!tile_map) {
  1507. return;
  1508. }
  1509. Ref<TileSet> tile_set = tile_map->get_tileset();
  1510. if (!tile_set.is_valid()) {
  1511. return;
  1512. }
  1513. int source_index = sources_list->get_current();
  1514. if (source_index < 0 || source_index >= sources_list->get_item_count()) {
  1515. return;
  1516. }
  1517. int source_id = sources_list->get_item_metadata(source_index);
  1518. if (!tile_set->has_source(source_id)) {
  1519. return;
  1520. }
  1521. TileSetAtlasSource *atlas = Object::cast_to<TileSetAtlasSource>(*tile_set->get_source(source_id));
  1522. if (!atlas) {
  1523. return;
  1524. }
  1525. // Update the hovered tile
  1526. hovered_tile.source_id = source_id;
  1527. hovered_tile.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  1528. hovered_tile.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  1529. Vector3i alternative_coords = tile_atlas_view->get_alternative_tile_at_pos(alternative_tiles_control->get_local_mouse_position());
  1530. Vector2i coords = Vector2i(alternative_coords.x, alternative_coords.y);
  1531. int alternative = alternative_coords.z;
  1532. if (coords != TileSetSource::INVALID_ATLAS_COORDS && alternative != TileSetSource::INVALID_TILE_ALTERNATIVE) {
  1533. hovered_tile.set_atlas_coords(coords);
  1534. hovered_tile.alternative_tile = alternative;
  1535. }
  1536. Ref<InputEventMouseMotion> mm = p_event;
  1537. if (mm.is_valid()) {
  1538. tile_atlas_control->update();
  1539. alternative_tiles_control->update();
  1540. }
  1541. Ref<InputEventMouseButton> mb = p_event;
  1542. if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
  1543. if (mb->is_pressed()) { // Pressed
  1544. // Left click pressed.
  1545. if (!mb->is_shift_pressed()) {
  1546. tile_set_selection.clear();
  1547. }
  1548. if (coords != TileSetSource::INVALID_ATLAS_COORDS && alternative != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) {
  1549. if (mb->is_shift_pressed() && tile_set_selection.has(TileMapCell(source_id, hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile))) {
  1550. tile_set_selection.erase(TileMapCell(source_id, hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile));
  1551. } else {
  1552. tile_set_selection.insert(TileMapCell(source_id, hovered_tile.get_atlas_coords(), hovered_tile.alternative_tile));
  1553. }
  1554. }
  1555. _update_selection_pattern_from_tileset_selection();
  1556. }
  1557. tile_atlas_control->update();
  1558. alternative_tiles_control->update();
  1559. }
  1560. }
  1561. void TileMapEditorTilesPlugin::_set_tile_map_selection(const TypedArray<Vector2i> &p_selection) {
  1562. tile_map_selection.clear();
  1563. for (int i = 0; i < p_selection.size(); i++) {
  1564. tile_map_selection.insert(p_selection[i]);
  1565. }
  1566. _update_selection_pattern_from_tilemap_selection();
  1567. _update_tileset_selection_from_selection_pattern();
  1568. CanvasItemEditor::get_singleton()->update_viewport();
  1569. }
  1570. TypedArray<Vector2i> TileMapEditorTilesPlugin::_get_tile_map_selection() const {
  1571. TypedArray<Vector2i> output;
  1572. for (Set<Vector2i>::Element *E = tile_map_selection.front(); E; E = E->next()) {
  1573. output.push_back(E->get());
  1574. }
  1575. return output;
  1576. }
  1577. void TileMapEditorTilesPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_layer) {
  1578. _stop_dragging(); // Avoids staying in a wrong drag state.
  1579. if (tile_map_id != p_tile_map_id) {
  1580. tile_map_id = p_tile_map_id;
  1581. // Clear the selection.
  1582. tile_set_selection.clear();
  1583. tile_map_selection.clear();
  1584. selection_pattern->clear();
  1585. }
  1586. tile_map_layer = p_tile_map_layer;
  1587. }
  1588. void TileMapEditorTilesPlugin::_bind_methods() {
  1589. ClassDB::bind_method(D_METHOD("_scene_thumbnail_done"), &TileMapEditorTilesPlugin::_scene_thumbnail_done);
  1590. ClassDB::bind_method(D_METHOD("_set_tile_map_selection", "selection"), &TileMapEditorTilesPlugin::_set_tile_map_selection);
  1591. ClassDB::bind_method(D_METHOD("_get_tile_map_selection"), &TileMapEditorTilesPlugin::_get_tile_map_selection);
  1592. }
  1593. TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
  1594. CanvasItemEditor::get_singleton()->get_viewport_control()->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_mouse_exited_viewport));
  1595. // --- Shortcuts ---
  1596. ED_SHORTCUT("tiles_editor/cut", TTR("Cut"), KEY_MASK_CMD | KEY_X);
  1597. ED_SHORTCUT("tiles_editor/copy", TTR("Copy"), KEY_MASK_CMD | KEY_C);
  1598. ED_SHORTCUT("tiles_editor/paste", TTR("Paste"), KEY_MASK_CMD | KEY_V);
  1599. ED_SHORTCUT("tiles_editor/cancel", TTR("Cancel"), KEY_ESCAPE);
  1600. ED_SHORTCUT("tiles_editor/delete", TTR("Delete"), KEY_DELETE);
  1601. // --- Toolbar ---
  1602. toolbar = memnew(HBoxContainer);
  1603. toolbar->set_h_size_flags(SIZE_EXPAND_FILL);
  1604. HBoxContainer *tilemap_tiles_tools_buttons = memnew(HBoxContainer);
  1605. tool_buttons_group.instantiate();
  1606. select_tool_button = memnew(Button);
  1607. select_tool_button->set_flat(true);
  1608. select_tool_button->set_toggle_mode(true);
  1609. select_tool_button->set_button_group(tool_buttons_group);
  1610. select_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/selection_tool", "Selection", KEY_S));
  1611. select_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar));
  1612. tilemap_tiles_tools_buttons->add_child(select_tool_button);
  1613. paint_tool_button = memnew(Button);
  1614. paint_tool_button->set_flat(true);
  1615. paint_tool_button->set_toggle_mode(true);
  1616. paint_tool_button->set_button_group(tool_buttons_group);
  1617. paint_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/paint_tool", "Paint", KEY_D));
  1618. paint_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar));
  1619. tilemap_tiles_tools_buttons->add_child(paint_tool_button);
  1620. line_tool_button = memnew(Button);
  1621. line_tool_button->set_flat(true);
  1622. line_tool_button->set_toggle_mode(true);
  1623. line_tool_button->set_button_group(tool_buttons_group);
  1624. line_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/line_tool", "Line", KEY_L));
  1625. line_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar));
  1626. tilemap_tiles_tools_buttons->add_child(line_tool_button);
  1627. rect_tool_button = memnew(Button);
  1628. rect_tool_button->set_flat(true);
  1629. rect_tool_button->set_toggle_mode(true);
  1630. rect_tool_button->set_button_group(tool_buttons_group);
  1631. rect_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/rect_tool", "Rect", KEY_R));
  1632. rect_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar));
  1633. tilemap_tiles_tools_buttons->add_child(rect_tool_button);
  1634. bucket_tool_button = memnew(Button);
  1635. bucket_tool_button->set_flat(true);
  1636. bucket_tool_button->set_toggle_mode(true);
  1637. bucket_tool_button->set_button_group(tool_buttons_group);
  1638. bucket_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/bucket_tool", "Bucket", KEY_B));
  1639. bucket_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar));
  1640. tilemap_tiles_tools_buttons->add_child(bucket_tool_button);
  1641. toolbar->add_child(tilemap_tiles_tools_buttons);
  1642. // -- TileMap tool settings --
  1643. tools_settings = memnew(HBoxContainer);
  1644. toolbar->add_child(tools_settings);
  1645. tools_settings_vsep = memnew(VSeparator);
  1646. tools_settings->add_child(tools_settings_vsep);
  1647. // Picker
  1648. picker_button = memnew(Button);
  1649. picker_button->set_flat(true);
  1650. picker_button->set_toggle_mode(true);
  1651. picker_button->set_shortcut(ED_SHORTCUT("tiles_editor/picker", "Picker", KEY_P));
  1652. picker_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport));
  1653. tools_settings->add_child(picker_button);
  1654. // Erase button.
  1655. erase_button = memnew(Button);
  1656. erase_button->set_flat(true);
  1657. erase_button->set_toggle_mode(true);
  1658. erase_button->set_shortcut(ED_SHORTCUT("tiles_editor/eraser", "Eraser", KEY_E));
  1659. erase_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport));
  1660. tools_settings->add_child(erase_button);
  1661. // Separator 2.
  1662. tools_settings_vsep_2 = memnew(VSeparator);
  1663. tools_settings->add_child(tools_settings_vsep_2);
  1664. // Continuous checkbox.
  1665. bucket_continuous_checkbox = memnew(CheckBox);
  1666. bucket_continuous_checkbox->set_flat(true);
  1667. bucket_continuous_checkbox->set_text(TTR("Contiguous"));
  1668. tools_settings->add_child(bucket_continuous_checkbox);
  1669. // Random tile checkbox.
  1670. random_tile_checkbox = memnew(CheckBox);
  1671. random_tile_checkbox->set_flat(true);
  1672. random_tile_checkbox->set_text(TTR("Place Random Tile"));
  1673. random_tile_checkbox->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_random_tile_checkbox_toggled));
  1674. tools_settings->add_child(random_tile_checkbox);
  1675. // Random tile scattering.
  1676. scatter_label = memnew(Label);
  1677. scatter_label->set_tooltip(TTR("Defines the probability of painting nothing instead of a randomly selected tile."));
  1678. scatter_label->set_text(TTR("Scattering:"));
  1679. tools_settings->add_child(scatter_label);
  1680. scatter_spinbox = memnew(SpinBox);
  1681. scatter_spinbox->set_min(0.0);
  1682. scatter_spinbox->set_max(1000);
  1683. scatter_spinbox->set_step(0.001);
  1684. scatter_spinbox->set_tooltip(TTR("Defines the probability of painting nothing instead of a randomly selected tile."));
  1685. scatter_spinbox->get_line_edit()->add_theme_constant_override("minimum_character_width", 4);
  1686. scatter_spinbox->connect("value_changed", callable_mp(this, &TileMapEditorTilesPlugin::_on_scattering_spinbox_changed));
  1687. tools_settings->add_child(scatter_spinbox);
  1688. _on_random_tile_checkbox_toggled(false);
  1689. // Default tool.
  1690. paint_tool_button->set_pressed(true);
  1691. _update_toolbar();
  1692. // --- Bottom panel ---
  1693. set_name("Tiles");
  1694. missing_source_label = memnew(Label);
  1695. missing_source_label->set_text(TTR("This TileMap's TileSet has no source configured. Edit the TileSet resource to add one."));
  1696. missing_source_label->set_h_size_flags(SIZE_EXPAND_FILL);
  1697. missing_source_label->set_v_size_flags(SIZE_EXPAND_FILL);
  1698. missing_source_label->set_align(Label::ALIGN_CENTER);
  1699. missing_source_label->set_valign(Label::VALIGN_CENTER);
  1700. missing_source_label->hide();
  1701. add_child(missing_source_label);
  1702. atlas_sources_split_container = memnew(HSplitContainer);
  1703. atlas_sources_split_container->set_h_size_flags(SIZE_EXPAND_FILL);
  1704. atlas_sources_split_container->set_v_size_flags(SIZE_EXPAND_FILL);
  1705. add_child(atlas_sources_split_container);
  1706. sources_list = memnew(ItemList);
  1707. sources_list->set_fixed_icon_size(Size2i(60, 60) * EDSCALE);
  1708. sources_list->set_h_size_flags(SIZE_EXPAND_FILL);
  1709. sources_list->set_stretch_ratio(0.25);
  1710. sources_list->set_custom_minimum_size(Size2i(70, 0) * EDSCALE);
  1711. sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
  1712. sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_fix_selected_and_hovered).unbind(1));
  1713. sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_bottom_panel).unbind(1));
  1714. sources_list->connect("item_selected", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_sources_lists_current));
  1715. sources_list->connect("visibility_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::synchronize_sources_list), varray(sources_list));
  1716. atlas_sources_split_container->add_child(sources_list);
  1717. // Tile atlas source.
  1718. tile_atlas_view = memnew(TileAtlasView);
  1719. tile_atlas_view->set_h_size_flags(SIZE_EXPAND_FILL);
  1720. tile_atlas_view->set_v_size_flags(SIZE_EXPAND_FILL);
  1721. tile_atlas_view->set_texture_grid_visible(false);
  1722. tile_atlas_view->set_tile_shape_grid_visible(false);
  1723. tile_atlas_view->connect("transform_changed", callable_mp(TilesEditor::get_singleton(), &TilesEditor::set_atlas_view_transform));
  1724. atlas_sources_split_container->add_child(tile_atlas_view);
  1725. tile_atlas_control = memnew(Control);
  1726. tile_atlas_control->connect("draw", callable_mp(this, &TileMapEditorTilesPlugin::_tile_atlas_control_draw));
  1727. tile_atlas_control->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_tile_atlas_control_mouse_exited));
  1728. tile_atlas_control->connect("gui_input", callable_mp(this, &TileMapEditorTilesPlugin::_tile_atlas_control_gui_input));
  1729. tile_atlas_view->add_control_over_atlas_tiles(tile_atlas_control);
  1730. alternative_tiles_control = memnew(Control);
  1731. alternative_tiles_control->connect("draw", callable_mp(this, &TileMapEditorTilesPlugin::_tile_alternatives_control_draw));
  1732. alternative_tiles_control->connect("mouse_exited", callable_mp(this, &TileMapEditorTilesPlugin::_tile_alternatives_control_mouse_exited));
  1733. alternative_tiles_control->connect("gui_input", callable_mp(this, &TileMapEditorTilesPlugin::_tile_alternatives_control_gui_input));
  1734. tile_atlas_view->add_control_over_alternative_tiles(alternative_tiles_control);
  1735. // Scenes collection source.
  1736. scene_tiles_list = memnew(ItemList);
  1737. scene_tiles_list->set_h_size_flags(SIZE_EXPAND_FILL);
  1738. scene_tiles_list->set_v_size_flags(SIZE_EXPAND_FILL);
  1739. scene_tiles_list->set_drag_forwarding(this);
  1740. scene_tiles_list->set_select_mode(ItemList::SELECT_MULTI);
  1741. scene_tiles_list->connect("multi_selected", callable_mp(this, &TileMapEditorTilesPlugin::_scenes_list_multi_selected));
  1742. scene_tiles_list->connect("nothing_selected", callable_mp(this, &TileMapEditorTilesPlugin::_scenes_list_nothing_selected));
  1743. scene_tiles_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
  1744. atlas_sources_split_container->add_child(scene_tiles_list);
  1745. // Invalid source label.
  1746. invalid_source_label = memnew(Label);
  1747. invalid_source_label->set_text(TTR("Invalid source selected."));
  1748. invalid_source_label->set_h_size_flags(SIZE_EXPAND_FILL);
  1749. invalid_source_label->set_v_size_flags(SIZE_EXPAND_FILL);
  1750. invalid_source_label->set_align(Label::ALIGN_CENTER);
  1751. invalid_source_label->set_valign(Label::VALIGN_CENTER);
  1752. invalid_source_label->hide();
  1753. atlas_sources_split_container->add_child(invalid_source_label);
  1754. _update_bottom_panel();
  1755. }
  1756. TileMapEditorTilesPlugin::~TileMapEditorTilesPlugin() {
  1757. memdelete(selection_pattern);
  1758. memdelete(tile_map_clipboard);
  1759. }
  1760. void TileMapEditorTerrainsPlugin::_notification(int p_what) {
  1761. switch (p_what) {
  1762. case NOTIFICATION_ENTER_TREE:
  1763. case NOTIFICATION_THEME_CHANGED:
  1764. paint_tool_button->set_icon(get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
  1765. picker_button->set_icon(get_theme_icon(SNAME("ColorPick"), SNAME("EditorIcons")));
  1766. erase_button->set_icon(get_theme_icon(SNAME("Eraser"), SNAME("EditorIcons")));
  1767. break;
  1768. }
  1769. }
  1770. void TileMapEditorTerrainsPlugin::tile_set_changed() {
  1771. _update_terrains_cache();
  1772. _update_terrains_tree();
  1773. _update_tiles_list();
  1774. }
  1775. void TileMapEditorTerrainsPlugin::_update_toolbar() {
  1776. // Hide all settings.
  1777. for (int i = 0; i < tools_settings->get_child_count(); i++) {
  1778. Object::cast_to<CanvasItem>(tools_settings->get_child(i))->hide();
  1779. }
  1780. // Show only the correct settings.
  1781. if (tool_buttons_group->get_pressed_button() == paint_tool_button) {
  1782. tools_settings_vsep->show();
  1783. picker_button->show();
  1784. erase_button->show();
  1785. }
  1786. }
  1787. Control *TileMapEditorTerrainsPlugin::get_toolbar() const {
  1788. return toolbar;
  1789. }
  1790. Map<Vector2i, TileSet::CellNeighbor> TileMapEditorTerrainsPlugin::Constraint::get_overlapping_coords_and_peering_bits() const {
  1791. Map<Vector2i, TileSet::CellNeighbor> output;
  1792. Ref<TileSet> tile_set = tile_map->get_tileset();
  1793. ERR_FAIL_COND_V(!tile_set.is_valid(), output);
  1794. TileSet::TileShape shape = tile_set->get_tile_shape();
  1795. if (shape == TileSet::TILE_SHAPE_SQUARE) {
  1796. switch (bit) {
  1797. case 0:
  1798. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_RIGHT_SIDE;
  1799. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_LEFT_SIDE;
  1800. break;
  1801. case 1:
  1802. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER;
  1803. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER;
  1804. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER;
  1805. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER;
  1806. break;
  1807. case 2:
  1808. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_SIDE;
  1809. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_SIDE;
  1810. break;
  1811. case 3:
  1812. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER;
  1813. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER;
  1814. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER)] = TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER;
  1815. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_LEFT_SIDE)] = TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER;
  1816. break;
  1817. default:
  1818. ERR_FAIL_V(output);
  1819. }
  1820. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  1821. switch (bit) {
  1822. case 0:
  1823. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_RIGHT_CORNER;
  1824. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_BOTTOM_CORNER;
  1825. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_RIGHT_CORNER)] = TileSet::CELL_NEIGHBOR_LEFT_CORNER;
  1826. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_CORNER;
  1827. break;
  1828. case 1:
  1829. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE;
  1830. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE;
  1831. break;
  1832. case 2:
  1833. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_CORNER;
  1834. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_LEFT_CORNER;
  1835. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_CORNER)] = TileSet::CELL_NEIGHBOR_TOP_CORNER;
  1836. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)] = TileSet::CELL_NEIGHBOR_RIGHT_CORNER;
  1837. break;
  1838. case 3:
  1839. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE;
  1840. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
  1841. break;
  1842. default:
  1843. ERR_FAIL_V(output);
  1844. }
  1845. } else {
  1846. // Half offset shapes.
  1847. TileSet::TileOffsetAxis offset_axis = tile_set->get_tile_offset_axis();
  1848. if (offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1849. switch (bit) {
  1850. case 0:
  1851. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_RIGHT_SIDE;
  1852. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_LEFT_SIDE;
  1853. break;
  1854. case 1:
  1855. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER;
  1856. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER;
  1857. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_CORNER;
  1858. break;
  1859. case 2:
  1860. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE;
  1861. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE;
  1862. break;
  1863. case 3:
  1864. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_CORNER;
  1865. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER;
  1866. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER;
  1867. break;
  1868. case 4:
  1869. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE;
  1870. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
  1871. break;
  1872. default:
  1873. ERR_FAIL_V(output);
  1874. }
  1875. } else {
  1876. switch (bit) {
  1877. case 0:
  1878. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_RIGHT_CORNER;
  1879. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER;
  1880. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER;
  1881. break;
  1882. case 1:
  1883. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE;
  1884. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE;
  1885. break;
  1886. case 2:
  1887. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER;
  1888. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE)] = TileSet::CELL_NEIGHBOR_LEFT_CORNER;
  1889. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER;
  1890. break;
  1891. case 3:
  1892. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_SIDE;
  1893. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_SIDE;
  1894. break;
  1895. case 4:
  1896. output[base_cell_coords] = TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE;
  1897. output[tile_map->get_neighbor_cell(base_cell_coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE)] = TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
  1898. break;
  1899. default:
  1900. ERR_FAIL_V(output);
  1901. }
  1902. }
  1903. }
  1904. return output;
  1905. }
  1906. TileMapEditorTerrainsPlugin::Constraint::Constraint(const TileMap *p_tile_map, const Vector2i &p_position, const TileSet::CellNeighbor &p_bit, int p_terrain) {
  1907. // The way we build the constraint make it easy to detect conflicting constraints.
  1908. tile_map = p_tile_map;
  1909. Ref<TileSet> tile_set = tile_map->get_tileset();
  1910. ERR_FAIL_COND(!tile_set.is_valid());
  1911. TileSet::TileShape shape = tile_set->get_tile_shape();
  1912. if (shape == TileSet::TILE_SHAPE_SQUARE || shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  1913. switch (p_bit) {
  1914. case TileSet::CELL_NEIGHBOR_RIGHT_SIDE:
  1915. case TileSet::CELL_NEIGHBOR_RIGHT_CORNER:
  1916. bit = 0;
  1917. base_cell_coords = p_position;
  1918. break;
  1919. case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  1920. case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE:
  1921. bit = 1;
  1922. base_cell_coords = p_position;
  1923. break;
  1924. case TileSet::CELL_NEIGHBOR_BOTTOM_SIDE:
  1925. case TileSet::CELL_NEIGHBOR_BOTTOM_CORNER:
  1926. bit = 2;
  1927. base_cell_coords = p_position;
  1928. break;
  1929. case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  1930. case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE:
  1931. bit = 3;
  1932. base_cell_coords = p_position;
  1933. break;
  1934. case TileSet::CELL_NEIGHBOR_LEFT_SIDE:
  1935. case TileSet::CELL_NEIGHBOR_LEFT_CORNER:
  1936. bit = 0;
  1937. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, p_bit);
  1938. break;
  1939. case TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER:
  1940. case TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE:
  1941. bit = 1;
  1942. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, p_bit);
  1943. break;
  1944. case TileSet::CELL_NEIGHBOR_TOP_SIDE:
  1945. case TileSet::CELL_NEIGHBOR_TOP_CORNER:
  1946. bit = 2;
  1947. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, p_bit);
  1948. break;
  1949. case TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  1950. case TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE:
  1951. bit = 3;
  1952. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, p_bit);
  1953. break;
  1954. default:
  1955. ERR_FAIL();
  1956. break;
  1957. }
  1958. } else {
  1959. // Half-offset shapes
  1960. TileSet::TileOffsetAxis offset_axis = tile_set->get_tile_offset_axis();
  1961. if (offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1962. switch (p_bit) {
  1963. case TileSet::CELL_NEIGHBOR_RIGHT_SIDE:
  1964. bit = 0;
  1965. base_cell_coords = p_position;
  1966. break;
  1967. case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  1968. bit = 1;
  1969. base_cell_coords = p_position;
  1970. break;
  1971. case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE:
  1972. bit = 2;
  1973. base_cell_coords = p_position;
  1974. break;
  1975. case TileSet::CELL_NEIGHBOR_BOTTOM_CORNER:
  1976. bit = 3;
  1977. base_cell_coords = p_position;
  1978. break;
  1979. case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE:
  1980. bit = 4;
  1981. base_cell_coords = p_position;
  1982. break;
  1983. case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  1984. bit = 1;
  1985. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_LEFT_SIDE);
  1986. break;
  1987. case TileSet::CELL_NEIGHBOR_LEFT_SIDE:
  1988. bit = 0;
  1989. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_LEFT_SIDE);
  1990. break;
  1991. case TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER:
  1992. bit = 3;
  1993. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  1994. break;
  1995. case TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE:
  1996. bit = 2;
  1997. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  1998. break;
  1999. case TileSet::CELL_NEIGHBOR_TOP_CORNER:
  2000. bit = 1;
  2001. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  2002. break;
  2003. case TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE:
  2004. bit = 4;
  2005. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
  2006. break;
  2007. case TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  2008. bit = 3;
  2009. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
  2010. break;
  2011. default:
  2012. ERR_FAIL();
  2013. break;
  2014. }
  2015. } else {
  2016. switch (p_bit) {
  2017. case TileSet::CELL_NEIGHBOR_RIGHT_CORNER:
  2018. bit = 0;
  2019. base_cell_coords = p_position;
  2020. break;
  2021. case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE:
  2022. bit = 1;
  2023. base_cell_coords = p_position;
  2024. break;
  2025. case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  2026. bit = 2;
  2027. base_cell_coords = p_position;
  2028. break;
  2029. case TileSet::CELL_NEIGHBOR_BOTTOM_SIDE:
  2030. bit = 3;
  2031. base_cell_coords = p_position;
  2032. break;
  2033. case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  2034. bit = 0;
  2035. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
  2036. break;
  2037. case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE:
  2038. bit = 4;
  2039. base_cell_coords = p_position;
  2040. break;
  2041. case TileSet::CELL_NEIGHBOR_LEFT_CORNER:
  2042. bit = 2;
  2043. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  2044. break;
  2045. case TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE:
  2046. bit = 1;
  2047. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  2048. break;
  2049. case TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER:
  2050. bit = 0;
  2051. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  2052. break;
  2053. case TileSet::CELL_NEIGHBOR_TOP_SIDE:
  2054. bit = 3;
  2055. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_SIDE);
  2056. break;
  2057. case TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  2058. bit = 2;
  2059. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_SIDE);
  2060. break;
  2061. case TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE:
  2062. bit = 4;
  2063. base_cell_coords = p_tile_map->get_neighbor_cell(p_position, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
  2064. break;
  2065. default:
  2066. ERR_FAIL();
  2067. break;
  2068. }
  2069. }
  2070. }
  2071. terrain = p_terrain;
  2072. }
  2073. Set<TileMapEditorTerrainsPlugin::TerrainsTilePattern> TileMapEditorTerrainsPlugin::_get_valid_terrains_tile_patterns_for_constraints(int p_terrain_set, const Vector2i &p_position, Set<Constraint> p_constraints) const {
  2074. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2075. if (!tile_map) {
  2076. return Set<TerrainsTilePattern>();
  2077. }
  2078. Ref<TileSet> tile_set = tile_map->get_tileset();
  2079. if (!tile_set.is_valid()) {
  2080. return Set<TerrainsTilePattern>();
  2081. }
  2082. // Returns all tiles compatible with the given constraints.
  2083. Set<TerrainsTilePattern> compatible_terrain_tile_patterns;
  2084. for (const KeyValue<TerrainsTilePattern, Set<TileMapCell>> &E : per_terrain_terrains_tile_patterns_tiles[p_terrain_set]) {
  2085. int valid = true;
  2086. int in_pattern_count = 0;
  2087. for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
  2088. TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
  2089. if (tile_set->is_valid_peering_bit_terrain(p_terrain_set, bit)) {
  2090. // Check if the bit is compatible with the constraints.
  2091. Constraint terrain_bit_constraint = Constraint(tile_map, p_position, bit, E.key[in_pattern_count]);
  2092. Set<Constraint>::Element *in_set_constraint_element = p_constraints.find(terrain_bit_constraint);
  2093. if (in_set_constraint_element && in_set_constraint_element->get().get_terrain() != terrain_bit_constraint.get_terrain()) {
  2094. valid = false;
  2095. break;
  2096. }
  2097. in_pattern_count++;
  2098. }
  2099. }
  2100. if (valid) {
  2101. compatible_terrain_tile_patterns.insert(E.key);
  2102. }
  2103. }
  2104. return compatible_terrain_tile_patterns;
  2105. }
  2106. Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_constraints_from_removed_cells_list(const Set<Vector2i> &p_to_replace, int p_terrain_set) const {
  2107. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2108. if (!tile_map) {
  2109. return Set<Constraint>();
  2110. }
  2111. Ref<TileSet> tile_set = tile_map->get_tileset();
  2112. if (!tile_set.is_valid()) {
  2113. return Set<Constraint>();
  2114. }
  2115. ERR_FAIL_INDEX_V(p_terrain_set, tile_set->get_terrain_sets_count(), Set<Constraint>());
  2116. ERR_FAIL_INDEX_V(tile_map_layer, tile_map->get_layers_count(), Set<Constraint>());
  2117. // Build a set of dummy constraints get the constrained points.
  2118. Set<Constraint> dummy_constraints;
  2119. for (Set<Vector2i>::Element *E = p_to_replace.front(); E; E = E->next()) {
  2120. for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) { // Iterates over sides.
  2121. TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
  2122. if (tile_set->is_valid_peering_bit_terrain(p_terrain_set, bit)) {
  2123. dummy_constraints.insert(Constraint(tile_map, E->get(), bit, -1));
  2124. }
  2125. }
  2126. }
  2127. // For each constrained point, we get all overlapping tiles, and select the most adequate terrain for it.
  2128. Set<Constraint> constraints;
  2129. for (Set<Constraint>::Element *E = dummy_constraints.front(); E; E = E->next()) {
  2130. Constraint c = E->get();
  2131. Map<int, int> terrain_count;
  2132. // Count the number of occurrences per terrain.
  2133. Map<Vector2i, TileSet::CellNeighbor> overlapping_terrain_bits = c.get_overlapping_coords_and_peering_bits();
  2134. for (const KeyValue<Vector2i, TileSet::CellNeighbor> &E_overlapping : overlapping_terrain_bits) {
  2135. if (!p_to_replace.has(E_overlapping.key)) {
  2136. TileMapCell neighbor_cell = tile_map->get_cell(tile_map_layer, E_overlapping.key);
  2137. TileData *neighbor_tile_data = nullptr;
  2138. if (terrain_tiles.has(neighbor_cell) && terrain_tiles[neighbor_cell]->get_terrain_set() == p_terrain_set) {
  2139. neighbor_tile_data = terrain_tiles[neighbor_cell];
  2140. }
  2141. int terrain = neighbor_tile_data ? neighbor_tile_data->get_peering_bit_terrain(TileSet::CellNeighbor(E_overlapping.value)) : -1;
  2142. if (terrain_count.has(terrain)) {
  2143. terrain_count[terrain] = 0;
  2144. }
  2145. terrain_count[terrain] += 1;
  2146. }
  2147. }
  2148. // Get the terrain with the max number of occurrences.
  2149. int max = 0;
  2150. int max_terrain = -1;
  2151. for (const KeyValue<int, int> &E_terrain_count : terrain_count) {
  2152. if (E_terrain_count.value > max) {
  2153. max = E_terrain_count.value;
  2154. max_terrain = E_terrain_count.key;
  2155. }
  2156. }
  2157. // Set the adequate terrain.
  2158. if (max > 0) {
  2159. c.set_terrain(max_terrain);
  2160. constraints.insert(c);
  2161. }
  2162. }
  2163. return constraints;
  2164. }
  2165. Set<TileMapEditorTerrainsPlugin::Constraint> TileMapEditorTerrainsPlugin::_get_constraints_from_added_tile(Vector2i p_position, int p_terrain_set, TerrainsTilePattern p_terrains_tile_pattern) const {
  2166. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2167. if (!tile_map) {
  2168. return Set<TileMapEditorTerrainsPlugin::Constraint>();
  2169. }
  2170. Ref<TileSet> tile_set = tile_map->get_tileset();
  2171. if (!tile_set.is_valid()) {
  2172. return Set<TileMapEditorTerrainsPlugin::Constraint>();
  2173. }
  2174. // Compute the constraints needed from the surrounding tiles.
  2175. Set<TileMapEditorTerrainsPlugin::Constraint> output;
  2176. int in_pattern_count = 0;
  2177. for (uint32_t i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
  2178. TileSet::CellNeighbor side = TileSet::CellNeighbor(i);
  2179. if (tile_set->is_valid_peering_bit_terrain(p_terrain_set, side)) {
  2180. Constraint c = Constraint(tile_map, p_position, side, p_terrains_tile_pattern[in_pattern_count]);
  2181. output.insert(c);
  2182. in_pattern_count++;
  2183. }
  2184. }
  2185. return output;
  2186. }
  2187. Map<Vector2i, TileMapEditorTerrainsPlugin::TerrainsTilePattern> TileMapEditorTerrainsPlugin::_wave_function_collapse(const Set<Vector2i> &p_to_replace, int p_terrain_set, const Set<TileMapEditorTerrainsPlugin::Constraint> p_constraints) const {
  2188. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2189. if (!tile_map) {
  2190. return Map<Vector2i, TerrainsTilePattern>();
  2191. }
  2192. Ref<TileSet> tile_set = tile_map->get_tileset();
  2193. if (!tile_set.is_valid()) {
  2194. return Map<Vector2i, TileMapEditorTerrainsPlugin::TerrainsTilePattern>();
  2195. }
  2196. // Copy the constraints set.
  2197. Set<TileMapEditorTerrainsPlugin::Constraint> constraints = p_constraints;
  2198. // Compute all acceptable tiles for each cell.
  2199. Map<Vector2i, Set<TerrainsTilePattern>> per_cell_acceptable_tiles;
  2200. for (Set<Vector2i>::Element *E = p_to_replace.front(); E; E = E->next()) {
  2201. per_cell_acceptable_tiles[E->get()] = _get_valid_terrains_tile_patterns_for_constraints(p_terrain_set, E->get(), constraints);
  2202. }
  2203. // Output map.
  2204. Map<Vector2i, TerrainsTilePattern> output;
  2205. // Add all positions to a set.
  2206. Set<Vector2i> to_replace = Set<Vector2i>(p_to_replace);
  2207. while (!to_replace.is_empty()) {
  2208. // Compute the minimum number of tile possibilities for each cell.
  2209. int min_nb_possibilities = 100000000;
  2210. for (const KeyValue<Vector2i, Set<TerrainsTilePattern>> &E : per_cell_acceptable_tiles) {
  2211. min_nb_possibilities = MIN(min_nb_possibilities, E.value.size());
  2212. }
  2213. // Get the set of possible cells to fill.
  2214. LocalVector<Vector2i> to_choose_from;
  2215. for (const KeyValue<Vector2i, Set<TerrainsTilePattern>> &E : per_cell_acceptable_tiles) {
  2216. if (E.value.size() == min_nb_possibilities) {
  2217. to_choose_from.push_back(E.key);
  2218. }
  2219. }
  2220. // Randomly pick a tile out of the most constrained.
  2221. Vector2i selected_cell_to_replace = to_choose_from[Math::random(0, to_choose_from.size() - 1)];
  2222. // Randomly select a tile out of them the put it in the grid.
  2223. Set<TerrainsTilePattern> valid_tiles = per_cell_acceptable_tiles[selected_cell_to_replace];
  2224. if (valid_tiles.is_empty()) {
  2225. // No possibilities :/
  2226. break;
  2227. }
  2228. int random_terrain_tile_pattern_index = Math::random(0, valid_tiles.size() - 1);
  2229. Set<TerrainsTilePattern>::Element *E = valid_tiles.front();
  2230. for (int i = 0; i < random_terrain_tile_pattern_index; i++) {
  2231. E = E->next();
  2232. }
  2233. TerrainsTilePattern selected_terrain_tile_pattern = E->get();
  2234. // Set the selected cell into the output.
  2235. output[selected_cell_to_replace] = selected_terrain_tile_pattern;
  2236. to_replace.erase(selected_cell_to_replace);
  2237. per_cell_acceptable_tiles.erase(selected_cell_to_replace);
  2238. // Add the new constraints from the added tiles.
  2239. Set<TileMapEditorTerrainsPlugin::Constraint> new_constraints = _get_constraints_from_added_tile(selected_cell_to_replace, p_terrain_set, selected_terrain_tile_pattern);
  2240. for (Set<TileMapEditorTerrainsPlugin::Constraint>::Element *E_constraint = new_constraints.front(); E_constraint; E_constraint = E_constraint->next()) {
  2241. constraints.insert(E_constraint->get());
  2242. }
  2243. // Compute valid tiles again for neighbors.
  2244. for (uint32_t i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
  2245. TileSet::CellNeighbor side = TileSet::CellNeighbor(i);
  2246. if (tile_map->is_existing_neighbor(side)) {
  2247. Vector2i neighbor = tile_map->get_neighbor_cell(selected_cell_to_replace, side);
  2248. if (to_replace.has(neighbor)) {
  2249. per_cell_acceptable_tiles[neighbor] = _get_valid_terrains_tile_patterns_for_constraints(p_terrain_set, neighbor, constraints);
  2250. }
  2251. }
  2252. }
  2253. }
  2254. return output;
  2255. }
  2256. TileMapCell TileMapEditorTerrainsPlugin::_get_random_tile_from_pattern(int p_terrain_set, TerrainsTilePattern p_terrain_tile_pattern) const {
  2257. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2258. if (!tile_map) {
  2259. return TileMapCell();
  2260. }
  2261. Ref<TileSet> tile_set = tile_map->get_tileset();
  2262. if (!tile_set.is_valid()) {
  2263. return TileMapCell();
  2264. }
  2265. // Count the sum of probabilities.
  2266. double sum = 0.0;
  2267. Set<TileMapCell> set = per_terrain_terrains_tile_patterns_tiles[p_terrain_set][p_terrain_tile_pattern];
  2268. for (Set<TileMapCell>::Element *E = set.front(); E; E = E->next()) {
  2269. if (E->get().source_id >= 0) {
  2270. Ref<TileSetSource> source = tile_set->get_source(E->get().source_id);
  2271. Ref<TileSetAtlasSource> atlas_source = source;
  2272. if (atlas_source.is_valid()) {
  2273. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E->get().get_atlas_coords(), E->get().alternative_tile));
  2274. sum += tile_data->get_probability();
  2275. } else {
  2276. sum += 1.0;
  2277. }
  2278. } else {
  2279. sum += 1.0;
  2280. }
  2281. }
  2282. // Generate a random number.
  2283. double count = 0.0;
  2284. double picked = Math::random(0.0, sum);
  2285. // Pick the tile.
  2286. for (Set<TileMapCell>::Element *E = set.front(); E; E = E->next()) {
  2287. if (E->get().source_id >= 0) {
  2288. Ref<TileSetSource> source = tile_set->get_source(E->get().source_id);
  2289. Ref<TileSetAtlasSource> atlas_source = source;
  2290. if (atlas_source.is_valid()) {
  2291. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E->get().get_atlas_coords(), E->get().alternative_tile));
  2292. count += tile_data->get_probability();
  2293. } else {
  2294. count += 1.0;
  2295. }
  2296. } else {
  2297. count += 1.0;
  2298. }
  2299. if (count >= picked) {
  2300. return E->get();
  2301. }
  2302. }
  2303. ERR_FAIL_V(TileMapCell());
  2304. }
  2305. Map<Vector2i, TileMapCell> TileMapEditorTerrainsPlugin::_draw_terrains(const Map<Vector2i, TerrainsTilePattern> &p_to_paint, int p_terrain_set) const {
  2306. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2307. if (!tile_map) {
  2308. return Map<Vector2i, TileMapCell>();
  2309. }
  2310. Ref<TileSet> tile_set = tile_map->get_tileset();
  2311. if (!tile_set.is_valid()) {
  2312. return Map<Vector2i, TileMapCell>();
  2313. }
  2314. Map<Vector2i, TileMapCell> output;
  2315. // Add the constraints from the added tiles.
  2316. Set<TileMapEditorTerrainsPlugin::Constraint> added_tiles_constraints_set;
  2317. for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) {
  2318. Vector2i coords = E_to_paint.key;
  2319. TerrainsTilePattern terrains_tile_pattern = E_to_paint.value;
  2320. Set<TileMapEditorTerrainsPlugin::Constraint> cell_constraints = _get_constraints_from_added_tile(coords, p_terrain_set, terrains_tile_pattern);
  2321. for (Set<TileMapEditorTerrainsPlugin::Constraint>::Element *E = cell_constraints.front(); E; E = E->next()) {
  2322. added_tiles_constraints_set.insert(E->get());
  2323. }
  2324. }
  2325. // Build the list of potential tiles to replace.
  2326. Set<Vector2i> potential_to_replace;
  2327. for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) {
  2328. Vector2i coords = E_to_paint.key;
  2329. for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
  2330. if (tile_map->is_existing_neighbor(TileSet::CellNeighbor(i))) {
  2331. Vector2i neighbor = tile_map->get_neighbor_cell(coords, TileSet::CellNeighbor(i));
  2332. if (!p_to_paint.has(neighbor)) {
  2333. potential_to_replace.insert(neighbor);
  2334. }
  2335. }
  2336. }
  2337. }
  2338. // Set of tiles to replace
  2339. Set<Vector2i> to_replace;
  2340. // Add the central tiles to the one to replace. TODO: maybe change that.
  2341. for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) {
  2342. to_replace.insert(E_to_paint.key);
  2343. }
  2344. // Add the constraints from the surroundings of the modified areas.
  2345. Set<TileMapEditorTerrainsPlugin::Constraint> removed_cells_constraints_set;
  2346. bool to_replace_modified = true;
  2347. while (to_replace_modified) {
  2348. // Get the constraints from the removed cells.
  2349. removed_cells_constraints_set = _get_constraints_from_removed_cells_list(to_replace, p_terrain_set);
  2350. // Filter the sources to make sure they are in the potential_to_replace.
  2351. Map<Constraint, Set<Vector2i>> source_tiles_of_constraint;
  2352. for (Set<Constraint>::Element *E = removed_cells_constraints_set.front(); E; E = E->next()) {
  2353. Map<Vector2i, TileSet::CellNeighbor> sources_of_constraint = E->get().get_overlapping_coords_and_peering_bits();
  2354. for (const KeyValue<Vector2i, TileSet::CellNeighbor> &E_source_tile_of_constraint : sources_of_constraint) {
  2355. if (potential_to_replace.has(E_source_tile_of_constraint.key)) {
  2356. source_tiles_of_constraint[E->get()].insert(E_source_tile_of_constraint.key);
  2357. }
  2358. }
  2359. }
  2360. to_replace_modified = false;
  2361. for (Set<TileMapEditorTerrainsPlugin::Constraint>::Element *E = added_tiles_constraints_set.front(); E; E = E->next()) {
  2362. Constraint c = E->get();
  2363. // Check if we have a conflict in constraints.
  2364. if (removed_cells_constraints_set.has(c) && removed_cells_constraints_set.find(c)->get().get_terrain() != c.get_terrain()) {
  2365. // If we do, we search for a neighbor to remove.
  2366. if (source_tiles_of_constraint.has(c) && !source_tiles_of_constraint[c].is_empty()) {
  2367. // Remove it.
  2368. Vector2i to_add_to_remove = source_tiles_of_constraint[c].front()->get();
  2369. potential_to_replace.erase(to_add_to_remove);
  2370. to_replace.insert(to_add_to_remove);
  2371. to_replace_modified = true;
  2372. for (KeyValue<Constraint, Set<Vector2i>> &E_source_tiles_of_constraint : source_tiles_of_constraint) {
  2373. E_source_tiles_of_constraint.value.erase(to_add_to_remove);
  2374. }
  2375. break;
  2376. }
  2377. }
  2378. }
  2379. }
  2380. // Combine all constraints together.
  2381. Set<TileMapEditorTerrainsPlugin::Constraint> constraints = removed_cells_constraints_set;
  2382. for (Set<TileMapEditorTerrainsPlugin::Constraint>::Element *E = added_tiles_constraints_set.front(); E; E = E->next()) {
  2383. constraints.insert(E->get());
  2384. }
  2385. // Run WFC to fill the holes with the constraints.
  2386. Map<Vector2i, TerrainsTilePattern> wfc_output = _wave_function_collapse(to_replace, p_terrain_set, constraints);
  2387. // Use the WFC run for the output.
  2388. for (const KeyValue<Vector2i, TerrainsTilePattern> &E : wfc_output) {
  2389. output[E.key] = _get_random_tile_from_pattern(p_terrain_set, E.value);
  2390. }
  2391. // Override the WFC results to make sure at least the painted tiles are actually painted.
  2392. for (const KeyValue<Vector2i, TerrainsTilePattern> &E_to_paint : p_to_paint) {
  2393. output[E_to_paint.key] = _get_random_tile_from_pattern(p_terrain_set, E_to_paint.value);
  2394. }
  2395. return output;
  2396. }
  2397. void TileMapEditorTerrainsPlugin::_stop_dragging() {
  2398. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2399. if (!tile_map) {
  2400. return;
  2401. }
  2402. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  2403. Vector2 mpos = xform.affine_inverse().xform(CanvasItemEditor::get_singleton()->get_viewport_control()->get_local_mouse_position());
  2404. switch (drag_type) {
  2405. case DRAG_TYPE_PICK: {
  2406. Vector2i coords = tile_map->world_to_map(mpos);
  2407. TileMapCell tile = tile_map->get_cell(tile_map_layer, coords);
  2408. if (terrain_tiles.has(tile)) {
  2409. Array terrains_tile_pattern = _build_terrains_tile_pattern(terrain_tiles[tile]);
  2410. // Find the tree item for the right terrain set.
  2411. bool need_tree_item_switch = true;
  2412. TreeItem *tree_item = terrains_tree->get_selected();
  2413. if (tree_item) {
  2414. Dictionary metadata_dict = tree_item->get_metadata(0);
  2415. if (metadata_dict.has("terrain_set") && metadata_dict.has("terrain_id")) {
  2416. int terrain_set = metadata_dict["terrain_set"];
  2417. int terrain_id = metadata_dict["terrain_id"];
  2418. if (per_terrain_terrains_tile_patterns[terrain_set][terrain_id].has(terrains_tile_pattern)) {
  2419. need_tree_item_switch = false;
  2420. }
  2421. }
  2422. }
  2423. if (need_tree_item_switch) {
  2424. for (tree_item = terrains_tree->get_root()->get_first_child(); tree_item; tree_item = tree_item->get_next_visible()) {
  2425. Dictionary metadata_dict = tree_item->get_metadata(0);
  2426. if (metadata_dict.has("terrain_set") && metadata_dict.has("terrain_id")) {
  2427. int terrain_set = metadata_dict["terrain_set"];
  2428. int terrain_id = metadata_dict["terrain_id"];
  2429. if (per_terrain_terrains_tile_patterns[terrain_set][terrain_id].has(terrains_tile_pattern)) {
  2430. // Found
  2431. tree_item->select(0);
  2432. _update_tiles_list();
  2433. break;
  2434. }
  2435. }
  2436. }
  2437. }
  2438. // Find the list item for the given tile.
  2439. if (tree_item) {
  2440. for (int i = 0; i < terrains_tile_list->get_item_count(); i++) {
  2441. Dictionary metadata_dict = terrains_tile_list->get_item_metadata(i);
  2442. TerrainsTilePattern in_meta_terrains_tile_pattern = metadata_dict["terrains_tile_pattern"];
  2443. bool equals = true;
  2444. for (int j = 0; j < terrains_tile_pattern.size(); j++) {
  2445. if (terrains_tile_pattern[j] != in_meta_terrains_tile_pattern[j]) {
  2446. equals = false;
  2447. break;
  2448. }
  2449. }
  2450. if (equals) {
  2451. terrains_tile_list->select(i);
  2452. break;
  2453. }
  2454. }
  2455. } else {
  2456. ERR_PRINT("Terrain tile not found.");
  2457. }
  2458. }
  2459. picker_button->set_pressed(false);
  2460. } break;
  2461. case DRAG_TYPE_PAINT: {
  2462. undo_redo->create_action(TTR("Paint terrain"));
  2463. for (const KeyValue<Vector2i, TileMapCell> &E : drag_modified) {
  2464. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, tile_map->get_cell_source_id(tile_map_layer, E.key), tile_map->get_cell_atlas_coords(tile_map_layer, E.key), tile_map->get_cell_alternative_tile(tile_map_layer, E.key));
  2465. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  2466. }
  2467. undo_redo->commit_action(false);
  2468. } break;
  2469. default:
  2470. break;
  2471. }
  2472. drag_type = DRAG_TYPE_NONE;
  2473. }
  2474. bool TileMapEditorTerrainsPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
  2475. if (!is_visible_in_tree()) {
  2476. // If the bottom editor is not visible, we ignore inputs.
  2477. return false;
  2478. }
  2479. if (CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT) {
  2480. return false;
  2481. }
  2482. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2483. if (!tile_map) {
  2484. return false;
  2485. }
  2486. Ref<TileSet> tile_set = tile_map->get_tileset();
  2487. if (!tile_set.is_valid()) {
  2488. return false;
  2489. }
  2490. if (tile_map_layer < 0) {
  2491. return false;
  2492. }
  2493. ERR_FAIL_COND_V(tile_map_layer >= tile_map->get_layers_count(), false);
  2494. // Get the selected terrain.
  2495. TerrainsTilePattern selected_terrains_tile_pattern;
  2496. int selected_terrain_set = -1;
  2497. TreeItem *selected_tree_item = terrains_tree->get_selected();
  2498. if (selected_tree_item && selected_tree_item->get_metadata(0)) {
  2499. Dictionary metadata_dict = selected_tree_item->get_metadata(0);
  2500. // Selected terrain
  2501. selected_terrain_set = metadata_dict["terrain_set"];
  2502. // Selected tile
  2503. if (erase_button->is_pressed()) {
  2504. selected_terrains_tile_pattern.clear();
  2505. for (uint32_t i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
  2506. TileSet::CellNeighbor side = TileSet::CellNeighbor(i);
  2507. if (tile_set->is_valid_peering_bit_terrain(selected_terrain_set, side)) {
  2508. selected_terrains_tile_pattern.push_back(-1);
  2509. }
  2510. }
  2511. } else if (terrains_tile_list->is_anything_selected()) {
  2512. metadata_dict = terrains_tile_list->get_item_metadata(terrains_tile_list->get_selected_items()[0]);
  2513. selected_terrains_tile_pattern = metadata_dict["terrains_tile_pattern"];
  2514. }
  2515. }
  2516. Ref<InputEventMouseMotion> mm = p_event;
  2517. if (mm.is_valid()) {
  2518. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  2519. Vector2 mpos = xform.affine_inverse().xform(mm->get_position());
  2520. switch (drag_type) {
  2521. case DRAG_TYPE_PAINT: {
  2522. if (selected_terrain_set >= 0) {
  2523. Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(drag_last_mouse_pos), tile_map->world_to_map(mpos));
  2524. Map<Vector2i, TerrainsTilePattern> to_draw;
  2525. for (int i = 0; i < line.size(); i++) {
  2526. to_draw[line[i]] = selected_terrains_tile_pattern;
  2527. }
  2528. Map<Vector2i, TileMapCell> modified = _draw_terrains(to_draw, selected_terrain_set);
  2529. for (const KeyValue<Vector2i, TileMapCell> &E : modified) {
  2530. if (!drag_modified.has(E.key)) {
  2531. drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key);
  2532. }
  2533. tile_map->set_cell(tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  2534. }
  2535. }
  2536. } break;
  2537. default:
  2538. break;
  2539. }
  2540. drag_last_mouse_pos = mpos;
  2541. CanvasItemEditor::get_singleton()->update_viewport();
  2542. return true;
  2543. }
  2544. Ref<InputEventMouseButton> mb = p_event;
  2545. if (mb.is_valid()) {
  2546. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  2547. Vector2 mpos = xform.affine_inverse().xform(mb->get_position());
  2548. if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
  2549. if (mb->is_pressed()) {
  2550. // Pressed
  2551. if (picker_button->is_pressed()) {
  2552. drag_type = DRAG_TYPE_PICK;
  2553. } else {
  2554. // Paint otherwise.
  2555. if (selected_terrain_set >= 0 && !selected_terrains_tile_pattern.is_empty() && tool_buttons_group->get_pressed_button() == paint_tool_button) {
  2556. drag_type = DRAG_TYPE_PAINT;
  2557. drag_start_mouse_pos = mpos;
  2558. drag_modified.clear();
  2559. Map<Vector2i, TerrainsTilePattern> terrains_to_draw;
  2560. terrains_to_draw[tile_map->world_to_map(mpos)] = selected_terrains_tile_pattern;
  2561. Map<Vector2i, TileMapCell> to_draw = _draw_terrains(terrains_to_draw, selected_terrain_set);
  2562. for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
  2563. drag_modified[E.key] = tile_map->get_cell(tile_map_layer, E.key);
  2564. tile_map->set_cell(tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
  2565. }
  2566. }
  2567. }
  2568. } else {
  2569. // Released
  2570. _stop_dragging();
  2571. }
  2572. CanvasItemEditor::get_singleton()->update_viewport();
  2573. return true;
  2574. }
  2575. drag_last_mouse_pos = mpos;
  2576. }
  2577. return false;
  2578. }
  2579. TileMapEditorTerrainsPlugin::TerrainsTilePattern TileMapEditorTerrainsPlugin::_build_terrains_tile_pattern(TileData *p_tile_data) {
  2580. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2581. if (!tile_map) {
  2582. return TerrainsTilePattern();
  2583. }
  2584. Ref<TileSet> tile_set = tile_map->get_tileset();
  2585. if (!tile_set.is_valid()) {
  2586. return TerrainsTilePattern();
  2587. }
  2588. TerrainsTilePattern output;
  2589. for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
  2590. if (tile_set->is_valid_peering_bit_terrain(p_tile_data->get_terrain_set(), TileSet::CellNeighbor(i))) {
  2591. output.push_back(p_tile_data->get_peering_bit_terrain(TileSet::CellNeighbor(i)));
  2592. }
  2593. }
  2594. return output;
  2595. }
  2596. void TileMapEditorTerrainsPlugin::_update_terrains_cache() {
  2597. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2598. if (!tile_map) {
  2599. return;
  2600. }
  2601. Ref<TileSet> tile_set = tile_map->get_tileset();
  2602. if (!tile_set.is_valid()) {
  2603. return;
  2604. }
  2605. // Compute the tile sides.
  2606. tile_sides.clear();
  2607. TileSet::TileShape shape = tile_set->get_tile_shape();
  2608. if (shape == TileSet::TILE_SHAPE_SQUARE) {
  2609. tile_sides.push_back(TileSet::CELL_NEIGHBOR_RIGHT_SIDE);
  2610. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE);
  2611. tile_sides.push_back(TileSet::CELL_NEIGHBOR_LEFT_SIDE);
  2612. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_SIDE);
  2613. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  2614. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE);
  2615. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
  2616. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  2617. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
  2618. } else {
  2619. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  2620. tile_sides.push_back(TileSet::CELL_NEIGHBOR_RIGHT_SIDE);
  2621. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE);
  2622. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
  2623. tile_sides.push_back(TileSet::CELL_NEIGHBOR_LEFT_SIDE);
  2624. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  2625. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
  2626. } else {
  2627. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE);
  2628. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE);
  2629. tile_sides.push_back(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE);
  2630. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE);
  2631. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_SIDE);
  2632. tile_sides.push_back(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE);
  2633. }
  2634. }
  2635. // Organizes tiles into structures.
  2636. per_terrain_terrains_tile_patterns_tiles.resize(tile_set->get_terrain_sets_count());
  2637. per_terrain_terrains_tile_patterns.resize(tile_set->get_terrain_sets_count());
  2638. for (int i = 0; i < tile_set->get_terrain_sets_count(); i++) {
  2639. per_terrain_terrains_tile_patterns_tiles[i].clear();
  2640. per_terrain_terrains_tile_patterns[i].resize(tile_set->get_terrains_count(i));
  2641. for (int j = 0; j < (int)per_terrain_terrains_tile_patterns[i].size(); j++) {
  2642. per_terrain_terrains_tile_patterns[i][j].clear();
  2643. }
  2644. }
  2645. for (int source_index = 0; source_index < tile_set->get_source_count(); source_index++) {
  2646. int source_id = tile_set->get_source_id(source_index);
  2647. Ref<TileSetSource> source = tile_set->get_source(source_id);
  2648. Ref<TileSetAtlasSource> atlas_source = source;
  2649. if (atlas_source.is_valid()) {
  2650. for (int tile_index = 0; tile_index < source->get_tiles_count(); tile_index++) {
  2651. Vector2i tile_id = source->get_tile_id(tile_index);
  2652. for (int alternative_index = 0; alternative_index < source->get_alternative_tiles_count(tile_id); alternative_index++) {
  2653. int alternative_id = source->get_alternative_tile_id(tile_id, alternative_index);
  2654. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_id, alternative_id));
  2655. int terrain_set = tile_data->get_terrain_set();
  2656. if (terrain_set >= 0) {
  2657. ERR_FAIL_INDEX(terrain_set, (int)per_terrain_terrains_tile_patterns.size());
  2658. TileMapCell cell;
  2659. cell.source_id = source_id;
  2660. cell.set_atlas_coords(tile_id);
  2661. cell.alternative_tile = alternative_id;
  2662. TerrainsTilePattern terrains_tile_pattern = _build_terrains_tile_pattern(tile_data);
  2663. // Terrain bits.
  2664. for (int i = 0; i < terrains_tile_pattern.size(); i++) {
  2665. int terrain = terrains_tile_pattern[i];
  2666. if (terrain >= 0 && terrain < (int)per_terrain_terrains_tile_patterns[terrain_set].size()) {
  2667. per_terrain_terrains_tile_patterns[terrain_set][terrain].insert(terrains_tile_pattern);
  2668. terrain_tiles[cell] = tile_data;
  2669. per_terrain_terrains_tile_patterns_tiles[terrain_set][terrains_tile_pattern].insert(cell);
  2670. }
  2671. }
  2672. }
  2673. }
  2674. }
  2675. }
  2676. }
  2677. // Add the empty cell in the possible patterns and cells.
  2678. for (int i = 0; i < tile_set->get_terrain_sets_count(); i++) {
  2679. TerrainsTilePattern empty_pattern;
  2680. for (int j = 0; j < TileSet::CELL_NEIGHBOR_MAX; j++) {
  2681. if (tile_set->is_valid_peering_bit_terrain(i, TileSet::CellNeighbor(j))) {
  2682. empty_pattern.push_back(-1);
  2683. }
  2684. }
  2685. TileMapCell empty_cell;
  2686. empty_cell.source_id = TileSet::INVALID_SOURCE;
  2687. empty_cell.set_atlas_coords(TileSetSource::INVALID_ATLAS_COORDS);
  2688. empty_cell.alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE;
  2689. per_terrain_terrains_tile_patterns_tiles[i][empty_pattern].insert(empty_cell);
  2690. }
  2691. }
  2692. void TileMapEditorTerrainsPlugin::_update_terrains_tree() {
  2693. terrains_tree->clear();
  2694. terrains_tree->create_item();
  2695. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2696. if (!tile_map) {
  2697. return;
  2698. }
  2699. Ref<TileSet> tile_set = tile_map->get_tileset();
  2700. if (!tile_set.is_valid()) {
  2701. return;
  2702. }
  2703. // Fill in the terrain list.
  2704. Vector<Vector<Ref<Texture2D>>> icons = tile_set->generate_terrains_icons(Size2(16, 16) * EDSCALE);
  2705. for (int terrain_set_index = 0; terrain_set_index < tile_set->get_terrain_sets_count(); terrain_set_index++) {
  2706. // Add an item for the terrain set.
  2707. TreeItem *terrain_set_tree_item = terrains_tree->create_item();
  2708. String matches;
  2709. if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS_AND_SIDES) {
  2710. terrain_set_tree_item->set_icon(0, get_theme_icon(SNAME("TerrainMatchCornersAndSides"), SNAME("EditorIcons")));
  2711. matches = String(TTR("Matches Corners and Sides"));
  2712. } else if (tile_set->get_terrain_set_mode(terrain_set_index) == TileSet::TERRAIN_MODE_MATCH_CORNERS) {
  2713. terrain_set_tree_item->set_icon(0, get_theme_icon(SNAME("TerrainMatchCorners"), SNAME("EditorIcons")));
  2714. matches = String(TTR("Matches Corners Only"));
  2715. } else {
  2716. terrain_set_tree_item->set_icon(0, get_theme_icon(SNAME("TerrainMatchSides"), SNAME("EditorIcons")));
  2717. matches = String(TTR("Matches Sides Only"));
  2718. }
  2719. terrain_set_tree_item->set_text(0, vformat("Terrain Set %d (%s)", terrain_set_index, matches));
  2720. terrain_set_tree_item->set_selectable(0, false);
  2721. for (int terrain_index = 0; terrain_index < tile_set->get_terrains_count(terrain_set_index); terrain_index++) {
  2722. // Add the item to the terrain list.
  2723. TreeItem *terrain_tree_item = terrains_tree->create_item(terrain_set_tree_item);
  2724. terrain_tree_item->set_text(0, tile_set->get_terrain_name(terrain_set_index, terrain_index));
  2725. terrain_tree_item->set_icon_max_width(0, 32 * EDSCALE);
  2726. terrain_tree_item->set_icon(0, icons[terrain_set_index][terrain_index]);
  2727. Dictionary metadata_dict;
  2728. metadata_dict["terrain_set"] = terrain_set_index;
  2729. metadata_dict["terrain_id"] = terrain_index;
  2730. terrain_tree_item->set_metadata(0, metadata_dict);
  2731. }
  2732. }
  2733. }
  2734. void TileMapEditorTerrainsPlugin::_update_tiles_list() {
  2735. terrains_tile_list->clear();
  2736. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2737. if (!tile_map) {
  2738. return;
  2739. }
  2740. Ref<TileSet> tile_set = tile_map->get_tileset();
  2741. if (!tile_set.is_valid()) {
  2742. return;
  2743. }
  2744. TreeItem *selected_tree_item = terrains_tree->get_selected();
  2745. if (selected_tree_item && selected_tree_item->get_metadata(0)) {
  2746. Dictionary metadata_dict = selected_tree_item->get_metadata(0);
  2747. int selected_terrain_set = metadata_dict["terrain_set"];
  2748. int selected_terrain_id = metadata_dict["terrain_id"];
  2749. ERR_FAIL_INDEX(selected_terrain_set, (int)per_terrain_terrains_tile_patterns.size());
  2750. ERR_FAIL_INDEX(selected_terrain_id, (int)per_terrain_terrains_tile_patterns[selected_terrain_set].size());
  2751. // Sort the items in a map by the number of corresponding terrains.
  2752. Map<int, Set<TerrainsTilePattern>> sorted;
  2753. for (Set<TerrainsTilePattern>::Element *E = per_terrain_terrains_tile_patterns[selected_terrain_set][selected_terrain_id].front(); E; E = E->next()) {
  2754. // Count the number of matching sides/terrains.
  2755. int count = 0;
  2756. for (int i = 0; i < E->get().size(); i++) {
  2757. if (int(E->get()[i]) == selected_terrain_id) {
  2758. count++;
  2759. }
  2760. }
  2761. sorted[count].insert(E->get());
  2762. }
  2763. for (Map<int, Set<TerrainsTilePattern>>::Element *E_set = sorted.back(); E_set; E_set = E_set->prev()) {
  2764. for (Set<TerrainsTilePattern>::Element *E = E_set->get().front(); E; E = E->next()) {
  2765. TerrainsTilePattern terrains_tile_pattern = E->get();
  2766. // Get the icon.
  2767. Ref<Texture2D> icon;
  2768. Rect2 region;
  2769. bool transpose = false;
  2770. double max_probability = -1.0;
  2771. for (Set<TileMapCell>::Element *E_tile_map_cell = per_terrain_terrains_tile_patterns_tiles[selected_terrain_set][terrains_tile_pattern].front(); E_tile_map_cell; E_tile_map_cell = E_tile_map_cell->next()) {
  2772. Ref<TileSetSource> source = tile_set->get_source(E_tile_map_cell->get().source_id);
  2773. Ref<TileSetAtlasSource> atlas_source = source;
  2774. if (atlas_source.is_valid()) {
  2775. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E_tile_map_cell->get().get_atlas_coords(), E_tile_map_cell->get().alternative_tile));
  2776. if (tile_data->get_probability() > max_probability) {
  2777. icon = atlas_source->get_texture();
  2778. region = atlas_source->get_tile_texture_region(E_tile_map_cell->get().get_atlas_coords());
  2779. if (tile_data->get_flip_h()) {
  2780. region.position.x += region.size.x;
  2781. region.size.x = -region.size.x;
  2782. }
  2783. if (tile_data->get_flip_v()) {
  2784. region.position.y += region.size.y;
  2785. region.size.y = -region.size.y;
  2786. }
  2787. transpose = tile_data->get_transpose();
  2788. max_probability = tile_data->get_probability();
  2789. }
  2790. }
  2791. }
  2792. // Create the ItemList's item.
  2793. int item_index = terrains_tile_list->add_item("");
  2794. terrains_tile_list->set_item_icon(item_index, icon);
  2795. terrains_tile_list->set_item_icon_region(item_index, region);
  2796. terrains_tile_list->set_item_icon_transposed(item_index, transpose);
  2797. Dictionary list_metadata_dict;
  2798. list_metadata_dict["terrains_tile_pattern"] = terrains_tile_pattern;
  2799. terrains_tile_list->set_item_metadata(item_index, list_metadata_dict);
  2800. }
  2801. }
  2802. if (terrains_tile_list->get_item_count() > 0) {
  2803. terrains_tile_list->select(0);
  2804. }
  2805. }
  2806. }
  2807. void TileMapEditorTerrainsPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_layer) {
  2808. _stop_dragging(); // Avoids staying in a wrong drag state.
  2809. tile_map_id = p_tile_map_id;
  2810. tile_map_layer = p_tile_map_layer;
  2811. _update_terrains_cache();
  2812. _update_terrains_tree();
  2813. _update_tiles_list();
  2814. }
  2815. TileMapEditorTerrainsPlugin::TileMapEditorTerrainsPlugin() {
  2816. set_name("Terrains");
  2817. HSplitContainer *tilemap_tab_terrains = memnew(HSplitContainer);
  2818. tilemap_tab_terrains->set_h_size_flags(SIZE_EXPAND_FILL);
  2819. tilemap_tab_terrains->set_v_size_flags(SIZE_EXPAND_FILL);
  2820. add_child(tilemap_tab_terrains);
  2821. terrains_tree = memnew(Tree);
  2822. terrains_tree->set_h_size_flags(SIZE_EXPAND_FILL);
  2823. terrains_tree->set_stretch_ratio(0.25);
  2824. terrains_tree->set_custom_minimum_size(Size2i(70, 0) * EDSCALE);
  2825. terrains_tree->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
  2826. terrains_tree->set_hide_root(true);
  2827. terrains_tree->connect("item_selected", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_tiles_list));
  2828. tilemap_tab_terrains->add_child(terrains_tree);
  2829. terrains_tile_list = memnew(ItemList);
  2830. terrains_tile_list->set_h_size_flags(SIZE_EXPAND_FILL);
  2831. terrains_tile_list->set_max_columns(0);
  2832. terrains_tile_list->set_same_column_width(true);
  2833. terrains_tile_list->set_fixed_icon_size(Size2(30, 30) * EDSCALE);
  2834. terrains_tile_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
  2835. tilemap_tab_terrains->add_child(terrains_tile_list);
  2836. // --- Toolbar ---
  2837. toolbar = memnew(HBoxContainer);
  2838. HBoxContainer *tilemap_tiles_tools_buttons = memnew(HBoxContainer);
  2839. tool_buttons_group.instantiate();
  2840. paint_tool_button = memnew(Button);
  2841. paint_tool_button->set_flat(true);
  2842. paint_tool_button->set_toggle_mode(true);
  2843. paint_tool_button->set_button_group(tool_buttons_group);
  2844. paint_tool_button->set_pressed(true);
  2845. paint_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/paint_tool", "Paint", KEY_D));
  2846. paint_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTerrainsPlugin::_update_toolbar));
  2847. tilemap_tiles_tools_buttons->add_child(paint_tool_button);
  2848. toolbar->add_child(tilemap_tiles_tools_buttons);
  2849. // -- TileMap tool settings --
  2850. tools_settings = memnew(HBoxContainer);
  2851. toolbar->add_child(tools_settings);
  2852. tools_settings_vsep = memnew(VSeparator);
  2853. tools_settings->add_child(tools_settings_vsep);
  2854. // Picker
  2855. picker_button = memnew(Button);
  2856. picker_button->set_flat(true);
  2857. picker_button->set_toggle_mode(true);
  2858. picker_button->set_shortcut(ED_SHORTCUT("tiles_editor/picker", "Picker", KEY_P));
  2859. picker_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport));
  2860. tools_settings->add_child(picker_button);
  2861. // Erase button.
  2862. erase_button = memnew(Button);
  2863. erase_button->set_flat(true);
  2864. erase_button->set_toggle_mode(true);
  2865. erase_button->set_shortcut(ED_SHORTCUT("tiles_editor/eraser", "Eraser", KEY_E));
  2866. erase_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport));
  2867. tools_settings->add_child(erase_button);
  2868. }
  2869. TileMapEditorTerrainsPlugin::~TileMapEditorTerrainsPlugin() {
  2870. }
  2871. void TileMapEditor::_notification(int p_what) {
  2872. switch (p_what) {
  2873. case NOTIFICATION_ENTER_TREE:
  2874. case NOTIFICATION_THEME_CHANGED:
  2875. missing_tile_texture = get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons"));
  2876. warning_pattern_texture = get_theme_icon(SNAME("WarningPattern"), SNAME("EditorIcons"));
  2877. advanced_menu_button->set_icon(get_theme_icon(SNAME("Tools"), SNAME("EditorIcons")));
  2878. toggle_grid_button->set_icon(get_theme_icon(SNAME("Grid"), SNAME("EditorIcons")));
  2879. toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"));
  2880. toogle_highlight_selected_layer_button->set_icon(get_theme_icon(SNAME("TileMapHighlightSelected"), SNAME("EditorIcons")));
  2881. break;
  2882. case NOTIFICATION_INTERNAL_PROCESS:
  2883. if (is_visible_in_tree() && tileset_changed_needs_update) {
  2884. _update_bottom_panel();
  2885. _update_layers_selection();
  2886. tile_map_editor_plugins[tabs->get_current_tab()]->tile_set_changed();
  2887. CanvasItemEditor::get_singleton()->update_viewport();
  2888. tileset_changed_needs_update = false;
  2889. }
  2890. break;
  2891. case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED:
  2892. toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"));
  2893. break;
  2894. case NOTIFICATION_VISIBILITY_CHANGED:
  2895. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2896. if (tile_map) {
  2897. if (is_visible_in_tree()) {
  2898. tile_map->set_selected_layer(tile_map_layer);
  2899. } else {
  2900. tile_map->set_selected_layer(-1);
  2901. }
  2902. }
  2903. break;
  2904. }
  2905. }
  2906. void TileMapEditor::_on_grid_toggled(bool p_pressed) {
  2907. EditorSettings::get_singleton()->set("editors/tiles_editor/display_grid", p_pressed);
  2908. }
  2909. void TileMapEditor::_layers_selection_button_draw() {
  2910. if (!has_theme_icon(SNAME("arrow"), SNAME("OptionButton"))) {
  2911. return;
  2912. }
  2913. RID ci = layers_selection_button->get_canvas_item();
  2914. Ref<Texture2D> arrow = Control::get_theme_icon(SNAME("arrow"), SNAME("OptionButton"));
  2915. Color clr = Color(1, 1, 1);
  2916. if (get_theme_constant(SNAME("modulate_arrow"))) {
  2917. switch (layers_selection_button->get_draw_mode()) {
  2918. case BaseButton::DRAW_PRESSED:
  2919. clr = get_theme_color(SNAME("font_pressed_color"));
  2920. break;
  2921. case BaseButton::DRAW_HOVER:
  2922. clr = get_theme_color(SNAME("font_hover_color"));
  2923. break;
  2924. case BaseButton::DRAW_DISABLED:
  2925. clr = get_theme_color(SNAME("font_disabled_color"));
  2926. break;
  2927. default:
  2928. clr = get_theme_color(SNAME("font_color"));
  2929. }
  2930. }
  2931. Size2 size = layers_selection_button->get_size();
  2932. Point2 ofs;
  2933. if (is_layout_rtl()) {
  2934. ofs = Point2(get_theme_constant(SNAME("arrow_margin"), SNAME("OptionButton")), int(Math::abs((size.height - arrow->get_height()) / 2)));
  2935. } else {
  2936. ofs = Point2(size.width - arrow->get_width() - get_theme_constant(SNAME("arrow_margin"), SNAME("OptionButton")), int(Math::abs((size.height - arrow->get_height()) / 2)));
  2937. }
  2938. Rect2 dst_rect = Rect2(ofs, arrow->get_size());
  2939. if (!layers_selection_button->is_pressed()) {
  2940. dst_rect.size = -dst_rect.size;
  2941. }
  2942. arrow->draw_rect(ci, dst_rect, false, clr);
  2943. }
  2944. void TileMapEditor::_layers_selection_button_pressed() {
  2945. if (!layers_selection_popup->is_visible()) {
  2946. Size2 size = layers_selection_popup->get_contents_minimum_size();
  2947. size.x = MAX(size.x, layers_selection_button->get_size().x);
  2948. layers_selection_popup->set_position(layers_selection_button->get_screen_position() - Size2(0, size.y * get_global_transform().get_scale().y));
  2949. layers_selection_popup->set_size(size);
  2950. layers_selection_popup->popup();
  2951. } else {
  2952. layers_selection_popup->hide();
  2953. }
  2954. }
  2955. void TileMapEditor::_layers_selection_id_pressed(int p_id) {
  2956. tile_map_layer = p_id;
  2957. _update_layers_selection();
  2958. }
  2959. void TileMapEditor::_advanced_menu_button_id_pressed(int p_id) {
  2960. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2961. if (!tile_map) {
  2962. return;
  2963. }
  2964. Ref<TileSet> tile_set = tile_map->get_tileset();
  2965. if (!tile_set.is_valid()) {
  2966. return;
  2967. }
  2968. if (p_id == 0) { // Replace Tile Proxies
  2969. undo_redo->create_action(TTR("Replace Tiles with Proxies"));
  2970. for (int layer_index = 0; layer_index < tile_map->get_layers_count(); layer_index++) {
  2971. TypedArray<Vector2i> used_cells = tile_map->get_used_cells(layer_index);
  2972. for (int i = 0; i < used_cells.size(); i++) {
  2973. Vector2i cell_coords = used_cells[i];
  2974. TileMapCell from = tile_map->get_cell(layer_index, cell_coords);
  2975. Array to_array = tile_set->map_tile_proxy(from.source_id, from.get_atlas_coords(), from.alternative_tile);
  2976. TileMapCell to;
  2977. to.source_id = to_array[0];
  2978. to.set_atlas_coords(to_array[1]);
  2979. to.alternative_tile = to_array[2];
  2980. if (from != to) {
  2981. undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, cell_coords, to.source_id, to.get_atlas_coords(), to.alternative_tile);
  2982. undo_redo->add_undo_method(tile_map, "set_cell", tile_map_layer, cell_coords, from.source_id, from.get_atlas_coords(), from.alternative_tile);
  2983. }
  2984. }
  2985. }
  2986. undo_redo->commit_action();
  2987. }
  2988. }
  2989. void TileMapEditor::_update_bottom_panel() {
  2990. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  2991. if (!tile_map) {
  2992. return;
  2993. }
  2994. Ref<TileSet> tile_set = tile_map->get_tileset();
  2995. // Update the visibility of controls.
  2996. missing_tileset_label->set_visible(!tile_set.is_valid());
  2997. if (!tile_set.is_valid()) {
  2998. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  2999. tile_map_editor_plugins[i]->hide();
  3000. }
  3001. } else {
  3002. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  3003. tile_map_editor_plugins[i]->set_visible(i == tabs->get_current_tab());
  3004. }
  3005. }
  3006. }
  3007. Vector<Vector2i> TileMapEditor::get_line(TileMap *p_tile_map, Vector2i p_from_cell, Vector2i p_to_cell) {
  3008. ERR_FAIL_COND_V(!p_tile_map, Vector<Vector2i>());
  3009. Ref<TileSet> tile_set = p_tile_map->get_tileset();
  3010. ERR_FAIL_COND_V(!tile_set.is_valid(), Vector<Vector2i>());
  3011. if (tile_set->get_tile_shape() == TileSet::TILE_SHAPE_SQUARE) {
  3012. return Geometry2D::bresenham_line(p_from_cell, p_to_cell);
  3013. } else {
  3014. // Adapt the bresenham line algorithm to half-offset shapes.
  3015. // See this blog post: http://zvold.blogspot.com/2010/01/bresenhams-line-drawing-algorithm-on_26.html
  3016. Vector<Point2i> points;
  3017. bool transposed = tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL;
  3018. p_from_cell = TileMap::transform_coords_layout(p_from_cell, tile_set->get_tile_offset_axis(), tile_set->get_tile_layout(), TileSet::TILE_LAYOUT_STACKED);
  3019. p_to_cell = TileMap::transform_coords_layout(p_to_cell, tile_set->get_tile_offset_axis(), tile_set->get_tile_layout(), TileSet::TILE_LAYOUT_STACKED);
  3020. if (transposed) {
  3021. SWAP(p_from_cell.x, p_from_cell.y);
  3022. SWAP(p_to_cell.x, p_to_cell.y);
  3023. }
  3024. Vector2i delta = p_to_cell - p_from_cell;
  3025. delta = Vector2i(2 * delta.x + ABS(p_to_cell.y % 2) - ABS(p_from_cell.y % 2), delta.y);
  3026. Vector2i sign = delta.sign();
  3027. Vector2i current = p_from_cell;
  3028. points.push_back(TileMap::transform_coords_layout(transposed ? Vector2i(current.y, current.x) : current, tile_set->get_tile_offset_axis(), TileSet::TILE_LAYOUT_STACKED, tile_set->get_tile_layout()));
  3029. int err = 0;
  3030. if (ABS(delta.y) < ABS(delta.x)) {
  3031. Vector2i err_step = 3 * delta.abs();
  3032. while (current != p_to_cell) {
  3033. err += err_step.y;
  3034. if (err > ABS(delta.x)) {
  3035. if (sign.x == 0) {
  3036. current += Vector2(sign.y, 0);
  3037. } else {
  3038. current += Vector2(bool(current.y % 2) ^ (sign.x < 0) ? sign.x : 0, sign.y);
  3039. }
  3040. err -= err_step.x;
  3041. } else {
  3042. current += Vector2i(sign.x, 0);
  3043. err += err_step.y;
  3044. }
  3045. points.push_back(TileMap::transform_coords_layout(transposed ? Vector2i(current.y, current.x) : current, tile_set->get_tile_offset_axis(), TileSet::TILE_LAYOUT_STACKED, tile_set->get_tile_layout()));
  3046. }
  3047. } else {
  3048. Vector2i err_step = delta.abs();
  3049. while (current != p_to_cell) {
  3050. err += err_step.x;
  3051. if (err > 0) {
  3052. if (sign.x == 0) {
  3053. current += Vector2(0, sign.y);
  3054. } else {
  3055. current += Vector2(bool(current.y % 2) ^ (sign.x < 0) ? sign.x : 0, sign.y);
  3056. }
  3057. err -= err_step.y;
  3058. } else {
  3059. if (sign.x == 0) {
  3060. current += Vector2(0, sign.y);
  3061. } else {
  3062. current += Vector2(bool(current.y % 2) ^ (sign.x > 0) ? -sign.x : 0, sign.y);
  3063. }
  3064. err += err_step.y;
  3065. }
  3066. points.push_back(TileMap::transform_coords_layout(transposed ? Vector2i(current.y, current.x) : current, tile_set->get_tile_offset_axis(), TileSet::TILE_LAYOUT_STACKED, tile_set->get_tile_layout()));
  3067. }
  3068. }
  3069. return points;
  3070. }
  3071. }
  3072. void TileMapEditor::_tile_map_changed() {
  3073. tileset_changed_needs_update = true;
  3074. }
  3075. void TileMapEditor::_tab_changed(int p_tab_id) {
  3076. // Make the plugin edit the correct tilemap.
  3077. tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id, tile_map_layer);
  3078. // Update toolbar.
  3079. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  3080. tile_map_editor_plugins[i]->get_toolbar()->set_visible(i == p_tab_id);
  3081. }
  3082. // Update visible panel.
  3083. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  3084. if (!tile_map || !tile_map->get_tileset().is_valid()) {
  3085. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  3086. tile_map_editor_plugins[i]->hide();
  3087. }
  3088. } else {
  3089. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  3090. tile_map_editor_plugins[i]->set_visible(i == tabs->get_current_tab());
  3091. }
  3092. }
  3093. // Graphical update.
  3094. tile_map_editor_plugins[tabs->get_current_tab()]->update();
  3095. CanvasItemEditor::get_singleton()->update_viewport();
  3096. }
  3097. void TileMapEditor::_layers_select_next_or_previous(bool p_next) {
  3098. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  3099. if (!tile_map) {
  3100. return;
  3101. }
  3102. if (tile_map->get_layers_count() < 1) {
  3103. return;
  3104. }
  3105. if (tile_map_layer < 0) {
  3106. tile_map_layer = 0;
  3107. }
  3108. int inc = p_next ? 1 : -1;
  3109. int origin_layer = tile_map_layer;
  3110. tile_map_layer = Math::posmod((tile_map_layer + inc), tile_map->get_layers_count());
  3111. while (tile_map_layer != origin_layer) {
  3112. if (tile_map->is_layer_enabled(tile_map_layer)) {
  3113. break;
  3114. }
  3115. tile_map_layer = Math::posmod((tile_map_layer + inc), tile_map->get_layers_count());
  3116. }
  3117. _update_layers_selection();
  3118. }
  3119. void TileMapEditor::_update_layers_selection() {
  3120. layers_selection_popup->clear();
  3121. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  3122. if (!tile_map) {
  3123. return;
  3124. }
  3125. // Update the selected layer.
  3126. if (is_visible_in_tree() && tile_map->get_layers_count() >= 1) {
  3127. tile_map_layer = CLAMP(tile_map_layer, 0, tile_map->get_layers_count() - 1);
  3128. // Search for an enabled layer if the current one is not.
  3129. int origin_layer = tile_map_layer;
  3130. while (tile_map_layer >= 0 && !tile_map->is_layer_enabled(tile_map_layer)) {
  3131. tile_map_layer--;
  3132. }
  3133. if (tile_map_layer < 0) {
  3134. tile_map_layer = origin_layer;
  3135. while (tile_map_layer < tile_map->get_layers_count() && !tile_map->is_layer_enabled(tile_map_layer)) {
  3136. tile_map_layer++;
  3137. }
  3138. }
  3139. if (tile_map_layer >= tile_map->get_layers_count()) {
  3140. tile_map_layer = -1;
  3141. }
  3142. } else {
  3143. tile_map_layer = -1;
  3144. }
  3145. tile_map->set_selected_layer(toogle_highlight_selected_layer_button->is_pressed() ? tile_map_layer : -1);
  3146. // Build the list of layers.
  3147. for (int i = 0; i < tile_map->get_layers_count(); i++) {
  3148. String name = tile_map->get_layer_name(i);
  3149. layers_selection_popup->add_item(name.is_empty() ? vformat(TTR("Layer #%d"), i) : name, i);
  3150. layers_selection_popup->set_item_as_radio_checkable(i, true);
  3151. layers_selection_popup->set_item_disabled(i, !tile_map->is_layer_enabled(i));
  3152. layers_selection_popup->set_item_checked(i, i == tile_map_layer);
  3153. }
  3154. // Update the button label.
  3155. if (tile_map_layer >= 0) {
  3156. layers_selection_button->set_text(layers_selection_popup->get_item_text(tile_map_layer));
  3157. } else {
  3158. layers_selection_button->set_text(TTR("Select a layer"));
  3159. }
  3160. // Set button minimum width.
  3161. Size2 min_button_size = Size2(layers_selection_popup->get_contents_minimum_size().x, 0);
  3162. if (has_theme_icon(SNAME("arrow"), SNAME("OptionButton"))) {
  3163. Ref<Texture2D> arrow = Control::get_theme_icon(SNAME("arrow"), SNAME("OptionButton"));
  3164. min_button_size.x += arrow->get_size().x;
  3165. }
  3166. layers_selection_button->set_custom_minimum_size(min_button_size);
  3167. layers_selection_button->update();
  3168. tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id, tile_map_layer);
  3169. }
  3170. void TileMapEditor::_move_tile_map_array_element(Object *p_undo_redo, Object *p_edited, String p_array_prefix, int p_from_index, int p_to_pos) {
  3171. UndoRedo *undo_redo = Object::cast_to<UndoRedo>(p_undo_redo);
  3172. ERR_FAIL_COND(!undo_redo);
  3173. TileMap *tile_map = Object::cast_to<TileMap>(p_edited);
  3174. if (!tile_map) {
  3175. return;
  3176. }
  3177. // Compute the array indices to save.
  3178. int begin = 0;
  3179. int end;
  3180. if (p_array_prefix == "layer_") {
  3181. end = tile_map->get_layers_count();
  3182. } else {
  3183. ERR_FAIL_MSG("Invalid array prefix for TileSet.");
  3184. }
  3185. if (p_from_index < 0) {
  3186. // Adding new.
  3187. if (p_to_pos >= 0) {
  3188. begin = p_to_pos;
  3189. } else {
  3190. end = 0; // Nothing to save when adding at the end.
  3191. }
  3192. } else if (p_to_pos < 0) {
  3193. // Removing.
  3194. begin = p_from_index;
  3195. } else {
  3196. // Moving.
  3197. begin = MIN(p_from_index, p_to_pos);
  3198. end = MIN(MAX(p_from_index, p_to_pos) + 1, end);
  3199. }
  3200. #define ADD_UNDO(obj, property) undo_redo->add_undo_property(obj, property, obj->get(property));
  3201. // Save layers' properties.
  3202. if (p_from_index < 0) {
  3203. undo_redo->add_undo_method(tile_map, "remove_layer", p_to_pos < 0 ? tile_map->get_layers_count() : p_to_pos);
  3204. } else if (p_to_pos < 0) {
  3205. undo_redo->add_undo_method(tile_map, "add_layer", p_from_index);
  3206. }
  3207. List<PropertyInfo> properties;
  3208. tile_map->get_property_list(&properties);
  3209. for (PropertyInfo pi : properties) {
  3210. if (pi.name.begins_with(p_array_prefix)) {
  3211. String str = pi.name.trim_prefix(p_array_prefix);
  3212. int to_char_index = 0;
  3213. while (to_char_index < str.length()) {
  3214. if (str[to_char_index] < '0' || str[to_char_index] > '9') {
  3215. break;
  3216. }
  3217. to_char_index++;
  3218. }
  3219. if (to_char_index > 0) {
  3220. int array_index = str.left(to_char_index).to_int();
  3221. if (array_index >= begin && array_index < end) {
  3222. ADD_UNDO(tile_map, pi.name);
  3223. }
  3224. }
  3225. }
  3226. }
  3227. #undef ADD_UNDO
  3228. if (p_from_index < 0) {
  3229. undo_redo->add_do_method(tile_map, "add_layer", p_to_pos);
  3230. } else if (p_to_pos < 0) {
  3231. undo_redo->add_do_method(tile_map, "remove_layer", p_from_index);
  3232. } else {
  3233. undo_redo->add_do_method(tile_map, "move_layer", p_from_index, p_to_pos);
  3234. }
  3235. }
  3236. bool TileMapEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
  3237. if (ED_IS_SHORTCUT("tiles_editor/select_next_layer", p_event) && p_event->is_pressed()) {
  3238. _layers_select_next_or_previous(true);
  3239. return true;
  3240. }
  3241. if (ED_IS_SHORTCUT("tiles_editor/select_previous_layer", p_event) && p_event->is_pressed()) {
  3242. _layers_select_next_or_previous(false);
  3243. return true;
  3244. }
  3245. return tile_map_editor_plugins[tabs->get_current_tab()]->forward_canvas_gui_input(p_event);
  3246. }
  3247. void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
  3248. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  3249. if (!tile_map) {
  3250. return;
  3251. }
  3252. Ref<TileSet> tile_set = tile_map->get_tileset();
  3253. if (!tile_set.is_valid()) {
  3254. return;
  3255. }
  3256. if (!tile_map->is_visible_in_tree()) {
  3257. return;
  3258. }
  3259. Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
  3260. Transform2D xform_inv = xform.affine_inverse();
  3261. Vector2i tile_shape_size = tile_set->get_tile_size();
  3262. // Draw tiles with invalid IDs in the grid.
  3263. if (tile_map_layer >= 0) {
  3264. ERR_FAIL_COND(tile_map_layer >= tile_map->get_layers_count());
  3265. TypedArray<Vector2i> used_cells = tile_map->get_used_cells(tile_map_layer);
  3266. for (int i = 0; i < used_cells.size(); i++) {
  3267. Vector2i coords = used_cells[i];
  3268. int tile_source_id = tile_map->get_cell_source_id(tile_map_layer, coords);
  3269. if (tile_source_id >= 0) {
  3270. Vector2i tile_atlas_coords = tile_map->get_cell_atlas_coords(tile_map_layer, coords);
  3271. int tile_alternative_tile = tile_map->get_cell_alternative_tile(tile_map_layer, coords);
  3272. TileSetSource *source = nullptr;
  3273. if (tile_set->has_source(tile_source_id)) {
  3274. source = *tile_set->get_source(tile_source_id);
  3275. }
  3276. if (!source || !source->has_tile(tile_atlas_coords) || !source->has_alternative_tile(tile_atlas_coords, tile_alternative_tile)) {
  3277. // Generate a random color from the hashed values of the tiles.
  3278. Array a = tile_set->map_tile_proxy(tile_source_id, tile_atlas_coords, tile_alternative_tile);
  3279. if (int(a[0]) == tile_source_id && Vector2i(a[1]) == tile_atlas_coords && int(a[2]) == tile_alternative_tile) {
  3280. // Only display the pattern if we have no proxy tile.
  3281. Array to_hash;
  3282. to_hash.push_back(tile_source_id);
  3283. to_hash.push_back(tile_atlas_coords);
  3284. to_hash.push_back(tile_alternative_tile);
  3285. uint32_t hash = RandomPCG(to_hash.hash()).rand();
  3286. Color color;
  3287. color = color.from_hsv(
  3288. (float)((hash >> 24) & 0xFF) / 256.0,
  3289. Math::lerp(0.5, 1.0, (float)((hash >> 16) & 0xFF) / 256.0),
  3290. Math::lerp(0.5, 1.0, (float)((hash >> 8) & 0xFF) / 256.0),
  3291. 0.8);
  3292. // Draw the scaled tile.
  3293. Transform2D tile_xform;
  3294. tile_xform.set_origin(tile_map->map_to_world(coords));
  3295. tile_xform.set_scale(tile_shape_size);
  3296. tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, true, warning_pattern_texture);
  3297. }
  3298. // Draw the warning icon.
  3299. int min_axis = missing_tile_texture->get_size().min_axis();
  3300. Vector2 icon_size;
  3301. icon_size[min_axis] = tile_set->get_tile_size()[min_axis] / 3;
  3302. icon_size[(min_axis + 1) % 2] = (icon_size[min_axis] * missing_tile_texture->get_size()[(min_axis + 1) % 2] / missing_tile_texture->get_size()[min_axis]);
  3303. Rect2 rect = Rect2(xform.xform(tile_map->map_to_world(coords)) - (icon_size * xform.get_scale() / 2), icon_size * xform.get_scale());
  3304. p_overlay->draw_texture_rect(missing_tile_texture, rect);
  3305. }
  3306. }
  3307. }
  3308. }
  3309. // Fading on the border.
  3310. const int fading = 5;
  3311. // Determine the drawn area.
  3312. Size2 screen_size = p_overlay->get_size();
  3313. Rect2i screen_rect;
  3314. screen_rect.position = tile_map->world_to_map(xform_inv.xform(Vector2()));
  3315. screen_rect.expand_to(tile_map->world_to_map(xform_inv.xform(Vector2(0, screen_size.height))));
  3316. screen_rect.expand_to(tile_map->world_to_map(xform_inv.xform(Vector2(screen_size.width, 0))));
  3317. screen_rect.expand_to(tile_map->world_to_map(xform_inv.xform(screen_size)));
  3318. screen_rect = screen_rect.grow(1);
  3319. Rect2i tilemap_used_rect = tile_map->get_used_rect();
  3320. Rect2i displayed_rect = tilemap_used_rect.intersection(screen_rect);
  3321. displayed_rect = displayed_rect.grow(fading);
  3322. // Reduce the drawn area to avoid crashes if needed.
  3323. int max_size = 100;
  3324. if (displayed_rect.size.x > max_size) {
  3325. displayed_rect = displayed_rect.grow_individual(-(displayed_rect.size.x - max_size) / 2, 0, -(displayed_rect.size.x - max_size) / 2, 0);
  3326. }
  3327. if (displayed_rect.size.y > max_size) {
  3328. displayed_rect = displayed_rect.grow_individual(0, -(displayed_rect.size.y - max_size) / 2, 0, -(displayed_rect.size.y - max_size) / 2);
  3329. }
  3330. // Draw the grid.
  3331. bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid");
  3332. if (display_grid) {
  3333. Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color");
  3334. for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) {
  3335. for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) {
  3336. Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position;
  3337. // Fade out the border of the grid.
  3338. float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f);
  3339. float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f);
  3340. float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f);
  3341. float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f);
  3342. float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
  3343. Transform2D tile_xform;
  3344. tile_xform.set_origin(tile_map->map_to_world(Vector2(x, y)));
  3345. tile_xform.set_scale(tile_shape_size);
  3346. Color color = grid_color;
  3347. color.a = color.a * opacity;
  3348. tile_set->draw_tile_shape(p_overlay, xform * tile_xform, color, false);
  3349. }
  3350. }
  3351. }
  3352. // Draw the IDs for debug.
  3353. /*Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
  3354. for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) {
  3355. for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) {
  3356. p_overlay->draw_string(font, xform.xform(tile_map->map_to_world(Vector2(x, y))) + Vector2i(-tile_shape_size.x / 2, 0), vformat("%s", Vector2(x, y)));
  3357. }
  3358. }*/
  3359. // Draw the plugins.
  3360. tile_map_editor_plugins[tabs->get_current_tab()]->forward_canvas_draw_over_viewport(p_overlay);
  3361. }
  3362. void TileMapEditor::edit(TileMap *p_tile_map) {
  3363. if (p_tile_map && p_tile_map->get_instance_id() == tile_map_id) {
  3364. return;
  3365. }
  3366. TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  3367. if (tile_map) {
  3368. // Unselect layer if we are changing tile_map.
  3369. if (tile_map != p_tile_map) {
  3370. tile_map->set_selected_layer(-1);
  3371. }
  3372. // Disconnect to changes.
  3373. tile_map->disconnect("changed", callable_mp(this, &TileMapEditor::_tile_map_changed));
  3374. }
  3375. if (p_tile_map) {
  3376. // Change the edited object.
  3377. tile_map_id = p_tile_map->get_instance_id();
  3378. tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
  3379. // Connect to changes.
  3380. if (!tile_map->is_connected("changed", callable_mp(this, &TileMapEditor::_tile_map_changed))) {
  3381. tile_map->connect("changed", callable_mp(this, &TileMapEditor::_tile_map_changed));
  3382. }
  3383. } else {
  3384. tile_map_id = ObjectID();
  3385. }
  3386. _update_layers_selection();
  3387. // Call the plugins.
  3388. tile_map_editor_plugins[tabs->get_current_tab()]->edit(tile_map_id, tile_map_layer);
  3389. _tile_map_changed();
  3390. }
  3391. TileMapEditor::TileMapEditor() {
  3392. set_process_internal(true);
  3393. // Shortcuts.
  3394. ED_SHORTCUT("tiles_editor/select_next_layer", TTR("Select Next Tile Map Layer"), KEY_PAGEUP);
  3395. ED_SHORTCUT("tiles_editor/select_previous_layer", TTR("Select Previous Tile Map Layer"), KEY_PAGEDOWN);
  3396. // TileMap editor plugins
  3397. tile_map_editor_plugins.push_back(memnew(TileMapEditorTilesPlugin));
  3398. tile_map_editor_plugins.push_back(memnew(TileMapEditorTerrainsPlugin));
  3399. // Tabs.
  3400. tabs = memnew(Tabs);
  3401. tabs->set_clip_tabs(false);
  3402. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  3403. tabs->add_tab(tile_map_editor_plugins[i]->get_name());
  3404. }
  3405. tabs->connect("tab_changed", callable_mp(this, &TileMapEditor::_tab_changed));
  3406. // --- TileMap toolbar ---
  3407. tile_map_toolbar = memnew(HBoxContainer);
  3408. tile_map_toolbar->set_h_size_flags(SIZE_EXPAND_FILL);
  3409. // Tabs.
  3410. tile_map_toolbar->add_child(tabs);
  3411. // Tabs toolbars.
  3412. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  3413. tile_map_editor_plugins[i]->get_toolbar()->hide();
  3414. tile_map_toolbar->add_child(tile_map_editor_plugins[i]->get_toolbar());
  3415. }
  3416. // Wide empty separation control.
  3417. Control *h_empty_space = memnew(Control);
  3418. h_empty_space->set_h_size_flags(SIZE_EXPAND_FILL);
  3419. tile_map_toolbar->add_child(h_empty_space);
  3420. // Layer selector.
  3421. layers_selection_popup = memnew(PopupMenu);
  3422. layers_selection_popup->connect("id_pressed", callable_mp(this, &TileMapEditor::_layers_selection_id_pressed));
  3423. layers_selection_popup->set_close_on_parent_focus(false);
  3424. layers_selection_button = memnew(Button);
  3425. layers_selection_button->set_toggle_mode(true);
  3426. layers_selection_button->connect("draw", callable_mp(this, &TileMapEditor::_layers_selection_button_draw));
  3427. layers_selection_button->connect("pressed", callable_mp(this, &TileMapEditor::_layers_selection_button_pressed));
  3428. layers_selection_button->connect("hidden", callable_mp((Window *)layers_selection_popup, &Popup::hide));
  3429. layers_selection_button->set_tooltip(TTR("Tile Map Layer"));
  3430. layers_selection_button->add_child(layers_selection_popup);
  3431. tile_map_toolbar->add_child(layers_selection_button);
  3432. toogle_highlight_selected_layer_button = memnew(Button);
  3433. toogle_highlight_selected_layer_button->set_flat(true);
  3434. toogle_highlight_selected_layer_button->set_toggle_mode(true);
  3435. toogle_highlight_selected_layer_button->set_pressed(true);
  3436. toogle_highlight_selected_layer_button->connect("pressed", callable_mp(this, &TileMapEditor::_update_layers_selection));
  3437. toogle_highlight_selected_layer_button->set_tooltip(TTR("Highlight Selected TileMap Layer"));
  3438. tile_map_toolbar->add_child(toogle_highlight_selected_layer_button);
  3439. tile_map_toolbar->add_child(memnew(VSeparator));
  3440. // Grid toggle.
  3441. toggle_grid_button = memnew(Button);
  3442. toggle_grid_button->set_flat(true);
  3443. toggle_grid_button->set_toggle_mode(true);
  3444. toggle_grid_button->set_tooltip(TTR("Toggle grid visibility."));
  3445. toggle_grid_button->connect("toggled", callable_mp(this, &TileMapEditor::_on_grid_toggled));
  3446. tile_map_toolbar->add_child(toggle_grid_button);
  3447. // Advanced settings menu button.
  3448. advanced_menu_button = memnew(MenuButton);
  3449. advanced_menu_button->set_flat(true);
  3450. advanced_menu_button->get_popup()->add_item(TTR("Automatically Replace Tiles with Proxies"));
  3451. advanced_menu_button->get_popup()->connect("id_pressed", callable_mp(this, &TileMapEditor::_advanced_menu_button_id_pressed));
  3452. tile_map_toolbar->add_child(advanced_menu_button);
  3453. missing_tileset_label = memnew(Label);
  3454. missing_tileset_label->set_text(TTR("The edited TileMap node has no TileSet resource."));
  3455. missing_tileset_label->set_h_size_flags(SIZE_EXPAND_FILL);
  3456. missing_tileset_label->set_v_size_flags(SIZE_EXPAND_FILL);
  3457. missing_tileset_label->set_align(Label::ALIGN_CENTER);
  3458. missing_tileset_label->set_valign(Label::VALIGN_CENTER);
  3459. missing_tileset_label->hide();
  3460. add_child(missing_tileset_label);
  3461. for (int i = 0; i < tile_map_editor_plugins.size(); i++) {
  3462. add_child(tile_map_editor_plugins[i]);
  3463. tile_map_editor_plugins[i]->set_h_size_flags(SIZE_EXPAND_FILL);
  3464. tile_map_editor_plugins[i]->set_v_size_flags(SIZE_EXPAND_FILL);
  3465. tile_map_editor_plugins[i]->set_visible(i == 0);
  3466. }
  3467. _tab_changed(0);
  3468. // Registers UndoRedo inspector callback.
  3469. EditorNode::get_singleton()->get_editor_data().add_move_array_element_function(SNAME("TileMap"), callable_mp(this, &TileMapEditor::_move_tile_map_array_element));
  3470. }
  3471. TileMapEditor::~TileMapEditor() {
  3472. }