/* Minetest Copyright (C) 2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "irrlichttypes_extrabloated.h" #include "mapnode.h" #include "porting.h" #include "main.h" // For g_settings #include "nodedef.h" #include "content_mapnode.h" // For mapnode_translate_*_internal #include "serialization.h" // For ser_ver_supported #include "util/serialize.h" #include "log.h" #include #include static const Rotation wallmounted_to_rot[] = { ROTATE_0, ROTATE_180, ROTATE_90, ROTATE_270 }; static const u8 rot_to_wallmounted[] = { 2, 4, 3, 5 }; /* MapNode */ // Create directly from a nodename // If name is unknown, sets CONTENT_IGNORE MapNode::MapNode(INodeDefManager *ndef, const std::string &name, u8 a_param1, u8 a_param2) { content_t id = CONTENT_IGNORE; ndef->getId(name, id); param0 = id; param1 = a_param1; param2 = a_param2; } void MapNode::setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr) { // If node doesn't contain light data, ignore this if(nodemgr->get(*this).param_type != CPT_LIGHT) return; if(bank == LIGHTBANK_DAY) { param1 &= 0xf0; param1 |= a_light & 0x0f; } else if(bank == LIGHTBANK_NIGHT) { param1 &= 0x0f; param1 |= (a_light & 0x0f)<<4; } else assert(0); } u8 MapNode::getLight(enum LightBank bank, INodeDefManager *nodemgr) const { // Select the brightest of [light source, propagated light] const ContentFeatures &f = nodemgr->get(*this); u8 light = 0; if(f.param_type == CPT_LIGHT) { if(bank == LIGHTBANK_DAY) light = param1 & 0x0f; else if(bank == LIGHTBANK_NIGHT) light = (param1>>4)&0x0f; else assert(0); } if(f.light_source > light) light = f.light_source; return light; } bool MapNode::getLightBanks(u8 &lightday, u8 &lightnight, INodeDefManager *nodemgr) const { // Select the brightest of [light source, propagated light] const ContentFeatures &f = nodemgr->get(*this); if(f.param_type == CPT_LIGHT) { lightday = param1 & 0x0f; lightnight = (param1>>4)&0x0f; } else { lightday = 0; lightnight = 0; } if(f.light_source > lightday) lightday = f.light_source; if(f.light_source > lightnight) lightnight = f.light_source; return f.param_type == CPT_LIGHT || f.light_source != 0; } u8 MapNode::getFaceDir(INodeDefManager *nodemgr) const { const ContentFeatures &f = nodemgr->get(*this); if(f.param_type_2 == CPT2_FACEDIR) return getParam2() & 0x1F; return 0; } u8 MapNode::getWallMounted(INodeDefManager *nodemgr) const { const ContentFeatures &f = nodemgr->get(*this); if(f.param_type_2 == CPT2_WALLMOUNTED) return getParam2() & 0x07; return 0; } v3s16 MapNode::getWallMountedDir(INodeDefManager *nodemgr) const { switch(getWallMounted(nodemgr)) { case 0: default: return v3s16(0,1,0); case 1: return v3s16(0,-1,0); case 2: return v3s16(1,0,0); case 3: return v3s16(-1,0,0); case 4: return v3s16(0,0,1); case 5: return v3s16(0,0,-1); } } void MapNode::rotateAlongYAxis(INodeDefManager *nodemgr, Rotation rot) { ContentParamType2 cpt2 = nodemgr->get(*this).param_type_2; if (cpt2 == CPT2_FACEDIR) { u8 newrot = param2 & 3; param2 &= ~3; param2 |= (newrot + rot) & 3; } else if (cpt2 == CPT2_WALLMOUNTED) { u8 wmountface = (param2 & 7); if (wmountface <= 1) return; Rotation oldrot = wallmounted_to_rot[wmountface - 2]; param2 &= ~7; param2 |= rot_to_wallmounted[(oldrot - rot) & 3]; } } static std::vector transformNodeBox(const MapNode &n, const NodeBox &nodebox, INodeDefManager *nodemgr) { std::vector boxes; if(nodebox.type == NODEBOX_FIXED || nodebox.type == NODEBOX_LEVELED) { const std::vector &fixed = nodebox.fixed; int facedir = n.getFaceDir(nodemgr); u8 axisdir = facedir>>2; facedir&=0x03; for(std::vector::const_iterator i = fixed.begin(); i != fixed.end(); i++) { aabb3f box = *i; if (nodebox.type == NODEBOX_LEVELED) { box.MaxEdge.Y = -BS/2 + BS*((float)1/LEVELED_MAX) * n.getLevel(nodemgr); } switch (axisdir) { case 0: if(facedir == 1) { box.MinEdge.rotateXZBy(-90); box.MaxEdge.rotateXZBy(-90); } else if(facedir == 2) { box.MinEdge.rotateXZBy(180); box.MaxEdge.rotateXZBy(180); } else if(facedir == 3) { box.MinEdge.rotateXZBy(90); box.MaxEdge.rotateXZBy(90); } break; case 1: // z+ box.MinEdge.rotateYZBy(90); box.MaxEdge.rotateYZBy(90); if(facedir == 1) { box.MinEdge.rotateXYBy(90); box.MaxEdge.rotateXYBy(90); } else if(facedir == 2) { box.MinEdge.rotateXYBy(180); box.MaxEdge.rotateXYBy(180); } else if(facedir == 3) { box.MinEdge.rotateXYBy(-90); box.MaxEdge.rotateXYBy(-90); } break; case 2: //z- box.MinEdge.rotateYZBy(-90); box.MaxEdge.rotateYZBy(-90); if(facedir == 1) { box.MinEdge.rotateXYBy(-90); box.MaxEdge.rotateXYBy(-90); } else if(facedir == 2) { box.MinEdge.rotateXYBy(180); box.MaxEdge.rotateXYBy(180); } else if(facedir == 3) { box.MinEdge.rotateXYBy(90); box.MaxEdge.rotateXYBy(90); } break; case 3: //x+ box.MinEdge.rotateXYBy(-90); box.MaxEdge.rotateXYBy(-90); if(facedir == 1) { box.MinEdge.rotateYZBy(90); box.MaxEdge.rotateYZBy(90); } else if(facedir == 2) { box.MinEdge.rotateYZBy(180); box.MaxEdge.rotateYZBy(180); } else if(facedir == 3) { box.MinEdge.rotateYZBy(-90); box.MaxEdge.rotateYZBy(-90); } break; case 4: //x- box.MinEdge.rotateXYBy(90); box.MaxEdge.rotateXYBy(90); if(facedir == 1) { box.MinEdge.rotateYZBy(-90); box.MaxEdge.rotateYZBy(-90); } else if(facedir == 2) { box.MinEdge.rotateYZBy(180); box.MaxEdge.rotateYZBy(180); } else if(facedir == 3) { box.MinEdge.rotateYZBy(90); box.MaxEdge.rotateYZBy(90); } break; case 5: box.MinEdge.rotateXYBy(-180); box.MaxEdge.rotateXYBy(-180); if(facedir == 1) { box.MinEdge.rotateXZBy(90); box.MaxEdge.rotateXZBy(90); } else if(facedir == 2) { box.MinEdge.rotateXZBy(180); box.MaxEdge.rotateXZBy(180); } else if(facedir == 3) { box.MinEdge.rotateXZBy(-90); box.MaxEdge.rotateXZBy(-90); } break; default: break; } box.repair(); boxes.push_back(box); } } else if(nodebox.type == NODE/* Minetest Copyright (C) 2016 sfan5 <sfan5@live.de> This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "test.h" #include <string> #include "exceptions.h" #include "keycode.h" class TestKeycode : public TestBase { public: TestKeycode() { TestManager::registerTestModule(this); } const char *getName() { return "TestKeycode"; } void runTests(IGameDef *gamedef); void testCreateFromString(); void testCreateFromSKeyInput(); void testCompare(); }; static TestKeycode g_test_instance; void TestKeycode::runTests(IGameDef *gamedef) { TEST(testCreateFromString); TEST(testCreateFromSKeyInput); TEST(testCompare); } //////////////////////////////////////////////////////////////////////////////// #define UASSERTEQ_STR(one, two) UASSERT(strcmp(one, two) == 0) void TestKeycode::testCreateFromString() { KeyPress k; // Character key, from char k = KeyPress("R"); UASSERTEQ_STR(k.sym(), "KEY_KEY_R"); UASSERTCMP(int, >, strlen(k.name()), 0); // should have human description // Character key, from identifier k = KeyPress("KEY_KEY_B"); UASSERTEQ_STR(k.sym(), "KEY_KEY_B"); UASSERTCMP(int, >, strlen(k.name()), 0); // Non-Character key, from identifier k = KeyPress("KEY_UP"); UASSERTEQ_STR(k.sym(), "KEY_UP"); UASSERTCMP(int, >, strlen(k.name()), 0); k = KeyPress("KEY_F6"); UASSERTEQ_STR(k.sym(), "KEY_F6"); UASSERTCMP(int, >, strlen(k.name()), 0); // Irrlicht-unknown key, from char k = KeyPress("/"); UASSERTEQ_STR(k.sym(), "/"); UASSERTCMP(int, >, strlen(k.name()), 0); } void TestKeycode::testCreateFromSKeyInput() { KeyPress k; irr::SEvent::SKeyInput in; // Character key in.Key = irr::KEY_KEY_3;<