#include <algorithm>
#include <cmath>
#include "client/shader.h"
+#include "script/scripting_client.h"
class Settings;
struct ToolCapabilities;
matrix.setTextureScale(txs, tys);
}
+// Evaluate transform chain recursively; irrlicht does not do this for us
+static void updatePositionRecursive(scene::ISceneNode *node)
+{
+ scene::ISceneNode *parent = node->getParent();
+ if (parent)
+ updatePositionRecursive(parent);
+ node->updateAbsolutePosition();
+}
+
/*
TestCAO
*/
u16 indices[] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
// Set material
- buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
+ buf->getMaterial().setFlag(video::EMF_LIGHTING, true); // false
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture(0, tsrc->getTextureForMesh("rat.png"));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
ClientActiveObject *parent = m_env->getActiveObject(parent_id);
if (parent_id != old_parent) {
+ if (old_parent)
+ m_waiting_for_reattach = 10;
if (auto *o = m_env->getActiveObject(old_parent))
o->removeAttachmentChild(m_id);
if (parent)
parent->addAttachmentChild(m_id);
}
-
-
+
updateAttachments();
}
if (m_enable_shaders) {
IShaderSource *shader_source = m_client->getShaderSource();
- u32 shader_id = shader_source->getShader(
- "object_shader",
- (m_prop.use_texture_alpha) ? TILE_MATERIAL_ALPHA : TILE_MATERIAL_BASIC,
- NDT_NORMAL);
+ MaterialType material_type;
+
+ if (m_prop.shaded && m_prop.glow == 0)
+ material_type = (m_prop.use_texture_alpha) ?
+ TILE_MATERIAL_ALPHA : TILE_MATERIAL_BASIC;
+ else
+ material_type = (m_prop.use_texture_alpha) ?
+ TILE_MATERIAL_PLAIN_ALPHA : TILE_MATERIAL_PLAIN;
+
+ u32 shader_id = shader_source->getShader("object_shader", material_type, NDT_NORMAL);
m_material_type = shader_source->getShaderInfo(shader_id).material;
} else {
m_material_type = (m_prop.use_texture_alpha) ?
}
void GenericCAO::updateLight(u32 day_night_ratio)
-{
+{
if (m_glow < 0)
return;
u8 light_at_pos = 0;
bool pos_ok = false;
+ if (g_settings->getBool("fullbright"))
+ light_at_pos = 255;
+
v3s16 pos[3];
u16 npos = getLightPosition(pos);
for (u16 i = 0; i < npos; i++) {
void GenericCAO::updateNametag()
{
- if (m_is_local_player) // No nametag for local player
+ if (m_is_local_player && ! g_settings->getBool("freecam")) // No nametag for local player
return;
if (m_prop.nametag.empty()) {
void GenericCAO::step(float dtime, ClientEnvironment *env)
{
- if (m_animated_meshnode) {
- m_animated_meshnode->animateJoints();
- updateBonePosition();
- }
-
// Handle model animations and update positions instantly to prevent lags
if (m_is_local_player) {
LocalPlayer *player = m_env->getLocalPlayer();
- m_position = player->getPosition();
+ m_position = player->getLegitPosition();
pos_translator.val_current = m_position;
- m_rotation.Y = wrapDegrees_0_360(player->getYaw());
- rot_translator.val_current = m_rotation;
+ if (! g_settings->getBool("freecam")) {
+ m_rotation.Y = wrapDegrees_0_360(player->getYaw());
+ rot_translator.val_current = m_rotation;
+ }
if (m_is_visible) {
int old_anim = player->last_animation;
const PlayerControl &controls = player->getPlayerControl();
bool walking = false;
- if (controls.up || controls.down || controls.left || controls.right ||
+ if ((controls.up || controls.down || controls.left || controls.right ||
controls.forw_move_joystick_axis != 0.f ||
- controls.sidew_move_joystick_axis != 0.f)
+ controls.sidew_move_joystick_axis != 0.f) && ! g_settings->getBool("freecam"))
walking = true;
f32 new_speed = player->local_animation_speed;
m_client->checkLocalPrivilege("fly"))))
new_speed *= 1.5;
// slowdown speed if sneeking
- if (controls.sneak && walking)
+ if (controls.sneak && walking && ! g_settings->getBool("no_slow"))
new_speed /= 2;
if (walking && (controls.LMB || controls.RMB)) {
rot_translator.val_current = m_rotation;
updateNodePos();
}
+
+ if (m_animated_meshnode) {
+ // Everything must be updated; the whole transform
+ // chain as well as the animated mesh node.
+ // Otherwise, bone attachments would be relative to
+ // a position that's one frame old.
+ if (m_matrixnode)
+ updatePositionRecursive(m_matrixnode);
+ m_animated_meshnode->updateAbsolutePosition();
+ m_animated_meshnode->animateJoints();
+ updateBonePosition();
+ }
}
void GenericCAO::updateTexturePos()
bone->updateAbsolutePosition();
}
}
+ // The following is needed for set_bone_pos to propagate to
+ // attached objects correctly.
+ // Irrlicht ought to do this, but doesn't when using EJUOR_CONTROL.
+ for (u32 i = 0; i < m_animated_meshnode->getJointCount(); ++i) {
+ auto bone = m_animated_meshnode->getJointNode(i);
+ // Look for the root bone.
+ if (bone && bone->getParent() == m_animated_meshnode) {
+ // Update entire skeleton.
+ bone->updateAbsolutePositionOfAllChildren();
+ break;
+ }
+ }
}
void GenericCAO::updateAttachments()
* - glow: handled by updateLight()
* - any other properties that do not change appearance
*/
+
+ bool uses_legacy_texture = new_.wield_item.empty() &&
+ (new_.visual == "wielditem" || new_.visual == "item");
// Ordered to compare primitive types before std::vectors
return old.backface_culling != new_.backface_culling ||
old.is_visible != new_.is_visible ||
old.mesh != new_.mesh ||
+ old.shaded != new_.shaded ||
old.use_texture_alpha != new_.use_texture_alpha ||
old.visual != new_.visual ||
old.visual_size != new_.visual_size ||
old.wield_item != new_.wield_item ||
- old.colors != new_.colors;
+ old.colors != new_.colors ||
+ (uses_legacy_texture && old.textures != new_.textures);
}
void GenericCAO::processMessage(const std::string &data)
if(m_is_local_player)
{
+ Client *client = m_env->getGameDef();
+
+ if (client->modsLoaded() && client->getScript()->on_recieve_physics_override(override_speed, override_jump, override_gravity, sneak, sneak_glitch, new_move))
+ return;
+
LocalPlayer *player = m_env->getLocalPlayer();
player->physics_override_speed = override_speed;
player->physics_override_jump = override_jump;