Tune caves
[oweals/minetest.git] / src / test.cpp
index caf31d1af9d2e823372e18852b0b583f2ce928ed..cb01edffdf1511c5b5687ca09b5114a3c2137888 100644 (file)
@@ -35,6 +35,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "mapsector.h"
 #include "settings.h"
 #include "log.h"
+#include "utility_string.h"
+#include "voxelalgorithms.h"
 
 /*
        Asserts that the exception occurs
@@ -53,6 +55,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #define CONTENT_STONE 0
 #define CONTENT_GRASS 0x800
+#define CONTENT_TORCH 100
 
 void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *ndef)
 {
@@ -68,6 +71,7 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n
        itemdef.type = ITEM_NODE;
        itemdef.name = "default:stone";
        itemdef.description = "Stone";
+       itemdef.groups["cracky"] = 3;
        itemdef.inventory_image = "[inventorycube"
                "{default_stone.png"
                "{default_stone.png"
@@ -76,14 +80,7 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n
        f.name = itemdef.name;
        for(int i = 0; i < 6; i++)
                f.tname_tiles[i] = "default_stone.png";
-       f.param_type = CPT_MINERAL;
        f.is_ground_content = true;
-       f.dug_item = itemdef.name;
-       f.material.diggability = DIGGABLE_NORMAL;
-       f.material.weight = 5.0;
-       f.material.crackiness = 1.0;
-       f.material.crumbliness = -0.1;
-       f.material.cuttability = -0.2;
        idef->registerItem(itemdef);
        ndef->set(i, f);
 
@@ -95,6 +92,7 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n
        itemdef.type = ITEM_NODE;
        itemdef.name = "default:dirt_with_grass";
        itemdef.description = "Dirt with grass";
+       itemdef.groups["crumbly"] = 3;
        itemdef.inventory_image = "[inventorycube"
                "{default_grass.png"
                "{default_dirt.png&default_grass_side.png"
@@ -106,12 +104,22 @@ void define_some_nodes(IWritableItemDefManager *idef, IWritableNodeDefManager *n
        for(int i = 2; i < 6; i++)
                f.tname_tiles[i] = "default_dirt.png^default_grass_side.png";
        f.is_ground_content = true;
-       f.dug_item = itemdef.name;
-       f.material.diggability = DIGGABLE_NORMAL;
-       f.material.weight = 1.2;
-       f.material.crackiness = 0.0;
-       f.material.crumbliness = 1.2;
-       f.material.cuttability = -0.4;
+       idef->registerItem(itemdef);
+       ndef->set(i, f);
+
+       /*
+               Torch (minimal definition for lighting tests)
+       */
+       i = CONTENT_TORCH;
+       itemdef = ItemDefinition();
+       itemdef.type = ITEM_NODE;
+       itemdef.name = "default:torch";
+       f = ContentFeatures();
+       f.name = itemdef.name;
+       f.param_type = CPT_LIGHT;
+       f.light_propagates = true;
+       f.sunlight_propagates = true;
+       f.light_source = LIGHT_MAX-1;
        idef->registerItem(itemdef);
        ndef->set(i, f);
 }
@@ -131,6 +139,11 @@ struct TestUtilities
                assert(is_yes("YeS") == true);
                assert(is_yes("") == false);
                assert(is_yes("FAlse") == false);
+               const char *ends[] = {"abc", "c", "bc", NULL};
+               assert(removeStringEnd("abc", ends) == "");
+               assert(removeStringEnd("bc", ends) == "b");
+               assert(removeStringEnd("12c", ends) == "12");
+               assert(removeStringEnd("foo", ends) == "");
        }
 };
 
@@ -218,6 +231,8 @@ struct TestSerialization
                        mkstr("\1\0") + teststring2_w_encoded);
                assert(serializeLongString(teststring2) ==
                        mkstr("\0\0\1\0") + teststring2);
