diff --git a/src/content_cao.cpp b/src/content_cao.cpp index afe52eae..936e9887 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -1057,7 +1057,39 @@ void GenericCAO::updateNodePos() if (node) { v3s16 camera_offset = m_env->getCameraOffset(); - node->setPosition(pos_translator.vect_show - intToFloat(camera_offset, BS)); + + /* + * Planet: Since the planet is actually just a flat map that wraps around + * a seemingly spherical object, there are 9 possible minimal distances to + * the same object, because the end of the map on one side is the beginning + * of the map on the other side again. Find the minimal distance from the player + * to this object. + */ + if (!g_settings->getBool("planet_enable")) { + node->setPosition(pos_translator.vect_show - intToFloat(camera_offset, BS)); + } else { + v3s16 cam_pos_nodes = floatToInt(m_gamedef->getCamera()->getPosition(), BS); + + // Round planet circumference up to even number of mapblocks, in nodes + int planet_circumference = ceil(g_settings->getU16("planet_radius") * M_PI) * 2 * MAP_BLOCKSIZE; + + float mindist = (cam_pos_nodes - floatToInt(m_position, BS)).getLength(); + int offset_minimal_x = 0, offset_minimal_z = 0; + for (int wrapx = -1; wrapx <= 1; ++wrapx) + for (int wrapz = -1; wrapz <= 1; ++wrapz) { + float distx = cam_pos_nodes.X - (m_position.X / BS + wrapx * planet_circumference); + float distz = cam_pos_nodes.Z - (m_position.Z / BS + wrapz * planet_circumference); + float dist = sqrt(distx * distx + distz * distz); + + if (dist < mindist) { + mindist = dist; + offset_minimal_x = wrapx * planet_circumference; + offset_minimal_z = wrapz * planet_circumference; + } + } + node->setPosition(pos_translator.vect_show - intToFloat(camera_offset, BS) + v3f(offset_minimal_x * BS, 0, offset_minimal_z * BS)); + } + if (node != m_spritenode) { // rotate if not a sprite v3f rot = node->getRotation(); rot.Y = -m_yaw; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 22694072..7d709db0 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -257,7 +257,7 @@ void set_default_settings(Settings *settings) settings->setDefault("player_transfer_distance", "0"); settings->setDefault("enable_pvp", "true"); settings->setDefault("disallow_empty_password", "false"); - settings->setDefault("disable_anticheat", "false"); + settings->setDefault("disable_anticheat", "true"); settings->setDefault("enable_rollback_recording", "false"); #ifdef NDEBUG settings->setDefault("deprecated_lua_api_handling", "legacy"); diff --git a/src/environment.cpp b/src/environment.cpp index 21440fdc..2224adff 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -512,13 +512,35 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block, u32 stamp) void fillRadiusBlock(v3s16 p0, s16 r, std::set &list) { + bool planet_enable = g_settings->getBool("planet_enable"); + int planet_radius = g_settings->getU16("planet_radius"); + int planet_circumference = ceil(g_settings->getU16("planet_radius") * M_PI) * 2; + v3s16 p; for(p.X=p0.X-r; p.X<=p0.X+r; p.X++) for(p.Y=p0.Y-r; p.Y<=p0.Y+r; p.Y++) for(p.Z=p0.Z-r; p.Z<=p0.Z+r; p.Z++) { - // Set in list - list.insert(p); + // Activate blocks across planet edges, insert in list + if (planet_enable) { + v3s16 ppos = p; + if (ppos.X >= planet_circumference / 2) + ppos.X -= planet_circumference; + if (ppos.X < -planet_circumference / 2) + ppos.X += planet_circumference; + if (ppos.Z >= planet_circumference / 2) + ppos.Z -= planet_circumference; + if (ppos.Z < -planet_circumference / 2) + ppos.Z += planet_circumference; + if (ppos.Y < -planet_radius) { + ppos.Y = -planet_radius - ppos.Y; + ppos.X += planet_circumference / 2 * (ppos.X < 0 ? 1 : -1); + } + + list.insert(ppos); + } else { + list.insert(p); + } } } @@ -1652,6 +1674,9 @@ void ServerEnvironment::getAddedActiveObjects(Player *player, s16 radius, if (player_radius_f < 0) player_radius_f = 0; + bool planet_enable = g_settings->getBool("planet_enable"); + int planet_circumference = ceil(g_settings->getU16("planet_radius") * M_PI) * 2 * MAP_BLOCKSIZE * BS; + /* Go through the object list, - discard m_removed objects, @@ -1674,6 +1699,19 @@ void ServerEnvironment::getAddedActiveObjects(Player *player, s16 radius, continue; f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + + // Distances on the planet are different, calculate distance across edges + if (planet_enable) { + for (int wrapx = -1; wrapx <= 1; ++wrapx) + for (int wrapz = -1; wrapz <= 1; ++wrapz) { + float dist = object->getBasePosition().getDistanceFrom( + v3f(player->getPosition() - v3f(wrapx, 0, wrapz) * planet_circumference)); + + if (dist < distance_f) + distance_f = dist; + } + } + if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { // Discard if too far if (distance_f > player_radius_f && player_radius_f != 0) @@ -1706,6 +1744,9 @@ void ServerEnvironment::getRemovedActiveObjects(Player *player, s16 radius, if (player_radius_f < 0) player_radius_f = 0; + bool planet_enable = g_settings->getBool("planet_enable"); + int planet_circumference = ceil(g_settings->getU16("planet_radius") * M_PI) * 2 * MAP_BLOCKSIZE * BS; + /* Go through current_objects; object is removed if: - object is not found in m_active_objects (this is actually an @@ -1734,6 +1775,19 @@ void ServerEnvironment::getRemovedActiveObjects(Player *player, s16 radius, } f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + + // Distances on the planet are different, calculate distance across edges + if (planet_enable) { + for (int wrapx = -1; wrapx <= 1; ++wrapx) + for (int wrapz = -1; wrapz <= 1; ++wrapz) { + float dist = object->getBasePosition().getDistanceFrom( + v3f(player->getPosition() - v3f(wrapx, 0, wrapz) * planet_circumference)); + + if (dist < distance_f) + distance_f = dist; + } + } + if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { if (distance_f <= player_radius_f || player_radius_f == 0) continue;