#include "main.h" // For g_settings
#include "settings.h"
#include "nodedef.h"
+#include "collision.h"
#include "environment.h"
#include "gamedef.h"
-#include "content_sao.h"
-#include "tooldef.h"
-#include "materials.h"
Player::Player(IGameDef *gamedef):
touching_ground(false),
in_water_stable(false),
is_climbing(false),
swimming_up(false),
+ inventory(gamedef->idef()),
inventory_backup(NULL),
- craftresult_is_preview(true),
hp(20),
peer_id(PEER_ID_INEXISTENT),
// protected
m_gamedef(gamedef),
- m_selected_item(0),
m_pitch(0),
m_yaw(0),
m_speed(0,0,0),
delete inventory_backup;
}
-void Player::wieldItem(u16 item)
-{
- m_selected_item = item;
-}
-
void Player::resetInventory()
{
inventory.clear();
inventory.addList("main", PLAYER_INVENTORY_SIZE);
inventory.addList("craft", 9);
+ inventory.addList("craftpreview", 1);
inventory.addList("craftresult", 1);
}
args.setFloat("pitch", m_pitch);
args.setFloat("yaw", m_yaw);
args.setV3F("position", m_position);
- args.setBool("craftresult_is_preview", craftresult_is_preview);
args.setS32("hp", hp);
args.writeLines(os);
setPitch(args.getFloat("pitch"));
setYaw(args.getFloat("yaw"));
setPosition(args.getV3F("position"));
- try{
- craftresult_is_preview = args.getBool("craftresult_is_preview");
- }catch(SettingNotFoundException &e){
- craftresult_is_preview = true;
- }
try{
hp = args.getS32("hp");
}catch(SettingNotFoundException &e){
hp = 20;
}
- inventory.deSerialize(is, m_gamedef);
-}
-
-/*
- ServerRemotePlayer
-*/
-
-ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
- Player(env->getGameDef()),
- ServerActiveObject(env, v3f(0,0,0)),
- m_last_good_position(0,0,0),
- m_last_good_position_age(0),
- m_additional_items(),
- m_inventory_not_sent(false),
- m_hp_not_sent(false),
- m_respawn_active(false),
- m_is_in_environment(false),
- m_position_not_sent(false)
-{
-}
-ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
- const char *name_):
- Player(env->getGameDef()),
- ServerActiveObject(env, pos_),
- m_inventory_not_sent(false),
- m_hp_not_sent(false),
- m_is_in_environment(false),
- m_position_not_sent(false)
-{
- setPosition(pos_);
- peer_id = peer_id_;
- updateName(name_);
-}
-ServerRemotePlayer::~ServerRemotePlayer()
-{
- clearAddToInventoryLater();
-}
-
-void ServerRemotePlayer::setPosition(const v3f &position)
-{
- Player::setPosition(position);
- ServerActiveObject::setBasePosition(position);
- m_position_not_sent = true;
-}
-
-InventoryItem* ServerRemotePlayer::getWieldedItem()
-{
- InventoryList *list = inventory.getList("main");
- if (list)
- return list->getItem(m_selected_item);
- return NULL;
-}
-
-/* ServerActiveObject interface */
-
-void ServerRemotePlayer::addedToEnvironment()
-{
- assert(!m_is_in_environment);
- m_is_in_environment = true;
-}
-
-void ServerRemotePlayer::removingFromEnvironment()
-{
- assert(m_is_in_environment);
- m_is_in_environment = false;
-}
-
-void ServerRemotePlayer::step(float dtime, bool send_recommended)
-{
- if(send_recommended == false)
- return;
-
- if(m_position_not_sent)
- {
- m_position_not_sent = false;
-
- std::ostringstream os(std::ios::binary);
- // command (0 = update position)
- writeU8(os, 0);
- // pos
- writeV3F1000(os, getPosition());
- // yaw
- writeF1000(os, getYaw());
- // create message and add to list
- ActiveObjectMessage aom(getId(), false, os.str());
- m_messages_out.push_back(aom);
- }
-}
-
-std::string ServerRemotePlayer::getClientInitializationData()
-{
- std::ostringstream os(std::ios::binary);
- // version
- writeU8(os, 0);
- // name
- os<<serializeString(getName());
- // pos
- writeV3F1000(os, getPosition());
- // yaw
- writeF1000(os, getYaw());
- return os.str();
-}
-
-std::string ServerRemotePlayer::getStaticData()
-{
- assert(0);
- return "";
-}
-
-void ServerRemotePlayer::punch(ServerActiveObject *puncher,
- float time_from_last_punch)
-{
- if(!puncher)
- return;
-
- // "Material" properties of a player
- MaterialProperties mp;
- mp.diggability = DIGGABLE_NORMAL;
- mp.crackiness = -1.0;
- mp.cuttability = 1.0;
-
- ToolDiggingProperties tp;
- puncher->getWieldDiggingProperties(&tp);
-
- HittingProperties hitprop = getHittingProperties(&mp, &tp,
- time_from_last_punch);
-
- infostream<<"1. getHP()="<<getHP()<<std::endl;
- setHP(getHP() - hitprop.hp);
- infostream<<"2. getHP()="<<getHP()<<std::endl;
- puncher->damageWieldedItem(hitprop.wear);
-}
-
-void ServerRemotePlayer::rightClick(ServerActiveObject *clicker)
-{
-}
-
-void ServerRemotePlayer::setPos(v3f pos)
-{
- setPosition(pos);
- // Movement caused by this command is always valid
- m_last_good_position = pos;
- m_last_good_position_age = 0;
-}
-void ServerRemotePlayer::moveTo(v3f pos, bool continuous)
-{
- setPosition(pos);
- // Movement caused by this command is always valid
- m_last_good_position = pos;
- m_last_good_position_age = 0;
-}
-
-void ServerRemotePlayer::getWieldDiggingProperties(ToolDiggingProperties *dst)
-{
- IGameDef *gamedef = m_env->getGameDef();
- IToolDefManager *tdef = gamedef->tdef();
-
- InventoryItem *item = getWieldedItem();
- if(item == NULL || std::string(item->getName()) != "ToolItem"){
- *dst = ToolDiggingProperties();
- return;
- }
- ToolItem *titem = (ToolItem*)item;
- *dst = tdef->getDiggingProperties(titem->getToolName());
-}
-
-void ServerRemotePlayer::damageWieldedItem(u16 amount)
-{
- infostream<<"Damaging "<<getName()<<"'s wielded item for amount="
- <<amount<<std::endl;
- InventoryList *list = inventory.getList("main");
- if(!list)
- return;
- InventoryItem *item = list->getItem(m_selected_item);
- if(item && (std::string)item->getName() == "ToolItem"){
- ToolItem *titem = (ToolItem*)item;
- bool weared_out = titem->addWear(amount);
- if(weared_out)
- list->deleteItem(m_selected_item);
- }
-}
-bool ServerRemotePlayer::addToInventory(InventoryItem *item)
-{
- infostream<<"Adding "<<item->getName()<<" into "<<getName()
- <<"'s inventory"<<std::endl;
-
- InventoryList *ilist = inventory.getList("main");
- if(ilist == NULL)
- return false;
-
- // In creative mode, just delete the item
- if(g_settings->getBool("creative_mode")){
- return false;
- }
+ inventory.deSerialize(is);
- // Skip if inventory has no free space
- if(ilist->roomForItem(item) == false)
+ if(inventory.getList("craftpreview") == NULL)
{
- infostream<<"Player inventory has no free space"<<std::endl;
- return false;
- }
-
- // Add to inventory
- InventoryItem *leftover = ilist->addItem(item);
- assert(!leftover);
-
- m_inventory_not_sent = true;
+ // Convert players without craftpreview
+ inventory.addList("craftpreview", 1);
- return true;
-}
-void ServerRemotePlayer::addToInventoryLater(InventoryItem *item)
-{
- infostream<<"Adding (later) "<<item->getName()<<" into "<<getName()
- <<"'s inventory"<<std::endl;
- m_additional_items.push_back(item);
-}
-void ServerRemotePlayer::clearAddToInventoryLater()
-{
- for (std::vector<InventoryItem*>::iterator
- i = m_additional_items.begin();
- i != m_additional_items.end(); i++)
- {
- delete *i;
- }
- m_additional_items.clear();
-}
-void ServerRemotePlayer::completeAddToInventoryLater(u16 preferred_index)
-{
- InventoryList *ilist = inventory.getList("main");
- if(ilist == NULL)
- {
- clearAddToInventoryLater();
- return;
- }
-
- // In creative mode, just delete the items
- if(g_settings->getBool("creative_mode"))
- {
- clearAddToInventoryLater();
- return;
- }
-
- for (std::vector<InventoryItem*>::iterator
- i = m_additional_items.begin();
- i != m_additional_items.end(); i++)
- {
- InventoryItem *item = *i;
- InventoryItem *leftover = item;
- leftover = ilist->addItem(preferred_index, leftover);
- leftover = ilist->addItem(leftover);
- delete leftover;
+ bool craftresult_is_preview = true;
+ if(args.exists("craftresult_is_preview"))
+ craftresult_is_preview = args.getBool("craftresult_is_preview");
+ if(craftresult_is_preview)
+ {
+ // Clear craftresult
+ inventory.getList("craftresult")->changeItem(0, ItemStack());
+ }
}
- m_additional_items.clear();
- m_inventory_not_sent = true;
-}
-void ServerRemotePlayer::setHP(s16 hp_)
-{
- s16 oldhp = hp;
-
- // FIXME: don't hardcode maximum HP, make configurable per object
- if(hp_ < 0)
- hp_ = 0;
- else if(hp_ > 20)
- hp_ = 20;
- hp = hp_;
-
- if(hp != oldhp)
- m_hp_not_sent = true;
-}
-s16 ServerRemotePlayer::getHP()
-{
- return hp;
}
#ifndef SERVER
// This should always apply, otherwise there are glitches
assert(d > pos_max_d);
- float player_radius = BS*0.35;
- float player_height = BS*1.7;
+ float player_radius = BS*0.30;
+ float player_height = BS*1.55;
// Maximum distance over border for sneaking
f32 sneak_max = BS*0.4;
}
else if(touching_ground)
{
- v3f speed = getSpeed();
/*
NOTE: The d value in move() affects jump height by
raising the height at which the jump speed is kept
at its starting value
*/
- speed.Y = 6.5*BS;
- setSpeed(speed);
+ v3f speed = getSpeed();
+ if(speed.Y >= -0.5*BS)
+ {
+ speed.Y = 6.5*BS;
+ setSpeed(speed);
+ }
}
// Use the oscillating value for getting out of water
// (so that the player doesn't fly on the surface)