+               // MSVC fails when directly using "\\\\"
+               std::string backslash = "\\";
                assert(serializeJsonString(teststring2) ==
                        mkstr("\"") +
                        "\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007" +
@@ -226,7 +241,7 @@ struct TestSerialization
                        "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f" +
                        " !\\\"" + teststring2.substr(0x23, 0x2f-0x23) +
                        "\\/" + teststring2.substr(0x30, 0x5c-0x30) +
-                       "\\\\" + teststring2.substr(0x5d, 0x7f-0x5d) + "\\u007f" +
+                       backslash + backslash + teststring2.substr(0x5d, 0x7f-0x5d) + "\\u007f" +
                        "\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085\\u0086\\u0087" +
                        "\\u0088\\u0089\\u008a\\u008b\\u008c\\u008d\\u008e\\u008f" +
                        "\\u0090\\u0091\\u0092\\u0093\\u0094\\u0095\\u0096\\u0097" +
@@ -486,6 +501,155 @@ struct TestVoxelManipulator
        }
 };
 
+struct TestVoxelAlgorithms
+{
+       void Run(INodeDefManager *ndef)
+       {
+               /*
+                       voxalgo::propagateSunlight
+               */
+               {
+                       VoxelManipulator v;
+                       for(u16 z=0; z<3; z++)
+                       for(u16 y=0; y<3; y++)
+                       for(u16 x=0; x<3; x++)
+                       {
+                               v3s16 p(x,y,z);
+                               v.setNodeNoRef(p, MapNode(CONTENT_AIR));
+                       }
+                       VoxelArea a(v3s16(0,0,0), v3s16(2,2,2));
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, true, light_sources, ndef);
+                               //v.print(dstream, ndef, VOXELPRINT_LIGHT_DAY);
+                               assert(res.bottom_sunlight_valid == true);
+                               assert(v.getNode(v3s16(1,1,1)).getLight(LIGHTBANK_DAY, ndef)
+                                               == LIGHT_SUN);
+                       }
+                       v.setNodeNoRef(v3s16(0,0,0), MapNode(CONTENT_STONE));
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, true, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == true);
+                               assert(v.getNode(v3s16(1,1,1)).getLight(LIGHTBANK_DAY, ndef)
+                                               == LIGHT_SUN);
+                       }
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, false, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == true);
+                               assert(v.getNode(v3s16(2,0,2)).getLight(LIGHTBANK_DAY, ndef)
+                                               == 0);
+                       }
+                       v.setNodeNoRef(v3s16(1,3,2), MapNode(CONTENT_STONE));
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, true, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == true);
+                               assert(v.getNode(v3s16(1,1,2)).getLight(LIGHTBANK_DAY, ndef)
+                                               == 0);
+                       }
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, false, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == true);
+                               assert(v.getNode(v3s16(1,0,2)).getLight(LIGHTBANK_DAY, ndef)
+                                               == 0);
+                       }
+                       {
+                               MapNode n(CONTENT_AIR);
+                               n.setLight(LIGHTBANK_DAY, 10, ndef);
+                               v.setNodeNoRef(v3s16(1,-1,2), n);
+                       }
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, true, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == true);
+                       }
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, false, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == true);
+                       }
+                       {
+                               MapNode n(CONTENT_AIR);
+                               n.setLight(LIGHTBANK_DAY, LIGHT_SUN, ndef);
+                               v.setNodeNoRef(v3s16(1,-1,2), n);
+                       }
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, true, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == false);
+                       }
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, false, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == false);
+                       }
+                       v.setNodeNoRef(v3s16(1,3,2), MapNode(CONTENT_IGNORE));
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               voxalgo::setLight(v, a, 0, ndef);
+                               voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
+                                               v, a, true, light_sources, ndef);
+                               assert(res.bottom_sunlight_valid == true);
+                       }
+               }
+               /*
+                       voxalgo::clearLightAndCollectSources
+               */
+               {
+                       VoxelManipulator v;
+                       for(u16 z=0; z<3; z++)
+                       for(u16 y=0; y<3; y++)
+                       for(u16 x=0; x<3; x++)
+                       {
+                               v3s16 p(x,y,z);
+                               v.setNode(p, MapNode(CONTENT_AIR));
+                       }
+                       VoxelArea a(v3s16(0,0,0), v3s16(2,2,2));
+                       v.setNodeNoRef(v3s16(0,0,0), MapNode(CONTENT_STONE));
+                       v.setNodeNoRef(v3s16(1,1,1), MapNode(CONTENT_TORCH));
+                       {
+                               MapNode n(CONTENT_AIR);
+                               n.setLight(LIGHTBANK_DAY, 1, ndef);
+                               v.setNode(v3s16(1,1,2), n);
+                       }
+                       {
+                               core::map<v3s16, bool> light_sources;
+                               core::map<v3s16, u8> unlight_from;
+                               voxalgo::clearLightAndCollectSources(v, a, LIGHTBANK_DAY,
+                                               ndef, light_sources, unlight_from);
+                               //v.print(dstream, ndef, VOXELPRINT_LIGHT_DAY);
+                               assert(v.getNode(v3s16(0,1,1)).getLight(LIGHTBANK_DAY, ndef)
+                                               == 0);
+                               assert(light_sources.find(v3s16(1,1,1)) != NULL);
+                               assert(light_sources.size() == 1);
+                               assert(unlight_from.find(v3s16(1,1,2)) != NULL);
+                               assert(unlight_from.size() == 1);
+                       }
+               }
+       }
+};
+
 /*
        NOTE: These tests became non-working then NodeContainer was removed.
              These should be redone, utilizing some kind of a virtual
@@ -1193,8 +1357,10 @@ struct TestConnection
 
                        infostream<<"Sending data (size="<<datasize<<"):";
                        for(int i=0; i<datasize && i<20; i++){
-                               if(i%2==0) DEBUGPRINT(" ");
-                               DEBUGPRINT("%.2X", ((int)((const char*)*data1)[i])&0xff);
+                               if(i%2==0) infostream<<" ";
+                               char buf[10];
+                               snprintf(buf, 10, "%.2X", ((int)((const char*)*data1)[i])&0xff);
+                               infostream<<buf;
                        }
                        if(datasize>20)
                                infostream<<"...";
@@ -1202,7 +1368,7 @@ struct TestConnection
                        
                        server.Send(peer_id_client, 0, data1, true);
 
-                       sleep_ms(3000);
+                       //sleep_ms(3000);
                        
                        SharedBuffer<u8> recvdata;
                        infostream<<"** running client.Receive()"<<std::endl;
@@ -1211,7 +1377,7 @@ struct TestConnection
                        bool received = false;
                        u32 timems0 = porting::getTimeMs();
                        for(;;){
-                               if(porting::getTimeMs() - timems0 > 5000)
+                               if(porting::getTimeMs() - timems0 > 5000 || received)
                                        break;
                                try{
                                        size = client.Receive(peer_id, recvdata);
@@ -1225,10 +1391,12 @@ struct TestConnection
                                        <<", size="<<size
                                        <<std::endl;
 
-                       infostream<<"Received data (size="<<size<<"):";
+                       infostream<<"Received data (size="<<size<<"): ";
                        for(int i=0; i<size && i<20; i++){
-                               if(i%2==0) DEBUGPRINT(" ");
-                               DEBUGPRINT("%.2X", ((int)(recvdata[i]))&0xff);
+                               if(i%2==0) infostream<<" ";
+                               char buf[10];
+                               snprintf(buf, 10, "%.2X", ((int)(recvdata[i]))&0xff);
+                               infostream<<buf;
                        }
                        if(size>20)
                                infostream<<"...";
@@ -1278,6 +1446,7 @@ void run_tests()
        TEST(TestSerialization);
        TESTPARAMS(TestMapNode, ndef);
        TESTPARAMS(TestVoxelManipulator, ndef);
+       TESTPARAMS(TestVoxelAlgorithms, ndef);
        //TEST(TestMapBlock);
        //TEST(TestMapSector);
        if(INTERNET_SIMULATOR == false){