Make objects visible and active across planet edges

Disable anti-cheat by default. This caused issues for players crossing the planet edges in multiplayer.
master
Jeija 2016-09-11 15:19:41 +02:00
parent f66044be43
commit 38bcb295e9
3 changed files with 90 additions and 4 deletions

View File

@ -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;

View File

@ -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");

View File

@ -512,13 +512,35 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block, u32 stamp)
void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &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;