Fix and tune stars
[oweals/minetest.git] / src / player.cpp
index 937ca9a3ff9f1ea3dea18129813071e78e04eeb6..40b7a249793298aefec58d9b09c429f837b2077d 100644 (file)
@@ -28,9 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #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"
 
 Player::Player(IGameDef *gamedef):
        touching_ground(false),
@@ -38,13 +38,12 @@ Player::Player(IGameDef *gamedef):
        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),
@@ -59,16 +58,12 @@ Player::~Player()
        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);
 }
 
@@ -124,7 +119,6 @@ void Player::serialize(std::ostream &os)
        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);
@@ -162,315 +156,30 @@ void Player::deSerialize(std::istream &is)
        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_sao(NULL)
-{
-}
-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_sao(NULL)
-{
-       setPosition(pos_);
-       peer_id = peer_id_;
-       updateName(name_);
-}
-ServerRemotePlayer::~ServerRemotePlayer()
-{
-       clearAddToInventoryLater();
-       if(m_sao)
-               m_sao->setPlayer(NULL);
-}
-
-void ServerRemotePlayer::setPosition(const v3f &position)
-{
-       Player::setPosition(position);
-       ServerActiveObject::setBasePosition(position);
-       if(m_sao)
-               m_sao->positionUpdated();
-}
-
-void ServerRemotePlayer::setSAO(PlayerSAO *sao)
-{
-       infostream<<"ServerRemotePlayer \""<<getName()
-                       <<"\" got sao="<<sao<<std::endl;
-       m_sao = sao;
-}
-
-PlayerSAO* ServerRemotePlayer::getSAO()
-{
-       return m_sao;
-}
-
-/* ServerActiveObject interface */
+       inventory.deSerialize(is);
 
-InventoryItem* ServerRemotePlayer::getWieldedItem()
-{
-       InventoryList *list = inventory.getList("main");
-       if (list)
-               return list->getItem(m_selected_item);
-       return NULL;
-}
-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;
-       }
-
-       // 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;
-       }
-       m_additional_items.clear();
-       m_inventory_not_sent = true;
-}
-void ServerRemotePlayer::setHP(s16 hp_)
-{
-       s16 oldhp = hp;
-
-       hp = hp_;
-
-       // FIXME: don't hardcode maximum HP, make configurable per object
-       if(hp < 0)
-               hp = 0;
-       else if(hp > 20)
-               hp = 20;
-
-       if(hp != oldhp)
-               m_hp_not_sent = true;
-}
-s16 ServerRemotePlayer::getHP()
-{
-       return hp;
-}
-
-/*
-       RemotePlayer
-*/
-
-#ifndef SERVER
-
-#if 0
-RemotePlayer::RemotePlayer(
-               IGameDef *gamedef,
-               scene::ISceneNode* parent,
-               IrrlichtDevice *device,
-               s32 id):
-       Player(gamedef),
-       scene::ISceneNode(parent, (device==NULL)?NULL:device->getSceneManager(), id),
-       m_text(NULL)
-{
-       m_box = core::aabbox3d<f32>(-BS/2,0,-BS/2,BS/2,BS*2,BS/2);
-
-       if(parent != NULL && device != NULL)
-       {
-               // ISceneNode stores a member called SceneManager
-               scene::ISceneManager* mgr = SceneManager;
-               video::IVideoDriver* driver = mgr->getVideoDriver();
-               gui::IGUIEnvironment* gui = device->getGUIEnvironment();
-
-               // Add a text node for showing the name
-               wchar_t wname[1] = {0};
-               m_text = mgr->addTextSceneNode(gui->getBuiltInFont(),
-                               wname, video::SColor(255,255,255,255), this);
-               m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
-
-               // Attach a simple mesh to the player for showing an image
-               scene::SMesh *mesh = new scene::SMesh();
-               { // Front
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
+               bool craftresult_is_preview = true;
+               if(args.exists("craftresult_is_preview"))
+                       craftresult_is_preview = args.getBool("craftresult_is_preview");
+               if(craftresult_is_preview)
                {
-                       video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
-               };
-               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_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player.png").c_str()));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
-               //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
+                       // Clear craftresult
+                       inventory.getList("craftresult")->changeItem(0, ItemStack());
                }
-               { // Back
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
-               {
-                       video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
-                       video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
-               };
-               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_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture(0, driver->getTexture(getTexturePath("player_back.png").c_str()));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
-               }
-               m_node = mgr->addMeshSceneNode(mesh, this);
-               mesh->drop();
-               m_node->setPosition(v3f(0,0,0));
-       }
-}
-
-RemotePlayer::~RemotePlayer()
-{
-       if(SceneManager != NULL)
-               ISceneNode::remove();
-}
-
-void RemotePlayer::updateName(const char *name)
-{
-       Player::updateName(name);
-       if(m_text != NULL)
-       {
-               wchar_t wname[PLAYERNAME_SIZE];
-               mbstowcs(wname, m_name, strlen(m_name)+1);
-               m_text->setText(wname);
        }
 }
 
-void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
-{
-       m_pos_animation_time_counter += dtime;
-       m_pos_animation_counter += dtime;
-       v3f movevector = m_position - m_oldpos;
-       f32 moveratio;
-       if(m_pos_animation_time < 0.001)
-               moveratio = 1.0;
-       else
-               moveratio = m_pos_animation_counter / m_pos_animation_time;
-       if(moveratio > 1.5)
-               moveratio = 1.5;
-       m_showpos = m_oldpos + movevector * moveratio;
-       
-       ISceneNode::setPosition(m_showpos);
-}
-#endif
-
-#endif
-
 #ifndef SERVER
 /*
        LocalPlayer
@@ -584,8 +293,8 @@ void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d,
        // 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;
@@ -1004,14 +713,17 @@ void LocalPlayer::applyControl(float dtime)
                }
                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)