/*
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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 "localplayer.h"
#include "event.h"
#include "collision.h"
#include "nodedef.h"
#include "settings.h"
#include "environment.h"
#include "map.h"
#include "client.h"
/*
LocalPlayer
*/
LocalPlayer::LocalPlayer(Client *client, const char *name):
Player(name, client->idef()),
parent(0),
hp(PLAYER_MAX_HP),
got_teleported(false),
isAttached(false),
touching_ground(false),
in_liquid(false),
in_liquid_stable(false),
liquid_viscosity(0),
is_climbing(false),
swimming_vertical(false),
// Movement overrides are multipliers and must be 1 by default
physics_override_speed(1.0f),
physics_override_jump(1.0f),
physics_override_gravity(1.0f),
physics_override_sneak(true),
physics_override_sneak_glitch(true),
physics_override_new_move(true), // Temporary option for old move code
overridePosition(v3f(0,0,0)),
last_position(v3f(0,0,0)),
last_speed(v3f(0,0,0)),
last_pitch(0),
last_yaw(0),
last_keyPressed(0),
last_camera_fov(0),
last_wanted_range(0),
camera_impact(0.f),
last_animation(NO_ANIM),
hotbar_image(""),
hotbar_selected_image(""),
light_color(255,255,255,255),
hurt_tilt_timer(0.0f),
hurt_tilt_strength(0.0f),
m_position(0,0,0),
m_sneak_node(32767,32767,32767),
m_sneak_node_bb_ymax(0), // To support temporary option for old move code
m_sneak_node_bb_top(0,0,0,0,0,0),
m_sneak_node_exists(false),
m_need_to_get_new_sneak_node(true),
m_sneak_ladder_detected(false),
m_ledge_detected(false),
m_old_node_below(32767,32767,32767),
m_old_node_below_type("air"),
m_can_jump(false),
m_breath(PLAYER_MAX_BREATH),
m_yaw(0),
m_pitch(0),
camera_barely_in_ceiling(false),
m_collisionbox(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30),
m_cao(NULL),
m_client(client)
{
// Initialize hp to 0, so that no hearts will be shown if server
// doesn't support health points
hp = 0;
eye_offset_first = v3f(0,0,0);
eye_offset_third = v3f(0,0,0);
}
LocalPlayer::~LocalPlayer()
{
}
static aabb3f getTopBoundingBox(const std::vector<aabb3f> &nodeboxes)
{
aabb3f b_max;
b_max.reset(-BS, -BS, -BS);
for (std::vector<aabb3f>::const_iterator it = nodeboxes.begin();
it != nodeboxes.end(); ++it) {
aabb3f box = *it;
if (box.MaxEdge.Y > b_max.MaxEdge.Y)
b_max = box;
else if (box.MaxEdge.Y == b_max.MaxEdge.Y)
b_max.addInternalBox(box);
}
return aabb3f(v3f(b_max.MinEdge.X, b_max.MaxEdge.Y, b_max.MinEdge.Z), b_max.MaxEdge);
}
#define GETNODE(map, p3, v2, y, valid) \
(map)->getNodeNoEx((p3) + v3s16((v2).X, y, (v2).Y), valid)
// pos is the node the player is standing inside(!)
static bool detectSneakLadder(Map *map, INodeDefManager *nodemgr, v3s16 pos)
{
// Detects a structure known as "sneak ladder" or "sneak elevator"
// that relies on bugs to provide a fast means of vertical transportation,
// the bugs have since been fixed but this function remains to keep it working.
// NOTE: This is just entirely a huge hack and causes way too many problems.
bool is_valid_position;
MapNode node;
// X/Z vectors for 4 neighboring nodes
static const v2s16 vecs[] = { v2s16(-1, 0), v2s16(1, 0), v2s16(0, -1), v2s16(0, 1) };
for (u16 i = 0; i < ARRLEN(vecs); i++) {
const v2s16 vec = vecs[i];
// walkability of bottom & top node should differ
node = GETNODE(map, pos, vec, 0, &is_valid_position);
if (!is_valid_position)
continue;
|