#include "environment.h"
#include "collision.h"
#include "raycast.h"
-#include "serverobject.h"
#include "scripting_server.h"
#include "server.h"
#include "daynightratio.h"
m_cache_active_block_mgmt_interval = g_settings->getFloat("active_block_mgmt_interval");
m_cache_abm_interval = g_settings->getFloat("abm_interval");
m_cache_nodetimer_interval = g_settings->getFloat("nodetimer_interval");
+ m_cache_abm_time_budget = g_settings->getFloat("abm_time_budget");
m_time_of_day = g_settings->getU32("world_start_time");
m_time_of_day_f = (float)m_time_of_day / 24000.0f;
u32 Environment::getDayNightRatio()
{
MutexAutoLock lock(this->m_time_lock);
+ if (g_settings->getBool("no_night"))
+ return time_to_daynight_ratio(12000, m_cache_enable_shaders);
if (m_enable_day_night_ratio_override)
return m_day_night_ratio_override;
return time_to_daynight_ratio(m_time_of_day_f * 24000, m_cache_enable_shaders);
return m_time_of_day_f;
}
+bool Environment::line_of_sight(v3f pos1, v3f pos2, v3s16 *p)
+{
+ // Iterate trough nodes on the line
+ voxalgo::VoxelLineIterator iterator(pos1 / BS, (pos2 - pos1) / BS);
+ do {
+ MapNode n = getMap().getNode(iterator.m_current_node_pos);
+
+ // Return non-air
+ if (n.param0 != CONTENT_AIR) {
+ if (p)
+ *p = iterator.m_current_node_pos;
+ return false;
+ }
+ iterator.next();
+ } while (iterator.m_current_index <= iterator.m_last_index);
+ return true;
+}
+
/*
Check if a node is pointable
*/
inline static bool isPointableNode(const MapNode &n,
- INodeDefManager *nodedef , bool liquids_pointable)
+ const NodeDefManager *nodedef , bool liquids_pointable, bool nodes_pointable)
{
+ if (! nodes_pointable)
+ return false;
const ContentFeatures &features = nodedef->get(n);
return features.pointable ||
- (liquids_pointable && features.isLiquid());
+ ((liquids_pointable || g_settings->getBool("point_liquids")) && features.isLiquid());
}
void Environment::continueRaycast(RaycastState *state, PointedThing *result)
{
- INodeDefManager *nodedef = getMap().getNodeDefManager();
+ const NodeDefManager *nodedef = getMap().getNodeDefManager();
if (state->m_initialization_needed) {
// Add objects
if (state->m_objects_pointable) {
new_nodes.MaxEdge.Z = new_nodes.MinEdge.Z;
}
+ if (new_nodes.MaxEdge.X == S16_MAX ||
+ new_nodes.MaxEdge.Y == S16_MAX ||
+ new_nodes.MaxEdge.Z == S16_MAX) {
+ break; // About to go out of bounds
+ }
+
// For each untested node
for (s16 x = new_nodes.MinEdge.X; x <= new_nodes.MaxEdge.X; x++)
for (s16 y = new_nodes.MinEdge.Y; y <= new_nodes.MaxEdge.Y; y++)
v3s16 np(x, y, z);
bool is_valid_position;
- n = map.getNodeNoEx(np, &is_valid_position);
+ n = map.getNode(np, &is_valid_position);
if (!(is_valid_position && isPointableNode(n, nodedef,
- state->m_liquids_pointable))) {
+ state->m_liquids_pointable, state->m_nodes_pointable))) {
continue;
}
bool is_colliding = false;
// Minimal distance of all collisions
float min_distance_sq = 10000000;
+ // ID of the current box (loop counter)
+ u16 id = 0;
v3f npf = intToFloat(np, BS);
- for (std::vector<aabb3f>::const_iterator i = boxes.begin();
- i != boxes.end(); ++i) {
- // Get current collision box
- aabb3f box = *i;
+ // This loop translates the boxes to their in-world place.
+ for (aabb3f &box : boxes) {
box.MinEdge += npf;
box.MaxEdge += npf;
v3s16 intersection_normal;
if (!boxLineCollision(box, state->m_shootline.start,
state->m_shootline.getVector(), &intersection_point,
- &intersection_normal))
+ &intersection_normal)) {
+ ++id;
continue;
+ }
f32 distanceSq = (intersection_point
- state->m_shootline.start).getLengthSQ();
min_distance_sq = distanceSq;
result.intersection_point = intersection_point;
result.intersection_normal = intersection_normal;
+ result.box_id = id;
found_boxcenter = box.getCenter();
is_colliding = true;
}
+ ++id;
}
// If there wasn't a collision, stop
if (!is_colliding) {