diff --git a/src/client.cpp b/src/client.cpp index a5ed6f61b..d491f9d36 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -2008,6 +2008,14 @@ v3f Client::getPlayerPosition(v3f *eye_position) return player->getPosition(); } +void Client::setPlayerWield(scene::ISceneNode *wield) +{ + //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out + LocalPlayer *player = m_env.getLocalPlayer(); + assert(player != NULL); + player->wield = wield; +} + void Client::setPlayerControl(PlayerControl &control) { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out diff --git a/src/client.h b/src/client.h index 1a7ef924a..398a3b849 100644 --- a/src/client.h +++ b/src/client.h @@ -210,6 +210,7 @@ public: // eye position in *eye_position v3f getPlayerPosition(v3f *eye_position=NULL); + void setPlayerWield(scene::ISceneNode *wield); void setPlayerControl(PlayerControl &control); void selectPlayerItem(u16 item); diff --git a/src/game.cpp b/src/game.cpp index dc3ed2456..86f1939c3 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -956,7 +956,10 @@ void the_game( v3f(BS*100, BS*2, BS*100), // Look from v3f(BS*100+1, BS*2, BS*100), // Look to -1 // Camera ID - ); + ); + + // Do this so children rotate accordingly (tool) + camera->bindTargetAndRotation(true); if(camera == NULL) { @@ -972,6 +975,44 @@ void the_game( f32 camera_yaw = 0; // "right/left" f32 camera_pitch = 0; // "up/down" + /* + Tool + */ + + v3f tool_wield_position(0.6, -0.6, 1.0); + v3f tool_wield_rotation(-25, 180, -25); + float tool_wield_animation = 0.0; + scene::IMeshSceneNode *tool_wield; + { + scene::SMesh *mesh = new scene::SMesh(); + scene::IMeshBuffer *buf = new scene::SMeshBuffer(); + video::SColor c(255,255,255,255); + video::S3DVertex vertices[4] = + { + video::S3DVertex(-0.5,0,0, 0,0,0, c, 0,1), + video::S3DVertex(0.5,0,0, 0,0,0, c, 1,1), + video::S3DVertex(0.5,0.5,0, 0,0,0, c, 1,0), + video::S3DVertex(-0.5,0.5,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_BILINEAR_FILTER, false); + buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + // Add to mesh + mesh->addMeshBuffer(buf); + buf->drop(); + + tool_wield = smgr->addMeshSceneNode(mesh, camera); + mesh->drop(); + } + tool_wield->setVisible(false); + tool_wield->setPosition(tool_wield_position); + tool_wield->setRotation(tool_wield_rotation); + + client.setPlayerWield(tool_wield); + /* Clouds */ @@ -1920,6 +1961,7 @@ void the_game( } } + if(input->getRightClicked()) { std::cout<getLeftState()) + // Tool animation loops 0.0 - 1.0 + tool_wield_animation = fmod(tool_wield_animation + dtime * 3.0, 1.0); + else + // Return tool to holding position if not digging + tool_wield_animation /= 1.5; + } // selected_object == NULL input->resetLeftClicked(); @@ -2103,6 +2153,14 @@ void the_game( ); } + /* + Animate tool + */ + { + tool_wield->setRotation(tool_wield_rotation - sin(tool_wield_animation * PI) * 40.0); + tool_wield->setPosition(tool_wield_position - sin(tool_wield_animation * PI) / 3.0); + } + /* Update gui stuff (0ms) diff --git a/src/inventory.h b/src/inventory.h index 44ba6a5ad..f70d69b6d 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -53,6 +53,10 @@ public: // Shall make an exact clone of the item virtual InventoryItem* clone() = 0; #ifndef SERVER + // Return the name of the image for this item + virtual std::string getBasename() { return ""; } + // Shall return an image of the item (or NULL) + virtual video::ITexture * getImageRaw() { return NULL; } // Shall return an image to show in the GUI (or NULL) virtual video::ITexture * getImage() { return NULL; } #endif @@ -353,40 +357,53 @@ public: return new ToolItem(m_toolname, m_wear); } #ifndef SERVER + std::string getBasename() { + if(m_toolname == "WPick") + return "tool_woodpick.png"; + else if(m_toolname == "STPick") + return "tool_stonepick.png"; + else if(m_toolname == "SteelPick") + return "tool_steelpick.png"; + else if(m_toolname == "MesePick") + return "tool_mesepick.png"; + else if(m_toolname == "WShovel") + return "tool_woodshovel.png"; + else if(m_toolname == "STShovel") + return "tool_stoneshovel.png"; + else if(m_toolname == "SteelShovel") + return "tool_steelshovel.png"; + else if(m_toolname == "WAxe") + return "tool_woodaxe.png"; + else if(m_toolname == "STAxe") + return "tool_stoneaxe.png"; + else if(m_toolname == "SteelAxe") + return "tool_steelaxe.png"; + else if(m_toolname == "WSword") + return "tool_woodsword.png"; + else if(m_toolname == "STSword") + return "tool_stonesword.png"; + else if(m_toolname == "SteelSword") + return "tool_steelsword.png"; + else + return "cloud.png"; +} + + video::ITexture * getImageRaw() + { + if(g_texturesource == NULL) + return NULL; + + return g_texturesource->getTextureRaw(getBasename()); + } + video::ITexture * getImage() { if(g_texturesource == NULL) return NULL; - std::string basename; - if(m_toolname == "WPick") - basename = "tool_woodpick.png"; - else if(m_toolname == "STPick") - basename = "tool_stonepick.png"; - else if(m_toolname == "SteelPick") - basename = "tool_steelpick.png"; - else if(m_toolname == "MesePick") - basename = "tool_mesepick.png"; - else if(m_toolname == "WShovel") - basename = "tool_woodshovel.png"; - else if(m_toolname == "STShovel") - basename = "tool_stoneshovel.png"; - else if(m_toolname == "SteelShovel") - basename = "tool_steelshovel.png"; - else if(m_toolname == "WAxe") - basename = "tool_woodaxe.png"; - else if(m_toolname == "STAxe") - basename = "tool_stoneaxe.png"; - else if(m_toolname == "SteelAxe") - basename = "tool_steelaxe.png"; - else if(m_toolname == "WSword") - basename = "tool_woodsword.png"; - else if(m_toolname == "STSword") - basename = "tool_stonesword.png"; - else if(m_toolname == "SteelSword") - basename = "tool_steelsword.png"; - else - basename = "cloud.png"; + std::string basename = getBasename(); + + return g_texturesource->getTextureRaw(basename); /* Calculate a progress value with sane amount of diff --git a/src/player.cpp b/src/player.cpp index 7cfdfebb6..03ae24f45 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -309,12 +309,31 @@ LocalPlayer::LocalPlayer(): // Initialize hp to 0, so that no hearts will be shown if server // doesn't support health points hp = 0; + + // No tool wielded initially + wield = NULL; } LocalPlayer::~LocalPlayer() { } +void LocalPlayer::wieldItem(u16 item) +{ + m_selected_item = item; + + if(wield) { + InventoryItem* i = inventory.getList("main")->getItem(m_selected_item); + + if(i && strcmp(i->getName(), "ToolItem") == 0) { + wield->getMaterial(0).setTexture(0, i->getImageRaw()); + wield->setVisible(true); + } + else + wield->setVisible(false); + } +} + void LocalPlayer::move(f32 dtime, Map &map, f32 pos_max_d, core::list *collision_info) { diff --git a/src/player.h b/src/player.h index 13cffa205..0f2c40011 100644 --- a/src/player.h +++ b/src/player.h @@ -356,6 +356,8 @@ public: { return true; } + + void wieldItem(u16 item); void move(f32 dtime, Map &map, f32 pos_max_d, core::list *collision_info); @@ -365,6 +367,8 @@ public: PlayerControl control; + scene::ISceneNode *wield; + private: // This is used for determining the sneaking range v3s16 m_sneak_node;