From 63611932ebae93620386b26cfa82f7c4552b22ff Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 29 May 2011 21:11:16 +0300 Subject: player passwords and privileges in world/auth.txt --HG-- extra : rebase_source : 7260636295d9068fbeeddf4143c89f2b8a91446c --- src/game.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/game.cpp') diff --git a/src/game.cpp b/src/game.cpp index 603a86da3..cc758be7e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -764,8 +764,9 @@ void the_game( { if(client.accessDenied()) { - error_message = L"Access denied. Check your password and try again."; - std::cout< Date: Sun, 29 May 2011 21:13:29 +0300 Subject: invert_mouse config option --HG-- extra : rebase_source : 2695ad71185244cefbcf6e3e28ba1ab5e54c882f --- doc/changelog.txt | 1 + minetest.conf.example | 2 ++ src/defaultsettings.cpp | 1 + src/game.cpp | 4 ++++ 4 files changed, 8 insertions(+) (limited to 'src/game.cpp') diff --git a/doc/changelog.txt b/doc/changelog.txt index cb3594a98..e886370a6 100644 --- a/doc/changelog.txt +++ b/doc/changelog.txt @@ -14,6 +14,7 @@ X: - Player passwords - All textures first searched from texture_path - Map directory ("map") has been renamed to "world" (just rename it to load an old world) +- Mouse inversion (invert_mouse) 2011-04-24: - Smooth lighting with simple ambient occlusion diff --git a/minetest.conf.example b/minetest.conf.example index 5e6393228..1a1dbe0fc 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -42,6 +42,8 @@ #keymap_special1 = KEY_KEY_E #keymap_print_debug_stacks = KEY_KEY_P +#invert_mouse = false + # The desired FPS #wanted_fps = 30 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 1d758a2a4..6fcdc1dbb 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -65,6 +65,7 @@ void set_default_settings() g_settings.setDefault("free_move", "false"); g_settings.setDefault("continuous_forward", "false"); g_settings.setDefault("fast_move", "false"); + g_settings.setDefault("invert_mouse", "false"); // Server stuff g_settings.setDefault("enable_experimental", "false"); diff --git a/src/game.cpp b/src/game.cpp index cc758be7e..6932b45f1 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -894,6 +894,8 @@ void the_game( core::list frametime_log; float damage_flash_timer = 0; + + bool invert_mouse = g_settings.getBool("invert_mouse"); /* Main loop @@ -1306,6 +1308,8 @@ void the_game( else{ s32 dx = input->getMousePos().X - displaycenter.X; s32 dy = input->getMousePos().Y - displaycenter.Y; + if(invert_mouse) + dy = -dy; //std::cout<<"window active, pos difference "< Date: Tue, 31 May 2011 00:15:43 +0300 Subject: Reduced the CPU usage of the sent block selector algorithm --- minetest.conf.example | 11 +-- src/defaultsettings.cpp | 3 +- src/game.cpp | 19 +++++ src/main.cpp | 33 ++++++++- src/main.h | 4 ++ src/map.cpp | 6 +- src/mapblock.cpp | 4 +- src/profiler.h | 131 ++++++++++++++++++++++++++++++++++ src/server.cpp | 185 +++++++++++++++++++++++++++++++++++++----------- src/server.h | 11 +++ src/utility.h | 3 + 11 files changed, 355 insertions(+), 55 deletions(-) create mode 100644 src/profiler.h (limited to 'src/game.cpp') diff --git a/minetest.conf.example b/minetest.conf.example index 1a1dbe0fc..743186853 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -92,10 +92,6 @@ # Server side stuff # -# Set to true to enable experimental features -# (varies from version to version, see wiki) -#enable_experimental = false - # Map directory (everything in the world is stored here) #map-dir = /home/palle/custom_map @@ -112,6 +108,13 @@ # Gives some stuff to players at the beginning #give_initial_stuff = false +# Set to true to enable experimental features +# (varies from version to version, see wiki) +#enable_experimental = false + +# Profiler data print interval. 0 = disable. +#profiler_print_interval = 10 + # Player and object positions are sent at intervals specified by this #objectdata_inverval = 0.2 diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 6fcdc1dbb..73f22a7f7 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -74,12 +74,13 @@ void set_default_settings() g_settings.setDefault("give_initial_stuff", "false"); g_settings.setDefault("default_password", ""); g_settings.setDefault("default_privs", "build, shout"); + g_settings.setDefault("profiler_print_interval", "0"); g_settings.setDefault("objectdata_interval", "0.2"); g_settings.setDefault("active_object_range", "2"); g_settings.setDefault("max_simultaneous_block_sends_per_client", "1"); //g_settings.setDefault("max_simultaneous_block_sends_per_client", "2"); - g_settings.setDefault("max_simultaneous_block_sends_server_total", "4"); + g_settings.setDefault("max_simultaneous_block_sends_server_total", "8"); g_settings.setDefault("max_block_send_distance", "8"); g_settings.setDefault("max_block_generate_distance", "8"); g_settings.setDefault("time_send_interval", "20"); diff --git a/src/game.cpp b/src/game.cpp index 6932b45f1..e8e6cb71f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -903,6 +903,10 @@ void the_game( bool first_loop_after_window_activation = true; + // TODO: Convert the static interval timers to these + // Interval limiter for profiler + IntervalLimiter m_profiler_interval; + // Time is in milliseconds // NOTE: getRealTime() causes strange problems in wine (imprecision?) // NOTE: So we have to use getTime() and call run()s between them @@ -1089,6 +1093,21 @@ void the_game( } } + /* + Profiler + */ + float profiler_print_interval = + g_settings.getFloat("profiler_print_interval"); + if(profiler_print_interval != 0) + { + if(m_profiler_interval.step(0.030, profiler_print_interval)) + { + dstream<<"Profiler:"< diff --git a/src/map.cpp b/src/map.cpp index a49de3c46..f9809e9fd 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -5692,9 +5692,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) p_nodes_min.Y / MAP_BLOCKSIZE - 1, p_nodes_min.Z / MAP_BLOCKSIZE - 1); v3s16 p_blocks_max( - p_nodes_max.X / MAP_BLOCKSIZE + 1, - p_nodes_max.Y / MAP_BLOCKSIZE + 1, - p_nodes_max.Z / MAP_BLOCKSIZE + 1); + p_nodes_max.X / MAP_BLOCKSIZE, + p_nodes_max.Y / MAP_BLOCKSIZE, + p_nodes_max.Z / MAP_BLOCKSIZE); u32 vertex_count = 0; diff --git a/src/mapblock.cpp b/src/mapblock.cpp index c448ef236..b2f972dde 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -540,10 +540,10 @@ void updateFastFaceRow( v3s16 p_next; - bool next_makes_face; + bool next_makes_face = false; v3s16 next_p_corrected; v3s16 next_face_dir_corrected; - u8 next_lights[4]; + u8 next_lights[4] = {0,0,0,0}; TileSpec next_tile; // If at last position, there is nothing to compare to and diff --git a/src/profiler.h b/src/profiler.h new file mode 100644 index 000000000..a30e34a7c --- /dev/null +++ b/src/profiler.h @@ -0,0 +1,131 @@ +/* +Minetest-c55 +Copyright (C) 2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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. +*/ + +#ifndef PROFILER_HEADER +#define PROFILER_HEADER + +#include "common_irrlicht.h" +#include +#include "utility.h" +#include +#include + +/* + Time profiler +*/ + +class Profiler +{ +public: + Profiler() + { + m_mutex.Init(); + } + + void add(const std::string &name, u32 duration) + { + JMutexAutoLock lock(m_mutex); + core::map::Node *n = m_data.find(name); + if(n == NULL) + { + m_data[name] = duration; + } + else + { + n->setValue(n->getValue()+duration); + } + } + + void clear() + { + JMutexAutoLock lock(m_mutex); + for(core::map::Iterator + i = m_data.getIterator(); + i.atEnd() == false; i++) + { + i.getNode()->setValue(0); + } + } + + void print(std::ostream &o) + { + JMutexAutoLock lock(m_mutex); + for(core::map::Iterator + i = m_data.getIterator(); + i.atEnd() == false; i++) + { + std::string name = i.getNode()->getKey(); + o<getValue(); + o< m_data; +}; + +class ScopeProfiler +{ +public: + ScopeProfiler(Profiler *profiler, const std::string &name): + m_profiler(profiler), + m_name(name), + m_timer(NULL) + { + if(m_profiler) + m_timer = new TimeTaker(m_name.c_str()); + } + // name is copied + ScopeProfiler(Profiler *profiler, const char *name): + m_profiler(profiler), + m_name(name), + m_timer(NULL) + { + if(m_profiler) + m_timer = new TimeTaker(m_name.c_str()); + } + ~ScopeProfiler() + { + if(m_timer) + { + u32 duration = m_timer->stop(true); + if(m_profiler) + m_profiler->add(m_name, duration); + delete m_timer; + } + } +private: + Profiler *m_profiler; + std::string m_name; + TimeTaker *m_timer; +}; + +#endif + diff --git a/src/server.cpp b/src/server.cpp index 56874c46c..6f1f1e6e8 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -312,11 +312,14 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, TimeTaker timer("RemoteClient::GetNextBlocks", &timer_result);*/ // Increment timers - m_nearest_unsent_reset_timer += dtime; m_nothing_to_send_pause_timer -= dtime; if(m_nothing_to_send_pause_timer >= 0) + { + // Keep this reset + m_nearest_unsent_reset_timer = 0; return; + } // Won't send anything if already sending if(m_blocks_sending.size() >= g_settings.getU16 @@ -326,14 +329,21 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, return; } + //TimeTaker timer("RemoteClient::GetNextBlocks"); + Player *player = server->m_env.getPlayer(peer_id); assert(player != NULL); v3f playerpos = player->getPosition(); v3f playerspeed = player->getSpeed(); + v3f playerspeeddir(0,0,0); + if(playerspeed.getLength() > 1.0*BS) + playerspeeddir = playerspeed / playerspeed.getLength(); + // Predict to next block + v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS; - v3s16 center_nodepos = floatToInt(playerpos, BS); + v3s16 center_nodepos = floatToInt(playerpos_predicted, BS); v3s16 center = getNodeBlockPos(center_nodepos); @@ -344,6 +354,9 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, camera_dir.rotateYZBy(player->getPitch()); camera_dir.rotateXZBy(player->getYaw()); + /*dstream<<"camera_dir=("<getPlayerName(peer_id)< d_start+1) + d_max = d_start+1; + /*if(d_max_gen > d_start+2) + d_max_gen = d_start+2;*/ + //dstream<<"Starting from "<= 3) + if((s16)m_nothing_to_send_counter >= + g_settings.getS16("max_block_send_distance")) { // Pause time in seconds - m_nothing_to_send_pause_timer = 2.0; + m_nothing_to_send_pause_timer = 1.0; + dstream<<"nothing to send to " + <getPlayerName(peer_id) + <<" (d="< modified_blocks; m_env.getMap().transformLiquids(modified_blocks); #if 0 @@ -1298,10 +1360,11 @@ void Server::AsyncRunStep() */ { //dstream<<"Server: Checking added and deleted active objects"<* > buffered_messages; @@ -1598,6 +1663,9 @@ void Server::AsyncRunStep() { JMutexAutoLock lock1(m_env_mutex); JMutexAutoLock lock2(m_con_mutex); + + ScopeProfiler sp(&g_profiler, "Server: sending mbo positions"); + SendObjectData(counter); counter = 0.0; @@ -1612,7 +1680,9 @@ void Server::AsyncRunStep() JMutexAutoLock envlock(m_env_mutex); JMutexAutoLock conlock(m_con_mutex); - + + ScopeProfiler sp(&g_profiler, "Server: stepping node metadata"); + core::map changed_blocks; m_env.getMap().nodeMetadataStep(dtime, changed_blocks); @@ -1655,6 +1725,8 @@ void Server::AsyncRunStep() { counter = 0.0; + ScopeProfiler sp(&g_profiler, "Server: saving stuff"); + // Auth stuff m_authmanager.save(); @@ -3646,20 +3718,24 @@ void Server::SendBlocks(float dtime) core::array queue; s32 total_sending = 0; - - for(core::map::Iterator - i = m_clients.getIterator(); - i.atEnd() == false; i++) + { - RemoteClient *client = i.getNode()->getValue(); - assert(client->peer_id == i.getNode()->getKey()); + ScopeProfiler sp(&g_profiler, "Server: selecting blocks for sending"); - total_sending += client->SendingCount(); - - if(client->serialization_version == SER_FMT_VER_INVALID) - continue; - - client->GetNextBlocks(this, dtime, queue); + for(core::map::Iterator + i = m_clients.getIterator(); + i.atEnd() == false; i++) + { + RemoteClient *client = i.getNode()->getValue(); + assert(client->peer_id == i.getNode()->getKey()); + + total_sending += client->SendingCount(); + + if(client->serialization_version == SER_FMT_VER_INVALID) + continue; + + client->GetNextBlocks(this, dtime, queue); + } } // Sort. @@ -4531,25 +4607,48 @@ void dedicated_server_loop(Server &server, bool &kill) { DSTACK(__FUNCTION_NAME); - std::cout<PrintLine(&std::cout); + i->PrintLine(&dstream); } } sum_old = sum; diff --git a/src/server.h b/src/server.h index 7b73e476c..6bee10685 100644 --- a/src/server.h +++ b/src/server.h @@ -500,6 +500,15 @@ private: // When called, connection mutex should be locked RemoteClient* getClient(u16 peer_id); + // When called, environment mutex should be locked + std::string getPlayerName(u16 peer_id) + { + Player *player = m_env.getPlayer(peer_id); + if(player == NULL) + return "[id="+itos(peer_id); + return player->getName(); + } + /* Get a player from memory or creates one. If player is already connected, return NULL @@ -627,6 +636,8 @@ private: */ u16 m_ignore_map_edit_events_peer_id; + Profiler *m_profiler; + friend class EmergeThread; friend class RemoteClient; }; diff --git a/src/utility.h b/src/utility.h index f18d31278..534aea483 100644 --- a/src/utility.h +++ b/src/utility.h @@ -244,6 +244,9 @@ inline f32 readF1000(std::istream &is) { char buf[2]; is.read(buf, 2); + // TODO: verify if this gets rid of the valgrind warning + //if(is.gcount() != 2) + // return 0; return readF1000((u8*)buf); } -- cgit v1.2.3 From 72e742c24eb70fdf8aacb7d3043b6a1537ca14fb Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Tue, 7 Jun 2011 22:08:16 +0300 Subject: Added an experimental "far view" thing. Doesn't work exactly like it should and not suitable for real use yet, and might never be. --- minetest.conf.example | 6 ++ src/CMakeLists.txt | 1 + src/clouds.cpp | 2 +- src/defaultsettings.cpp | 3 +- src/farmesh.cpp | 253 ++++++++++++++++++++++++++++++++++++++++++++++++ src/farmesh.h | 84 ++++++++++++++++ src/game.cpp | 42 +++++++- 7 files changed, 386 insertions(+), 5 deletions(-) create mode 100644 src/farmesh.cpp create mode 100644 src/farmesh.h (limited to 'src/game.cpp') diff --git a/minetest.conf.example b/minetest.conf.example index 743186853..6e8a82bac 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -58,6 +58,12 @@ # Whether to fog out the end of the visible area #enable_fog = true +# Enable/disable clouds +#enable_clouds = true + +# Experimental +#enable_farmesh = false + # Enable a bit lower water surface; disable for speed #new_style_water = true diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 367b38818..558c28027 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -85,6 +85,7 @@ set(common_SRCS # Client sources set(minetest_SRCS ${common_SRCS} + farmesh.cpp keycode.cpp clouds.cpp clientobject.cpp diff --git a/src/clouds.cpp b/src/clouds.cpp index 70d19fde5..122beedac 100644 --- a/src/clouds.cpp +++ b/src/clouds.cpp @@ -58,8 +58,8 @@ void Clouds::OnRegisterSceneNode() { if(IsVisible) { - SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); //SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); } ISceneNode::OnRegisterSceneNode(); diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 73f22a7f7..e57157a82 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -61,11 +61,12 @@ void set_default_settings() g_settings.setDefault("enable_texture_atlas", "true"); g_settings.setDefault("texture_path", ""); g_settings.setDefault("video_driver", "opengl"); - g_settings.setDefault("free_move", "false"); g_settings.setDefault("continuous_forward", "false"); g_settings.setDefault("fast_move", "false"); g_settings.setDefault("invert_mouse", "false"); + g_settings.setDefault("enable_farmesh", "false"); + g_settings.setDefault("enable_clouds", "true"); // Server stuff g_settings.setDefault("enable_experimental", "false"); diff --git a/src/farmesh.cpp b/src/farmesh.cpp new file mode 100644 index 000000000..e4847966f --- /dev/null +++ b/src/farmesh.cpp @@ -0,0 +1,253 @@ +/* +Part of Minetest-c55 +Copyright (C) 2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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. +*/ + +/* + A quick messy implementation of terrain rendering for a long + distance according to map seed +*/ + +#include "farmesh.h" +#include "constants.h" +#include "debug.h" +#include "noise.h" +#include "map.h" + +FarMesh::FarMesh( + scene::ISceneNode* parent, + scene::ISceneManager* mgr, + s32 id, + u64 seed +): + scene::ISceneNode(parent, mgr, id), + m_seed(seed), + m_camera_pos(0,0), + m_time(0) +{ + dstream<<__FUNCTION_NAME<(-BS*1000000,-BS*31000,-BS*1000000, + BS*1000000,BS*31000,BS*1000000); + +} + +FarMesh::~FarMesh() +{ + dstream<<__FUNCTION_NAME<registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); + //SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX); + } + + ISceneNode::OnRegisterSceneNode(); +} + +#define MYROUND(x) (x > 0.0 ? (int)x : (int)x - 1) + +// Temporary hack +core::map g_heights; + +float ground_height(u64 seed, v2s16 p2d) +{ + core::map::Node *n = g_heights.find(p2d); + if(n) + return n->getValue(); + float avg_mud_amount = 4; + float gh = BS*base_rock_level_2d(seed, p2d) + avg_mud_amount*BS; + //gh *= 10; + g_heights[p2d] = gh; + return gh; +} + +void FarMesh::render() +{ + video::IVideoDriver* driver = SceneManager->getVideoDriver(); + + /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) + return;*/ + /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID) + return;*/ + if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SKY_BOX) + return; + + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); + driver->setMaterial(m_material); + + const s16 grid_radius_i = 12; + const float grid_size = BS*50; + const v2f grid_speed(-BS*0, 0); + + // Position of grid noise origin in world coordinates + v2f world_grid_origin_pos_f(0,0); + // Position of grid noise origin from the camera + v2f grid_origin_from_camera_f = world_grid_origin_pos_f - m_camera_pos; + // The center point of drawing in the noise + v2f center_of_drawing_in_noise_f = -grid_origin_from_camera_f; + // The integer center point of drawing in the noise + v2s16 center_of_drawing_in_noise_i( + MYROUND(center_of_drawing_in_noise_f.X / grid_size), + MYROUND(center_of_drawing_in_noise_f.Y / grid_size) + ); + // The world position of the integer center point of drawing in the noise + v2f world_center_of_drawing_in_noise_f = v2f( + center_of_drawing_in_noise_i.X * grid_size, + center_of_drawing_in_noise_i.Y * grid_size + ) + world_grid_origin_pos_f; + + for(s16 zi=-grid_radius_i; zi h_max) + h_max = noise[i]; + } + float steepness = (h_max - h_min)/grid_size; + + float h_avg = (noise[0]+noise[1]+noise[2]+noise[3])/4.0; + float light_f = noise[0]+noise[1]-noise[2]-noise[3]; + light_f /= 100; + if(light_f < -1.0) light_f = -1.0; + if(light_f > 1.0) light_f = 1.0; + //light_f += 1.0; + //light_f /= 2.0; + + v2f p1 = p0 + v2f(1,1)*grid_size; + + video::SColor c; + // Detect water + if(h_avg < WATER_LEVEL*BS && h_max < (WATER_LEVEL+5)*BS) + { + c = video::SColor(128,59,86,146); + /*// Set to water level + for(u32 i=0; i<4; i++) + { + if(noise[i] < BS*WATER_LEVEL) + noise[i] = BS*WATER_LEVEL; + }*/ + light_f = 0; + } + else if(steepness > 2.0) + c = video::SColor(128,128,128,128); + else + c = video::SColor(128,107,134,51); + + // Set to water level + for(u32 i=0; i<4; i++) + { + if(noise[i] < BS*WATER_LEVEL) + noise[i] = BS*WATER_LEVEL; + } + + float b = m_brightness + light_f*0.1*m_brightness; + if(b < 0) b = 0; + if(b > 2) b = 2; + + c = video::SColor(128, b*c.getRed(), b*c.getGreen(), b*c.getBlue()); + + video::S3DVertex vertices[4] = + { + video::S3DVertex(p0.X,noise[0],p0.Y, 0,0,0, c, 0,1), + video::S3DVertex(p0.X,noise[1],p1.Y, 0,0,0, c, 1,1), + video::S3DVertex(p1.X,noise[2],p1.Y, 0,0,0, c, 1,0), + video::S3DVertex(p1.X,noise[3],p0.Y, 0,0,0, c, 0,0), + }; + u16 indices[] = {0,1,2,2,3,0}; + driver->drawVertexPrimitiveList(vertices, 4, indices, 2, + video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); + } + + driver->clearZBuffer(); +} + +void FarMesh::step(float dtime) +{ + m_time += dtime; +} + +void FarMesh::update(v2f camera_p, float brightness) +{ + m_camera_pos = camera_p; + m_brightness = brightness; +} + diff --git a/src/farmesh.h b/src/farmesh.h new file mode 100644 index 000000000..12f587942 --- /dev/null +++ b/src/farmesh.h @@ -0,0 +1,84 @@ +/* +Part of Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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. +*/ + +#ifndef FARMESH_HEADER +#define FARMESH_HEADER + +/* + A quick messy implementation of terrain rendering for a long + distance according to map seed +*/ + +#include "common_irrlicht.h" + +class FarMesh : public scene::ISceneNode +{ +public: + FarMesh( + scene::ISceneNode* parent, + scene::ISceneManager* mgr, + s32 id, + u64 seed + ); + + ~FarMesh(); + + /* + ISceneNode methods + */ + + virtual void OnRegisterSceneNode(); + + virtual void render(); + + virtual const core::aabbox3d& getBoundingBox() const + { + return m_box; + } + + virtual u32 getMaterialCount() const + { + return 1; + } + + virtual video::SMaterial& getMaterial(u32 i) + { + return m_material; + } + + /* + Other stuff + */ + + void step(float dtime); + + void update(v2f camera_p, float brightness); + +private: + video::SMaterial m_material; + core::aabbox3d m_box; + float m_cloud_y; + float m_brightness; + u32 m_seed; + v2f m_camera_pos; + float m_time; +}; + +#endif + diff --git a/src/game.cpp b/src/game.cpp index e8e6cb71f..ef574c348 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "config.h" #include "clouds.h" #include "keycode.h" +#include "farmesh.h" /* Setting this to 1 enables a special camera mode that forces @@ -595,6 +596,10 @@ void update_skybox(video::IVideoDriver* driver, skybox->remove(); } + // Disable skybox if FarMesh is enabled + if(g_settings.getBool("enable_farmesh")) + return; + if(brightness >= 0.5) { skybox = smgr->addSkyBoxSceneNode( @@ -815,8 +820,21 @@ void the_game( float cloud_height = BS*100; Clouds *clouds = NULL; - clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, - cloud_height, time(0)); + if(g_settings.getBool("enable_clouds")) + { + clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, + cloud_height, time(0)); + } + + /* + FarMesh + */ + + FarMesh *farmesh = NULL; + if(g_settings.getBool("enable_farmesh")) + { + farmesh = new FarMesh(smgr->getRootSceneNode(), smgr, -1, client.getMapSeed()); + } /* Move into game @@ -1789,6 +1807,16 @@ void the_game( 0.05+brightness*0.95); } + /* + Update farmesh (TODO: Remove from here) + */ + if(farmesh) + { + farmesh->step(dtime); + farmesh->update(v2f(player_position.X, player_position.Z), + 0.05+brightness*0.95); + } + // Store brightness value old_brightness = brightness; @@ -1999,6 +2027,13 @@ void the_game( //driver->beginScene(false, true, bgcolor); beginscenetime = timer.stop(true); } + + /* + Draw farmesh before everything else + */ + { + //farmesh->render(); + } //timer3.stop(); @@ -2131,7 +2166,8 @@ void the_game( /* Drop stuff */ - clouds->drop(); + if(clouds) + clouds->drop(); /* Draw a "shutting down" screen, which will be shown while the map -- cgit v1.2.3 From dc5319b6c9f2e39d93f2fa881403f36fc47ffaac Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 17 Jun 2011 22:20:15 +0300 Subject: Moved some mapnode content stuff from mapnode.{h,cpp} and digging property stuff from material.cpp to content_mapnode.{h,cpp} --- src/CMakeLists.txt | 1 + src/content_mapnode.cpp | 351 ++++++++++++++++++++++++++++++++++++++++++++++++ src/content_mapnode.h | 53 ++++++++ src/environment.cpp | 1 + src/game.cpp | 3 + src/inventory.cpp | 1 + src/main.cpp | 9 +- src/map.cpp | 1 + src/mapblock.cpp | 3 + src/mapnode.cpp | 257 ++--------------------------------- src/mapnode.h | 157 ++++++++-------------- src/materials.cpp | 106 +-------------- src/materials.h | 24 ++-- src/nodemetadata.cpp | 1 + src/server.cpp | 1 + src/servermain.cpp | 2 +- src/test.cpp | 1 + src/voxel.cpp | 5 +- 18 files changed, 514 insertions(+), 463 deletions(-) create mode 100644 src/content_mapnode.cpp create mode 100644 src/content_mapnode.h (limited to 'src/game.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 558c28027..05b56310f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,7 @@ configure_file( ) set(common_SRCS + content_mapnode.cpp auth.cpp collision.cpp nodemetadata.cpp diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp new file mode 100644 index 000000000..1f1c8e30a --- /dev/null +++ b/src/content_mapnode.cpp @@ -0,0 +1,351 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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. +*/ + +// For g_settings +#include "main.h" + +#include "content_mapnode.h" +#include "mapnode.h" +#include "nodemetadata.h" + +// TODO: Get rid of these and set up some attributes like toughness, +// fluffyness, and a funciton to calculate time and durability loss +// (and sound? and whatever else) from them +void setStoneLikeDiggingProperties(DiggingPropertiesList &list, float toughness); +void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness); +void setWoodLikeDiggingProperties(DiggingPropertiesList &list, float toughness); + +void content_mapnode_init() +{ + // Read some settings + bool new_style_water = g_settings.getBool("new_style_water"); + bool new_style_leaves = g_settings.getBool("new_style_leaves"); + + u8 i; + ContentFeatures *f = NULL; + + i = CONTENT_STONE; + f = &content_features(i); + f->setAllTextures("stone.png"); + f->setInventoryTextureCube("stone.png", "stone.png", "stone.png"); + f->param_type = CPT_MINERAL; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 1"; + setStoneLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_GRASS; + f = &content_features(i); + f->setAllTextures("mud.png^grass_side.png"); + f->setTexture(0, "grass.png"); + f->setTexture(1, "mud.png"); + f->param_type = CPT_MINERAL; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1"; + setDirtLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_GRASS_FOOTSTEPS; + f = &content_features(i); + f->setAllTextures("mud.png^grass_side.png"); + f->setTexture(0, "grass_footsteps.png"); + f->setTexture(1, "mud.png"); + f->param_type = CPT_MINERAL; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1"; + setDirtLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_MUD; + f = &content_features(i); + f->setAllTextures("mud.png"); + f->setInventoryTextureCube("mud.png", "mud.png", "mud.png"); + f->param_type = CPT_MINERAL; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setDirtLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_SAND; + f = &content_features(i); + f->setAllTextures("sand.png"); + f->param_type = CPT_MINERAL; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setDirtLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_TREE; + f = &content_features(i); + f->setAllTextures("tree.png"); + f->setTexture(0, "tree_top.png"); + f->setTexture(1, "tree_top.png"); + f->param_type = CPT_MINERAL; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setWoodLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_LEAVES; + f = &content_features(i); + f->light_propagates = true; + //f->param_type = CPT_MINERAL; + f->param_type = CPT_LIGHT; + f->is_ground_content = true; + if(new_style_leaves) + { + f->solidness = 0; // drawn separately, makes no faces + f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png"); + } + else + { + f->setAllTextures("[noalpha:leaves.png"); + } + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setWoodLikeDiggingProperties(f->digging_properties, 0.15); + + i = CONTENT_GLASS; + f = &content_features(i); + f->light_propagates = true; + f->param_type = CPT_LIGHT; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + f->solidness = 0; // drawn separately, makes no faces + f->setInventoryTextureCube("glass.png", "glass.png", "glass.png"); + setWoodLikeDiggingProperties(f->digging_properties, 0.15); + + i = CONTENT_FENCE; + f = &content_features(i); + f->light_propagates = true; + f->param_type = CPT_LIGHT; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + f->solidness = 0; // drawn separately, makes no faces + f->air_equivalent = true; // grass grows underneath + f->setInventoryTexture("item_fence.png"); + setWoodLikeDiggingProperties(f->digging_properties, 0.75); + + // Deprecated + i = CONTENT_COALSTONE; + f = &content_features(i); + //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL); + f->setAllTextures("stone.png^mineral_coal.png"); + f->is_ground_content = true; + setStoneLikeDiggingProperties(f->digging_properties, 1.5); + + i = CONTENT_WOOD; + f = &content_features(i); + f->setAllTextures("wood.png"); + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setWoodLikeDiggingProperties(f->digging_properties, 0.75); + + i = CONTENT_MESE; + f = &content_features(i); + f->setAllTextures("mese.png"); + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setStoneLikeDiggingProperties(f->digging_properties, 0.5); + + i = CONTENT_CLOUD; + f = &content_features(i); + f->setAllTextures("cloud.png"); + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + + i = CONTENT_AIR; + f = &content_features(i); + f->param_type = CPT_LIGHT; + f->light_propagates = true; + f->sunlight_propagates = true; + f->solidness = 0; + f->walkable = false; + f->pointable = false; + f->diggable = false; + f->buildable_to = true; + f->air_equivalent = true; + + i = CONTENT_WATER; + f = &content_features(i); + f->setInventoryTextureCube("water.png", "water.png", "water.png"); + f->param_type = CPT_LIGHT; + f->light_propagates = true; + f->solidness = 0; // Drawn separately, makes no faces + f->walkable = false; + f->pointable = false; + f->diggable = false; + f->buildable_to = true; + f->liquid_type = LIQUID_FLOWING; + f->liquid_alternative_flowing = CONTENT_WATER; + + i = CONTENT_WATERSOURCE; + f = &content_features(i); + f->setInventoryTexture("water.png"); + if(new_style_water) + { + f->solidness = 0; // drawn separately, makes no faces + } + else // old style + { + f->solidness = 1; + + TileSpec t; + if(g_texturesource) + t.texture = g_texturesource->getTexture("water.png"); + + t.alpha = WATER_ALPHA; + t.material_type = MATERIAL_ALPHA_VERTEX; + t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; + f->setAllTiles(t); + } + f->param_type = CPT_LIGHT; + f->light_propagates = true; + f->walkable = false; + f->pointable = false; + f->diggable = false; + f->buildable_to = true; + f->liquid_type = LIQUID_SOURCE; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + f->liquid_alternative_flowing = CONTENT_WATER; + + i = CONTENT_TORCH; + f = &content_features(i); + f->setInventoryTexture("torch_on_floor.png"); + f->param_type = CPT_LIGHT; + f->light_propagates = true; + f->sunlight_propagates = true; + f->solidness = 0; // drawn separately, makes no faces + f->walkable = false; + f->wall_mounted = true; + f->air_equivalent = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + f->light_source = LIGHT_MAX; + f->digging_properties.set("", DiggingProperties(true, 0.0, 0)); + + i = CONTENT_SIGN_WALL; + f = &content_features(i); + f->setInventoryTexture("sign_wall.png"); + f->param_type = CPT_LIGHT; + f->light_propagates = true; + f->sunlight_propagates = true; + f->solidness = 0; // drawn separately, makes no faces + f->walkable = false; + f->wall_mounted = true; + f->air_equivalent = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + if(f->initial_metadata == NULL) + f->initial_metadata = new SignNodeMetadata("Some sign"); + f->digging_properties.set("", DiggingProperties(true, 0.5, 0)); + + i = CONTENT_CHEST; + f = &content_features(i); + f->param_type = CPT_FACEDIR_SIMPLE; + f->setAllTextures("chest_side.png"); + f->setTexture(0, "chest_top.png"); + f->setTexture(1, "chest_top.png"); + f->setTexture(5, "chest_front.png"); // Z- + f->setInventoryTexture("chest_top.png"); + //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png"); + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + if(f->initial_metadata == NULL) + f->initial_metadata = new ChestNodeMetadata(); + setWoodLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_FURNACE; + f = &content_features(i); + f->param_type = CPT_FACEDIR_SIMPLE; + f->setAllTextures("furnace_side.png"); + f->setTexture(5, "furnace_front.png"); // Z- + f->setInventoryTexture("furnace_front.png"); + //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6"; + if(f->initial_metadata == NULL) + f->initial_metadata = new FurnaceNodeMetadata(); + setStoneLikeDiggingProperties(f->digging_properties, 3.0); + + i = CONTENT_COBBLE; + f = &content_features(i); + f->setAllTextures("cobble.png"); + f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png"); + f->param_type = CPT_NONE; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setStoneLikeDiggingProperties(f->digging_properties, 1.0); + + i = CONTENT_STEEL; + f = &content_features(i); + f->setAllTextures("steel_block.png"); + f->setInventoryTextureCube("steel_block.png", "steel_block.png", + "steel_block.png"); + f->param_type = CPT_NONE; + f->is_ground_content = true; + f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + setStoneLikeDiggingProperties(f->digging_properties, 5.0); + + // NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp + + + /* + Add MesePick to everything + */ + for(u16 i=0; i<256; i++) + { + content_features(i).digging_properties.set("MesePick", + DiggingProperties(true, 0.0, 65535./1337)); + } + +} + +void setStoneLikeDiggingProperties(DiggingPropertiesList &list, float toughness) +{ + list.set("", + DiggingProperties(true, 15.0*toughness, 0)); + + list.set("WPick", + DiggingProperties(true, 1.3*toughness, 65535./30.*toughness)); + list.set("STPick", + DiggingProperties(true, 0.75*toughness, 65535./100.*toughness)); + list.set("SteelPick", + DiggingProperties(true, 0.50*toughness, 65535./333.*toughness)); + + /*list.set("MesePick", + DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/ +} + +void setDirtLikeDiggingProperties(DiggingPropertiesList &list, float toughness) +{ + list.set("", + DiggingProperties(true, 0.75*toughness, 0)); + + list.set("WShovel", + DiggingProperties(true, 0.4*toughness, 65535./50.*toughness)); + list.set("STShovel", + DiggingProperties(true, 0.2*toughness, 65535./150.*toughness)); + list.set("SteelShovel", + DiggingProperties(true, 0.15*toughness, 65535./400.*toughness)); +} + +void setWoodLikeDiggingProperties(DiggingPropertiesList &list, float toughness) +{ + list.set("", + DiggingProperties(true, 3.0*toughness, 0)); + + list.set("WAxe", + DiggingProperties(true, 1.5*toughness, 65535./30.*toughness)); + list.set("STAxe", + DiggingProperties(true, 0.75*toughness, 65535./100.*toughness)); + list.set("SteelAxe", + DiggingProperties(true, 0.5*toughness, 65535./333.*toughness)); +} + + diff --git a/src/content_mapnode.h b/src/content_mapnode.h new file mode 100644 index 000000000..c511834e5 --- /dev/null +++ b/src/content_mapnode.h @@ -0,0 +1,53 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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. +*/ + +#ifndef CONTENT_MAPNODE_HEADER +#define CONTENT_MAPNODE_HEADER + +void content_mapnode_init(); + +/* + Node content type IDs +*/ +#define CONTENT_STONE 0 +#define CONTENT_GRASS 1 +#define CONTENT_WATER 2 +#define CONTENT_TORCH 3 +#define CONTENT_TREE 4 +#define CONTENT_LEAVES 5 +#define CONTENT_GRASS_FOOTSTEPS 6 +#define CONTENT_MESE 7 +#define CONTENT_MUD 8 +#define CONTENT_WATERSOURCE 9 +// Pretty much useless, clouds won't be drawn this way +#define CONTENT_CLOUD 10 +#define CONTENT_COALSTONE 11 +#define CONTENT_WOOD 12 +#define CONTENT_SAND 13 +#define CONTENT_SIGN_WALL 14 +#define CONTENT_CHEST 15 +#define CONTENT_FURNACE 16 +//#define CONTENT_WORKBENCH 17 +#define CONTENT_COBBLE 18 +#define CONTENT_STEEL 19 +#define CONTENT_GLASS 20 +#define CONTENT_FENCE 21 + +#endif + diff --git a/src/environment.cpp b/src/environment.cpp index 798228802..8f8628305 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "porting.h" #include "collision.h" +#include "content_mapnode.h" Environment::Environment(): diff --git a/src/game.cpp b/src/game.cpp index ef574c348..eef27c805 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -32,6 +32,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "keycode.h" #include "farmesh.h" +// TODO: Move content-aware stuff to separate file +#include "content_mapnode.h" + /* Setting this to 1 enables a special camera mode that forces the renderers to think that the camera statically points from diff --git a/src/inventory.cpp b/src/inventory.cpp index 47a8d4de9..88453530e 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "main.h" #include "serverobject.h" +#include "content_mapnode.h" /* InventoryItem diff --git a/src/main.cpp b/src/main.cpp index bb34a1a97..ed3b322a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -228,6 +228,12 @@ TODO: Map saving should be done by EmergeThread SUGG: Map unloading based on sector reference is not very good, it keeps unnecessary stuff in memory. I guess. Investigate this. +TODO: FIXME: Make furnaces handle long step() times better; now a 10-day + dtime for a bunch of furnaces will take ages + +TODO: When block is placed and it has param_type==CPT_FACEDIR_SIMPLE, set + the direction accordingly. + Environment: ------------ @@ -1143,7 +1149,7 @@ int main(int argc, char *argv[]) fs::CreateDir(porting::path_userdata); // Init material properties table - initializeMaterialProperties(); + //initializeMaterialProperties(); // Debug handler BEGIN_DEBUG_EXCEPTION_HANDLER @@ -1414,7 +1420,6 @@ int main(int argc, char *argv[]) Preload some textures and stuff */ - init_content_inventory_texture_paths(); init_mapnode(); // Second call with g_texturesource set init_mineral(); diff --git a/src/map.cpp b/src/map.cpp index 9230d1c16..515885d87 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mineral.h" #include "noise.h" #include "serverobject.h" +#include "content_mapnode.h" /* Map diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 1ebdd6b0d..70006a718 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -24,6 +24,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "light.h" #include +// TODO: Move content-aware mesh generation to a separate file +#include "content_mapnode.h" + #ifndef SERVER void MeshMakeData::fill(u32 daynight_ratio, MapBlock *block) { diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 9a8a09a15..3717bf0ab 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mineral.h" // For g_settings #include "main.h" +#include "content_mapnode.h" #include "nodemetadata.h" ContentFeatures::~ContentFeatures() @@ -107,9 +108,9 @@ void init_mapnode() "g_texturesource!=NULL"<reset(); for(u16 j=0; j<6; j++) f->tiles[j].material_type = initial_material_type; } - - u8 i; - ContentFeatures *f = NULL; - - i = CONTENT_STONE; - f = &g_content_features[i]; - f->setAllTextures("stone.png"); - f->setInventoryTextureCube("stone.png", "stone.png", "stone.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 1"; - - i = CONTENT_GRASS; - f = &g_content_features[i]; - f->setAllTextures("mud.png^grass_side.png"); - f->setTexture(0, "grass.png"); - f->setTexture(1, "mud.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1"; - - i = CONTENT_GRASS_FOOTSTEPS; - f = &g_content_features[i]; - f->setAllTextures("mud.png^grass_side.png"); - f->setTexture(0, "grass_footsteps.png"); - f->setTexture(1, "mud.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(CONTENT_MUD)+" 1"; - - i = CONTENT_MUD; - f = &g_content_features[i]; - f->setAllTextures("mud.png"); - f->setInventoryTextureCube("mud.png", "mud.png", "mud.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_SAND; - f = &g_content_features[i]; - f->setAllTextures("sand.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_TREE; - f = &g_content_features[i]; - f->setAllTextures("tree.png"); - f->setTexture(0, "tree_top.png"); - f->setTexture(1, "tree_top.png"); - f->param_type = CPT_MINERAL; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_LEAVES; - f = &g_content_features[i]; - f->light_propagates = true; - //f->param_type = CPT_MINERAL; - f->param_type = CPT_LIGHT; - f->is_ground_content = true; - if(new_style_leaves) - { - f->solidness = 0; // drawn separately, makes no faces - f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png"); - } - else - { - f->setAllTextures("[noalpha:leaves.png"); - } - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_GLASS; - f = &g_content_features[i]; - f->light_propagates = true; - f->param_type = CPT_LIGHT; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - f->solidness = 0; // drawn separately, makes no faces - f->setInventoryTextureCube("glass.png", "glass.png", "glass.png"); - - i = CONTENT_FENCE; - f = &g_content_features[i]; - f->light_propagates = true; - f->param_type = CPT_LIGHT; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - f->solidness = 0; // drawn separately, makes no faces - f->air_equivalent = true; // grass grows underneath - f->setInventoryTexture("item_fence.png"); - - // Deprecated - i = CONTENT_COALSTONE; - f = &g_content_features[i]; - //f->translate_to = new MapNode(CONTENT_STONE, MINERAL_COAL); - f->setAllTextures("stone.png^mineral_coal.png"); - f->is_ground_content = true; - - i = CONTENT_WOOD; - f = &g_content_features[i]; - f->setAllTextures("wood.png"); - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_MESE; - f = &g_content_features[i]; - f->setAllTextures("mese.png"); - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_CLOUD; - f = &g_content_features[i]; - f->setAllTextures("cloud.png"); - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_AIR; - f = &g_content_features[i]; - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->sunlight_propagates = true; - f->solidness = 0; - f->walkable = false; - f->pointable = false; - f->diggable = false; - f->buildable_to = true; - f->air_equivalent = true; - - i = CONTENT_WATER; - f = &g_content_features[i]; - f->setInventoryTextureCube("water.png", "water.png", "water.png"); - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->solidness = 0; // Drawn separately, makes no faces - f->walkable = false; - f->pointable = false; - f->diggable = false; - f->buildable_to = true; - f->liquid_type = LIQUID_FLOWING; - - i = CONTENT_WATERSOURCE; - f = &g_content_features[i]; - f->setInventoryTexture("water.png"); - if(new_style_water) - { - f->solidness = 0; // drawn separately, makes no faces - } - else // old style - { - f->solidness = 1; - TileSpec t; - if(g_texturesource) - t.texture = g_texturesource->getTexture("water.png"); - - t.alpha = WATER_ALPHA; - t.material_type = MATERIAL_ALPHA_VERTEX; - t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; - f->setAllTiles(t); - } - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->walkable = false; - f->pointable = false; - f->diggable = false; - f->buildable_to = true; - f->liquid_type = LIQUID_SOURCE; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_TORCH; - f = &g_content_features[i]; - f->setInventoryTexture("torch_on_floor.png"); - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->sunlight_propagates = true; - f->solidness = 0; // drawn separately, makes no faces - f->walkable = false; - f->wall_mounted = true; - f->air_equivalent = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_SIGN_WALL; - f = &g_content_features[i]; - f->setInventoryTexture("sign_wall.png"); - f->param_type = CPT_LIGHT; - f->light_propagates = true; - f->sunlight_propagates = true; - f->solidness = 0; // drawn separately, makes no faces - f->walkable = false; - f->wall_mounted = true; - f->air_equivalent = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - if(f->initial_metadata == NULL) - f->initial_metadata = new SignNodeMetadata("Some sign"); - - i = CONTENT_CHEST; - f = &g_content_features[i]; - f->param_type = CPT_FACEDIR_SIMPLE; - f->setAllTextures("chest_side.png"); - f->setTexture(0, "chest_top.png"); - f->setTexture(1, "chest_top.png"); - f->setTexture(5, "chest_front.png"); // Z- - f->setInventoryTexture("chest_top.png"); - //f->setInventoryTextureCube("chest_top.png", "chest_side.png", "chest_side.png"); - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - if(f->initial_metadata == NULL) - f->initial_metadata = new ChestNodeMetadata(); - - i = CONTENT_FURNACE; - f = &g_content_features[i]; - f->param_type = CPT_FACEDIR_SIMPLE; - f->setAllTextures("furnace_side.png"); - f->setTexture(5, "furnace_front.png"); // Z- - f->setInventoryTexture("furnace_front.png"); - //f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - f->dug_item = std::string("MaterialItem ")+itos(CONTENT_COBBLE)+" 6"; - if(f->initial_metadata == NULL) - f->initial_metadata = new FurnaceNodeMetadata(); - - i = CONTENT_COBBLE; - f = &g_content_features[i]; - f->setAllTextures("cobble.png"); - f->setInventoryTextureCube("cobble.png", "cobble.png", "cobble.png"); - f->param_type = CPT_NONE; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; - - i = CONTENT_STEEL; - f = &g_content_features[i]; - f->setAllTextures("steel_block.png"); - f->setInventoryTextureCube("steel_block.png", "steel_block.png", - "steel_block.png"); - f->param_type = CPT_NONE; - f->is_ground_content = true; - f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; + /* + Initialize mapnode content + */ + content_mapnode_init(); - // NOTE: Remember to add frequently used stuff to the texture atlas in tile.cpp } v3s16 facedir_rotate(u8 facedir, v3s16 dir) @@ -459,16 +230,4 @@ u8 MapNode::getMineral() return MINERAL_NONE; } -// Pointers to c_str()s g_content_features[i].inventory_image_path -//const char * g_content_inventory_texture_paths[USEFUL_CONTENT_COUNT] = {0}; - -void init_content_inventory_texture_paths() -{ - dstream<<"DEPRECATED "<<__FUNCTION_NAME< CONTENT_WATER // CONTENT_LAVA || CONTENT_LAVASOURCE -> CONTENT_LAVA +// NOTE: Don't use, use "content_features(m).whatever" instead inline u8 make_liquid_flowing(u8 m) { - if(m == CONTENT_WATER || m == CONTENT_WATERSOURCE) - return CONTENT_WATER; - assert(0); + u8 c = content_features(m).liquid_alternative_flowing; + assert(c != CONTENT_IGNORE); + return c; } - // Pointable contents can be pointed to in the map // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_pointable(u8 m) { return content_features(m).pointable; - //return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE); } - // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_diggable(u8 m) { return content_features(m).diggable; - //return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_WATERSOURCE); } - // NOTE: Don't use, use "content_features(m).whatever" instead inline bool content_buildable_to(u8 m) { return content_features(m).buildable_to; - //return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_WATERSOURCE); } -/* - Returns true for contents that form the base ground that - follows the main heightmap -*/ -/*inline bool is_ground_content(u8 m) -{ - return content_features(m).is_ground_content; -}*/ - /* Nodes make a face if contents differ and solidness differs. Return value: @@ -493,31 +449,25 @@ struct MapNode && param == other.param && param2 == other.param2); } - + + /* + These four are DEPRECATED I guess. -c55 + */ bool light_propagates() { return light_propagates_content(d); } - bool sunlight_propagates() { return sunlight_propagates_content(d); } - u8 solidness() { return content_solidness(d); } - u8 light_source() { - /* - Note that a block that isn't light_propagates() can be a light source. - */ - if(d == CONTENT_TORCH) - return LIGHT_MAX; - - return 0; + return content_features(d).light_source; } u8 getLightBanksWithSource() @@ -537,11 +487,6 @@ struct MapNode return (lightday&0x0f) | ((lightnight<<4)&0xf0); } - void setLightBanks(u8 a_light) - { - param = a_light; - } - u8 getLight(enum LightBank bank) { // Select the brightest of [light source, propagated light] @@ -606,13 +551,25 @@ struct MapNode } // In mapnode.cpp + /* + Get tile of a face of the node. + dir: direction of face + Returns: TileSpec. Can contain miscellaneous texture coordinates, + which must be obeyed so that the texture atlas can be used. + */ TileSpec getTile(v3s16 dir); - + + /* + Gets mineral content of node, if there is any. + MINERAL_NONE if doesn't contain or isn't able to contain mineral. + */ u8 getMineral(); /* These serialization functions are used when informing client - of a single node add + of a single node add. + + NOTE: When loading a MapBlock, these are not used. Should they? */ static u32 serializedLength(u8 version) diff --git a/src/materials.cpp b/src/materials.cpp index 841f1d655..e3a24b9e3 100644 --- a/src/materials.cpp +++ b/src/materials.cpp @@ -1,112 +1,20 @@ #include "materials.h" +#include "mapnode.h" -#define MATERIAL_PROPERTIES_COUNT 256 +// NOTE: DEPRECATED -// These correspond to the CONTENT_* constants -MaterialProperties g_material_properties[MATERIAL_PROPERTIES_COUNT]; - -bool g_material_properties_initialized = false; - -void setStoneLikeDiggingProperties(u8 material, float toughness) -{ - g_material_properties[material].setDiggingProperties("", - DiggingProperties(true, 15.0*toughness, 0)); - - g_material_properties[material].setDiggingProperties("WPick", - DiggingProperties(true, 1.3*toughness, 65535./30.*toughness)); - g_material_properties[material].setDiggingProperties("STPick", - DiggingProperties(true, 0.75*toughness, 65535./100.*toughness)); - g_material_properties[material].setDiggingProperties("SteelPick", - DiggingProperties(true, 0.50*toughness, 65535./333.*toughness)); - - /*g_material_properties[material].setDiggingProperties("MesePick", - DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/ -} - -void setDirtLikeDiggingProperties(u8 material, float toughness) -{ - g_material_properties[material].setDiggingProperties("", - DiggingProperties(true, 0.75*toughness, 0)); - - g_material_properties[material].setDiggingProperties("WShovel", - DiggingProperties(true, 0.4*toughness, 65535./50.*toughness)); - g_material_properties[material].setDiggingProperties("STShovel", - DiggingProperties(true, 0.2*toughness, 65535./150.*toughness)); - g_material_properties[material].setDiggingProperties("SteelShovel", - DiggingProperties(true, 0.15*toughness, 65535./400.*toughness)); -} - -void setWoodLikeDiggingProperties(u8 material, float toughness) -{ - g_material_properties[material].setDiggingProperties("", - DiggingProperties(true, 3.0*toughness, 0)); - - g_material_properties[material].setDiggingProperties("WAxe", - DiggingProperties(true, 1.5*toughness, 65535./30.*toughness)); - g_material_properties[material].setDiggingProperties("STAxe", - DiggingProperties(true, 0.75*toughness, 65535./100.*toughness)); - g_material_properties[material].setDiggingProperties("SteelAxe", - DiggingProperties(true, 0.5*toughness, 65535./333.*toughness)); -} - -void initializeMaterialProperties() -{ - /* - Now, the g_material_properties array is already initialized - by the constructors to such that no digging is possible. - - Add some digging properties to them. - */ - - setStoneLikeDiggingProperties(CONTENT_STONE, 1.0); - setStoneLikeDiggingProperties(CONTENT_MESE, 0.5); - setStoneLikeDiggingProperties(CONTENT_COALSTONE, 1.5); - setStoneLikeDiggingProperties(CONTENT_FURNACE, 3.0); - setStoneLikeDiggingProperties(CONTENT_COBBLE, 1.0); - setStoneLikeDiggingProperties(CONTENT_STEEL, 5.0); - - setDirtLikeDiggingProperties(CONTENT_MUD, 1.0); - setDirtLikeDiggingProperties(CONTENT_GRASS, 1.0); - setDirtLikeDiggingProperties(CONTENT_GRASS_FOOTSTEPS, 1.0); - setDirtLikeDiggingProperties(CONTENT_SAND, 1.0); - - setWoodLikeDiggingProperties(CONTENT_TREE, 1.0); - setWoodLikeDiggingProperties(CONTENT_LEAVES, 0.15); - setWoodLikeDiggingProperties(CONTENT_GLASS, 0.15); - setWoodLikeDiggingProperties(CONTENT_FENCE, 0.75); - setWoodLikeDiggingProperties(CONTENT_WOOD, 0.75); - setWoodLikeDiggingProperties(CONTENT_CHEST, 1.0); - - g_material_properties[CONTENT_SIGN_WALL].setDiggingProperties("", - DiggingProperties(true, 0.5, 0)); - g_material_properties[CONTENT_TORCH].setDiggingProperties("", - DiggingProperties(true, 0.0, 0)); - - /* - Add MesePick to everything - */ - for(u16 i=0; igetDiggingProperties(tool); + return mprop->get(tool); } diff --git a/src/materials.h b/src/materials.h index 422149753..272116d83 100644 --- a/src/materials.h +++ b/src/materials.h @@ -25,7 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "common_irrlicht.h" -#include "inventory.h" #include struct DiggingProperties @@ -49,20 +48,26 @@ struct DiggingProperties u16 wear; }; -class MaterialProperties +/* + This is a DEPRECATED way of determining mining characteristics. + TODO: Get rid of this and set up some attributes like toughness, + fluffyness, and a funciton to calculate time and durability loss + (and sound? and whatever else) from them +*/ +class DiggingPropertiesList { public: - MaterialProperties() + DiggingPropertiesList() { } - void setDiggingProperties(const std::string toolname, + void set(const std::string toolname, const DiggingProperties &prop) { m_digging_properties[toolname] = prop; } - DiggingProperties getDiggingProperties(const std::string toolname) + DiggingProperties get(const std::string toolname) { core::map::Node *n; n = m_digging_properties.find(toolname); @@ -80,16 +85,17 @@ public: return n->getValue(); } + void clear() + { + m_digging_properties.clear(); + } + private: // toolname="": default properties (digging by hand) // Key is toolname core::map m_digging_properties; }; -void initializeMaterialProperties(); - -// Material correspond to the CONTENT_* constants -MaterialProperties * getMaterialProperties(u8 material); // For getting the default properties, set tool="" DiggingProperties getDiggingProperties(u8 material, const std::string &tool); diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index 6822173cb..1fc4c93a1 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "exceptions.h" #include "inventory.h" #include +#include "content_mapnode.h" /* NodeMetadata diff --git a/src/server.cpp b/src/server.cpp index 16ad80c00..70448fbf6 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "config.h" #include "servercommand.h" #include "filesys.h" +#include "content_mapnode.h" #define BLOCK_EMERGE_FLAG_FROMDISK (1<<0) diff --git a/src/servermain.cpp b/src/servermain.cpp index 907d0d2db..6eb45ea22 100644 --- a/src/servermain.cpp +++ b/src/servermain.cpp @@ -152,7 +152,7 @@ int main(int argc, char *argv[]) DSTACK(__FUNCTION_NAME); // Init material properties table - initializeMaterialProperties(); + //initializeMaterialProperties(); // Debug handler BEGIN_DEBUG_EXCEPTION_HANDLER diff --git a/src/test.cpp b/src/test.cpp index 07ef772ef..38497136d 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "voxel.h" #include #include "porting.h" +#include "content_mapnode.h" /* Asserts that the exception occurs diff --git a/src/voxel.cpp b/src/voxel.cpp index f60b641f1..5938f9016 100644 --- a/src/voxel.cpp +++ b/src/voxel.cpp @@ -19,10 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "voxel.h" #include "map.h" - -// For TimeTaker -#include "utility.h" +#include "utility.h" // For TimeTaker #include "gettime.h" +#include "content_mapnode.h" /* Debug stuff -- cgit v1.2.3 From e7580d2804d29afb486f4eb2bd4dfb94f7181824 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Fri, 17 Jun 2011 23:55:21 +0300 Subject: added in-game key shortcuts for toggling free_move and fast_move (default K and J) --- src/defaultsettings.cpp | 2 ++ src/game.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) (limited to 'src/game.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index e57157a82..8ae5694e5 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -40,6 +40,8 @@ void set_default_settings() g_settings.setDefault("keymap_inventory", "KEY_KEY_I"); g_settings.setDefault("keymap_chat", "KEY_KEY_T"); g_settings.setDefault("keymap_rangeselect", "KEY_KEY_R"); + g_settings.setDefault("keymap_freemove", "KEY_KEY_K"); + g_settings.setDefault("keymap_fastmove", "KEY_KEY_J"); // Some (temporary) keys for debugging g_settings.setDefault("keymap_special1", "KEY_KEY_E"); g_settings.setDefault("keymap_print_debug_stacks", "KEY_KEY_P"); diff --git a/src/game.cpp b/src/game.cpp index eef27c805..09f06f4f6 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1190,6 +1190,32 @@ void the_game( &g_menumgr, dest, L""))->drop(); } + else if(input->wasKeyDown(getKeySetting("keymap_freemove"))) + { + if(g_settings.getBool("free_move")) + { + g_settings.set("free_move","false"); + chat_lines.push_back(ChatLine(L"free_move disabled")); + } + else + { + g_settings.set("free_move","true"); + chat_lines.push_back(ChatLine(L"free_move enabled")); + } + } + else if(input->wasKeyDown(getKeySetting("keymap_fastmove"))) + { + if(g_settings.getBool("fast_move")) + { + g_settings.set("fast_move","false"); + chat_lines.push_back(ChatLine(L"fast_move disabled")); + } + else + { + g_settings.set("fast_move","true"); + chat_lines.push_back(ChatLine(L"fast_move enabled")); + } + } // Item selection with mouse wheel { -- cgit v1.2.3 From da692355e84f8d1e5210c3c89daf775cf23ec38b Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 00:46:50 +0300 Subject: Created and moved stuff to content_nodemeta.{h,cpp} --- src/CMakeLists.txt | 2 + src/content_craft.cpp | 480 +++++++++++++++++++++++++++++++++++++++++++++ src/content_craft.h | 38 ++++ src/content_mapnode.cpp | 2 +- src/content_nodemeta.cpp | 305 +++++++++++++++++++++++++++++ src/content_nodemeta.h | 91 +++++++++ src/game.cpp | 13 +- src/nodemetadata.cpp | 296 +--------------------------- src/nodemetadata.h | 64 ------ src/server.cpp | 498 +---------------------------------------------- 10 files changed, 938 insertions(+), 851 deletions(-) create mode 100644 src/content_craft.cpp create mode 100644 src/content_craft.h create mode 100644 src/content_nodemeta.cpp create mode 100644 src/content_nodemeta.h (limited to 'src/game.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 10ed8c4af..3ee49f327 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,8 @@ configure_file( ) set(common_SRCS + content_nodemeta.cpp + content_craft.cpp content_mapblock.cpp content_mapnode.cpp auth.cpp diff --git a/src/content_craft.cpp b/src/content_craft.cpp new file mode 100644 index 000000000..32d2e6d48 --- /dev/null +++ b/src/content_craft.cpp @@ -0,0 +1,480 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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 "content_craft.h" +#include "inventory.h" +#include "content_mapnode.h" +#include "player.h" + +/* + items: actually *items[9] + return value: allocates a new item, or returns NULL. +*/ +InventoryItem *craft_get_result(InventoryItem **items) +{ + // Wood + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_TREE); + if(checkItemCombination(items, specs)) + { + return new MaterialItem(CONTENT_WOOD, 4); + } + } + + // Stick + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + if(checkItemCombination(items, specs)) + { + return new CraftItem("Stick", 4); + } + } + + // Fence + { + ItemSpec specs[9]; + specs[3] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[5] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[6] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[8] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new MaterialItem(CONTENT_FENCE, 2); + } + } + + // Sign + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + //return new MapBlockObjectItem("Sign"); + return new MaterialItem(CONTENT_SIGN_WALL, 1); + } + } + + // Torch + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_CRAFT, "lump_of_coal"); + specs[3] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new MaterialItem(CONTENT_TORCH, 4); + } + } + + // Wooden pick + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("WPick", 0); + } + } + + // Stone pick + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("STPick", 0); + } + } + + // Steel pick + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[2] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("SteelPick", 0); + } + } + + // Mese pick + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE); + specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("MesePick", 0); + } + } + + // Wooden shovel + { + ItemSpec specs[9]; + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("WShovel", 0); + } + } + + // Stone shovel + { + ItemSpec specs[9]; + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("STShovel", 0); + } + } + + // Steel shovel + { + ItemSpec specs[9]; + specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("SteelShovel", 0); + } + } + + // Wooden axe + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("WAxe", 0); + } + } + + // Stone axe + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("STAxe", 0); + } + } + + // Steel axe + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("SteelAxe", 0); + } + } + + // Wooden sword + { + ItemSpec specs[9]; + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("WSword", 0); + } + } + + // Stone sword + { + ItemSpec specs[9]; + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("STSword", 0); + } + } + + // Steel sword + { + ItemSpec specs[9]; + specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[4] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); + if(checkItemCombination(items, specs)) + { + return new ToolItem("SteelSword", 0); + } + } + + // Chest + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + specs[8] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); + if(checkItemCombination(items, specs)) + { + return new MaterialItem(CONTENT_CHEST, 1); + } + } + + // Furnace + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + specs[8] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); + if(checkItemCombination(items, specs)) + { + return new MaterialItem(CONTENT_FURNACE, 1); + } + } + + // Steel block + { + ItemSpec specs[9]; + specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[2] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[4] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[5] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[6] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[7] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + specs[8] = ItemSpec(ITEM_CRAFT, "steel_ingot"); + if(checkItemCombination(items, specs)) + { + return new MaterialItem(CONTENT_STEEL, 1); + } + } + + return NULL; +} + +void craft_set_creative_inventory(Player *player) +{ + player->resetInventory(); + + // Give some good tools + { + InventoryItem *item = new ToolItem("MesePick", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("SteelPick", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("SteelAxe", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("SteelShovel", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + + /* + Give materials + */ + + // CONTENT_IGNORE-terminated list + u8 material_items[] = { + CONTENT_TORCH, + CONTENT_COBBLE, + CONTENT_MUD, + CONTENT_STONE, + CONTENT_SAND, + CONTENT_TREE, + CONTENT_LEAVES, + CONTENT_GLASS, + CONTENT_FENCE, + CONTENT_MESE, + CONTENT_WATERSOURCE, + CONTENT_CLOUD, + CONTENT_CHEST, + CONTENT_FURNACE, + CONTENT_SIGN_WALL, + CONTENT_IGNORE + }; + + u8 *mip = material_items; + for(u16 i=0; iinventory.addItem("main", item); + + mip++; + } + +#if 0 + assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE); + + // add torch first + InventoryItem *item = new MaterialItem(CONTENT_TORCH, 1); + player->inventory.addItem("main", item); + + // Then others + for(u16 i=0; iinventory.addItem("main", item); + } +#endif + + /*// Sign + { + InventoryItem *item = new MapBlockObjectItem("Sign Example text"); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + }*/ +} + +void craft_give_initial_stuff(Player *player) +{ + { + InventoryItem *item = new ToolItem("SteelPick", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new MaterialItem(CONTENT_TORCH, 99); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("SteelAxe", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("SteelShovel", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new MaterialItem(CONTENT_COBBLE, 99); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + /*{ + InventoryItem *item = new MaterialItem(CONTENT_MESE, 6); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new MaterialItem(CONTENT_COALSTONE, 6); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new MaterialItem(CONTENT_WOOD, 6); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new CraftItem("Stick", 4); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("WPick", 32000); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("STPick", 32000); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + }*/ + /*// and some signs + for(u16 i=0; i<4; i++) + { + InventoryItem *item = new MapBlockObjectItem("Sign Example text"); + bool r = player->inventory.addItem("main", item); + assert(r == true); + }*/ + /*// Give some other stuff + { + InventoryItem *item = new MaterialItem(CONTENT_TREE, 999); + bool r = player->inventory.addItem("main", item); + assert(r == true); + }*/ +} + diff --git a/src/content_craft.h b/src/content_craft.h new file mode 100644 index 000000000..7a8b4659a --- /dev/null +++ b/src/content_craft.h @@ -0,0 +1,38 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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. +*/ + +#ifndef CONTENT_CRAFT_HEADER +#define CONTENT_CRAFT_HEADER + +class InventoryItem; +class Player; + +/* + items: actually *items[9] + return value: allocates a new item, or returns NULL. +*/ +InventoryItem *craft_get_result(InventoryItem **items); + +void craft_set_creative_inventory(Player *player); + +// Called when give_initial_stuff setting is used +void craft_give_initial_stuff(Player *player); + +#endif + diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 1f1c8e30a..ec236c63d 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_mapnode.h" #include "mapnode.h" -#include "nodemetadata.h" +#include "content_nodemeta.h" // TODO: Get rid of these and set up some attributes like toughness, // fluffyness, and a funciton to calculate time and durability loss diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp new file mode 100644 index 000000000..8627e18d0 --- /dev/null +++ b/src/content_nodemeta.cpp @@ -0,0 +1,305 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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 "content_nodemeta.h" +#include "inventory.h" +#include "content_mapnode.h" + +/* + SignNodeMetadata +*/ + +// Prototype +SignNodeMetadata proto_SignNodeMetadata(""); + +SignNodeMetadata::SignNodeMetadata(std::string text): + m_text(text) +{ + NodeMetadata::registerType(typeId(), create); +} +u16 SignNodeMetadata::typeId() const +{ + return CONTENT_SIGN_WALL; +} +NodeMetadata* SignNodeMetadata::create(std::istream &is) +{ + std::string text = deSerializeString(is); + return new SignNodeMetadata(text); +} +NodeMetadata* SignNodeMetadata::clone() +{ + return new SignNodeMetadata(m_text); +} +void SignNodeMetadata::serializeBody(std::ostream &os) +{ + os<addList("0", 8*4); +} +ChestNodeMetadata::~ChestNodeMetadata() +{ + delete m_inventory; +} +u16 ChestNodeMetadata::typeId() const +{ + return CONTENT_CHEST; +} +NodeMetadata* ChestNodeMetadata::create(std::istream &is) +{ + ChestNodeMetadata *d = new ChestNodeMetadata(); + d->m_inventory->deSerialize(is); + return d; +} +NodeMetadata* ChestNodeMetadata::clone() +{ + ChestNodeMetadata *d = new ChestNodeMetadata(); + *d->m_inventory = *m_inventory; + return d; +} +void ChestNodeMetadata::serializeBody(std::ostream &os) +{ + m_inventory->serialize(os); +} +std::string ChestNodeMetadata::infoText() +{ + return "Chest"; +} +bool ChestNodeMetadata::nodeRemovalDisabled() +{ + /* + Disable removal if chest contains something + */ + InventoryList *list = m_inventory->getList("0"); + if(list == NULL) + return false; + if(list->getUsedSlots() == 0) + return false; + return true; +} + +/* + FurnaceNodeMetadata +*/ + +// Prototype +FurnaceNodeMetadata proto_FurnaceNodeMetadata; + +FurnaceNodeMetadata::FurnaceNodeMetadata() +{ + NodeMetadata::registerType(typeId(), create); + + m_inventory = new Inventory(); + m_inventory->addList("fuel", 1); + m_inventory->addList("src", 1); + m_inventory->addList("dst", 4); + + m_step_accumulator = 0; + m_fuel_totaltime = 0; + m_fuel_time = 0; + m_src_totaltime = 0; + m_src_time = 0; +} +FurnaceNodeMetadata::~FurnaceNodeMetadata() +{ + delete m_inventory; +} +u16 FurnaceNodeMetadata::typeId() const +{ + return CONTENT_FURNACE; +} +NodeMetadata* FurnaceNodeMetadata::clone() +{ + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); + *d->m_inventory = *m_inventory; + return d; +} +NodeMetadata* FurnaceNodeMetadata::create(std::istream &is) +{ + FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); + + d->m_inventory->deSerialize(is); + + int temp; + is>>temp; + d->m_fuel_totaltime = (float)temp/10; + is>>temp; + d->m_fuel_time = (float)temp/10; + + return d; +} +void FurnaceNodeMetadata::serializeBody(std::ostream &os) +{ + m_inventory->serialize(os); + os<= m_fuel_totaltime) + { + InventoryList *src_list = m_inventory->getList("src"); + assert(src_list); + InventoryItem *src_item = src_list->getItem(0); + + if(src_item) + return "Furnace is out of fuel"; + else + return "Furnace is inactive"; + } + else + { + std::string s = "Furnace is active ("; + s += itos(m_fuel_time/m_fuel_totaltime*100); + s += "%)"; + return s; + } +} +void FurnaceNodeMetadata::inventoryModified() +{ + dstream<<"Furnace inventory modification callback"< 60.0) + dstream<<"Furnace stepping a long time ("< interval) + { + m_step_accumulator -= interval; + dtime = interval; + + //dstream<<"Furnace step dtime="<getList("dst"); + assert(dst_list); + + InventoryList *src_list = m_inventory->getList("src"); + assert(src_list); + InventoryItem *src_item = src_list->getItem(0); + + // Start only if there are free slots in dst, so that it can + // accomodate any result item + if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable()) + { + m_src_totaltime = 3; + } + else + { + m_src_time = 0; + m_src_totaltime = 0; + } + + /* + If fuel is burning, increment the burn counters. + If item finishes cooking, move it to result. + */ + if(m_fuel_time < m_fuel_totaltime) + { + //dstream<<"Furnace is active"<= m_src_totaltime && m_src_totaltime > 0.001 + && src_item) + { + InventoryItem *cookresult = src_item->createCookResult(); + dst_list->addItem(cookresult); + src_list->decrementMaterials(1); + m_src_time = 0; + m_src_totaltime = 0; + } + changed = true; + continue; + } + + /* + If there is no source item or source item is not cookable, stop loop. + */ + if(src_item == NULL || m_src_totaltime < 0.001) + { + m_step_accumulator = 0; + break; + } + + //dstream<<"Furnace is out of fuel"<getList("fuel"); + assert(fuel_list); + InventoryItem *fuel_item = fuel_list->getItem(0); + + if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item)) + { + m_fuel_totaltime = 30; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item)) + { + m_fuel_totaltime = 30/4; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item)) + { + m_fuel_totaltime = 30/4/4; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item)) + { + m_fuel_totaltime = 40; + m_fuel_time = 0; + fuel_list->decrementMaterials(1); + changed = true; + } + else + { + //dstream<<"No fuel found"< + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 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 General Public License for more details. + +You should have received a copy of the GNU 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. +*/ + +#ifndef CONTENT_NODEMETA_HEADER +#define CONTENT_NODEMETA_HEADER + +#include "nodemetadata.h" + +class Inventory; + +class SignNodeMetadata : public NodeMetadata +{ +public: + SignNodeMetadata(std::string text); + //~SignNodeMetadata(); + + virtual u16 typeId() const; + static NodeMetadata* create(std::istream &is); + virtual NodeMetadata* clone(); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + + std::string getText(){ return m_text; } + void setText(std::string t){ m_text = t; } + +private: + std::string m_text; +}; + +class ChestNodeMetadata : public NodeMetadata +{ +public: + ChestNodeMetadata(); + ~ChestNodeMetadata(); + + virtual u16 typeId() const; + static NodeMetadata* create(std::istream &is); + virtual NodeMetadata* clone(); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + virtual Inventory* getInventory() {return m_inventory;} + + virtual bool nodeRemovalDisabled(); + +private: + Inventory *m_inventory; +}; + +class FurnaceNodeMetadata : public NodeMetadata +{ +public: + FurnaceNodeMetadata(); + ~FurnaceNodeMetadata(); + + virtual u16 typeId() const; + virtual NodeMetadata* clone(); + static NodeMetadata* create(std::istream &is); + virtual void serializeBody(std::ostream &os); + virtual std::string infoText(); + virtual Inventory* getInventory() {return m_inventory;} + virtual void inventoryModified(); + virtual bool step(float dtime); + +private: + Inventory *m_inventory; + float m_step_accumulator; + float m_fuel_totaltime; + float m_fuel_time; + float m_src_totaltime; + float m_src_time; +}; + + +#endif + diff --git a/src/game.cpp b/src/game.cpp index 09f06f4f6..b11547679 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., // TODO: Move content-aware stuff to separate file #include "content_mapnode.h" +#include "content_nodemeta.h" /* Setting this to 1 enables a special camera mode that forces @@ -1730,7 +1731,11 @@ void the_game( dstream<<"Chest node right-clicked"<addList("0", 8*4); -} -ChestNodeMetadata::~ChestNodeMetadata() -{ - delete m_inventory; -} -u16 ChestNodeMetadata::typeId() const -{ - return CONTENT_CHEST; -} -NodeMetadata* ChestNodeMetadata::create(std::istream &is) -{ - ChestNodeMetadata *d = new ChestNodeMetadata(); - d->m_inventory->deSerialize(is); - return d; -} -NodeMetadata* ChestNodeMetadata::clone() -{ - ChestNodeMetadata *d = new ChestNodeMetadata(); - *d->m_inventory = *m_inventory; - return d; -} -void ChestNodeMetadata::serializeBody(std::ostream &os) -{ - m_inventory->serialize(os); -} -std::string ChestNodeMetadata::infoText() -{ - return "Chest"; -} -bool ChestNodeMetadata::nodeRemovalDisabled() -{ - /* - Disable removal if chest contains something - */ - InventoryList *list = m_inventory->getList("0"); - if(list == NULL) - return false; - if(list->getUsedSlots() == 0) - return false; - return true; -} - -/* - FurnaceNodeMetadata -*/ - -// Prototype -FurnaceNodeMetadata proto_FurnaceNodeMetadata; - -FurnaceNodeMetadata::FurnaceNodeMetadata() -{ - NodeMetadata::registerType(typeId(), create); - - m_inventory = new Inventory(); - m_inventory->addList("fuel", 1); - m_inventory->addList("src", 1); - m_inventory->addList("dst", 4); - - m_step_accumulator = 0; - m_fuel_totaltime = 0; - m_fuel_time = 0; - m_src_totaltime = 0; - m_src_time = 0; -} -FurnaceNodeMetadata::~FurnaceNodeMetadata() -{ - delete m_inventory; -} -u16 FurnaceNodeMetadata::typeId() const -{ - return CONTENT_FURNACE; -} -NodeMetadata* FurnaceNodeMetadata::clone() -{ - FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); - *d->m_inventory = *m_inventory; - return d; -} -NodeMetadata* FurnaceNodeMetadata::create(std::istream &is) -{ - FurnaceNodeMetadata *d = new FurnaceNodeMetadata(); - - d->m_inventory->deSerialize(is); - - int temp; - is>>temp; - d->m_fuel_totaltime = (float)temp/10; - is>>temp; - d->m_fuel_time = (float)temp/10; - - return d; -} -void FurnaceNodeMetadata::serializeBody(std::ostream &os) -{ - m_inventory->serialize(os); - os<= m_fuel_totaltime) - { - InventoryList *src_list = m_inventory->getList("src"); - assert(src_list); - InventoryItem *src_item = src_list->getItem(0); - - if(src_item) - return "Furnace is out of fuel"; - else - return "Furnace is inactive"; - } - else - { - std::string s = "Furnace is active ("; - s += itos(m_fuel_time/m_fuel_totaltime*100); - s += "%)"; - return s; - } -} -void FurnaceNodeMetadata::inventoryModified() -{ - dstream<<"Furnace inventory modification callback"< 60.0) - dstream<<"Furnace stepping a long time ("< interval) - { - m_step_accumulator -= interval; - dtime = interval; - - //dstream<<"Furnace step dtime="<getList("dst"); - assert(dst_list); - - InventoryList *src_list = m_inventory->getList("src"); - assert(src_list); - InventoryItem *src_item = src_list->getItem(0); - - // Start only if there are free slots in dst, so that it can - // accomodate any result item - if(dst_list->getFreeSlots() > 0 && src_item && src_item->isCookable()) - { - m_src_totaltime = 3; - } - else - { - m_src_time = 0; - m_src_totaltime = 0; - } - - /* - If fuel is burning, increment the burn counters. - If item finishes cooking, move it to result. - */ - if(m_fuel_time < m_fuel_totaltime) - { - //dstream<<"Furnace is active"<= m_src_totaltime && m_src_totaltime > 0.001 - && src_item) - { - InventoryItem *cookresult = src_item->createCookResult(); - dst_list->addItem(cookresult); - src_list->decrementMaterials(1); - m_src_time = 0; - m_src_totaltime = 0; - } - changed = true; - continue; - } - - /* - If there is no source item or source item is not cookable, stop loop. - */ - if(src_item == NULL || m_src_totaltime < 0.001) - { - m_step_accumulator = 0; - break; - } - - //dstream<<"Furnace is out of fuel"<getList("fuel"); - assert(fuel_list); - InventoryItem *fuel_item = fuel_list->getItem(0); - - if(ItemSpec(ITEM_MATERIAL, CONTENT_TREE).checkItem(fuel_item)) - { - m_fuel_totaltime = 30; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_MATERIAL, CONTENT_WOOD).checkItem(fuel_item)) - { - m_fuel_totaltime = 30/4; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_CRAFT, "Stick").checkItem(fuel_item)) - { - m_fuel_totaltime = 30/4/4; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else if(ItemSpec(ITEM_CRAFT, "lump_of_coal").checkItem(fuel_item)) - { - m_fuel_totaltime = 40; - m_fuel_time = 0; - fuel_list->decrementMaterials(1); - changed = true; - } - else - { - //dstream<<"No fuel found"<step(dtime); if(changed) something_changed = true; - /*if(res.inventory_changed) - { - std::string inv_id; - inv_id += "nodemeta:"; - inv_id += itos(p.X); - inv_id += ","; - inv_id += itos(p.Y); - inv_id += ","; - inv_id += itos(p.Z); - InventoryContext c; - c.current_player = NULL; - inv_mgr->inventoryModified(&c, inv_id); - }*/ } return something_changed; } diff --git a/src/nodemetadata.h b/src/nodemetadata.h index ae02cfc3c..8471e1d97 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -69,74 +69,10 @@ private: static core::map m_types; }; -class SignNodeMetadata : public NodeMetadata -{ -public: - SignNodeMetadata(std::string text); - //~SignNodeMetadata(); - - virtual u16 typeId() const; - static NodeMetadata* create(std::istream &is); - virtual NodeMetadata* clone(); - virtual void serializeBody(std::ostream &os); - virtual std::string infoText(); - - std::string getText(){ return m_text; } - void setText(std::string t){ m_text = t; } - -private: - std::string m_text; -}; - -class ChestNodeMetadata : public NodeMetadata -{ -public: - ChestNodeMetadata(); - ~ChestNodeMetadata(); - - virtual u16 typeId() const; - static NodeMetadata* create(std::istream &is); - virtual NodeMetadata* clone(); - virtual void serializeBody(std::ostream &os); - virtual std::string infoText(); - virtual Inventory* getInventory() {return m_inventory;} - - virtual bool nodeRemovalDisabled(); - -private: - Inventory *m_inventory; -}; - -class FurnaceNodeMetadata : public NodeMetadata -{ -public: - FurnaceNodeMetadata(); - ~FurnaceNodeMetadata(); - - virtual u16 typeId() const; - virtual NodeMetadata* clone(); - static NodeMetadata* create(std::istream &is); - virtual void serializeBody(std::ostream &os); - virtual std::string infoText(); - virtual Inventory* getInventory() {return m_inventory;} - virtual void inventoryModified(); - virtual bool step(float dtime); - -private: - Inventory *m_inventory; - float m_step_accumulator; - float m_fuel_totaltime; - float m_fuel_time; - float m_src_totaltime; - float m_src_time; -}; - /* List of metadata of all the nodes of a block */ -class InventoryManager; - class NodeMetadataList { public: diff --git a/src/server.cpp b/src/server.cpp index 70448fbf6..9fa957c2a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -32,6 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "servercommand.h" #include "filesys.h" #include "content_mapnode.h" +#include "content_craft.h" +#include "content_nodemeta.h" #define BLOCK_EMERGE_FLAG_FROMDISK (1<<0) @@ -3828,334 +3830,10 @@ void Server::UpdateCrafting(u16 peer_id) items[i] = clist->getItem(i); } - bool found = false; - - // Wood - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_TREE); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new MaterialItem(CONTENT_WOOD, 4)); - found = true; - } - } - - // Stick - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new CraftItem("Stick", 4)); - found = true; - } - } - - // Fence - if(!found) - { - ItemSpec specs[9]; - specs[3] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[5] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[6] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[8] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new MaterialItem(CONTENT_FENCE, 2)); - found = true; - } - } - - // Sign - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - //rlist->addItem(new MapBlockObjectItem("Sign")); - rlist->addItem(new MaterialItem(CONTENT_SIGN_WALL, 1)); - found = true; - } - } - - // Torch - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_CRAFT, "lump_of_coal"); - specs[3] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new MaterialItem(CONTENT_TORCH, 4)); - found = true; - } - } - - // Wooden pick - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("WPick", 0)); - found = true; - } - } - - // Stone pick - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("STPick", 0)); - found = true; - } - } - - // Steel pick - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[2] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("SteelPick", 0)); - found = true; - } - } - - // Mese pick - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE); - specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_MESE); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("MesePick", 0)); - found = true; - } - } - - // Wooden shovel - if(!found) - { - ItemSpec specs[9]; - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("WShovel", 0)); - found = true; - } - } - - // Stone shovel - if(!found) - { - ItemSpec specs[9]; - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("STShovel", 0)); - found = true; - } - } - - // Steel shovel - if(!found) - { - ItemSpec specs[9]; - specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("SteelShovel", 0)); - found = true; - } - } - - // Wooden axe - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("WAxe", 0)); - found = true; - } - } - - // Stone axe - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("STAxe", 0)); - found = true; - } - } - - // Steel axe - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[4] = ItemSpec(ITEM_CRAFT, "Stick"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("SteelAxe", 0)); - found = true; - } - } - - // Wooden sword - if(!found) - { - ItemSpec specs[9]; - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("WSword", 0)); - found = true; - } - } - - // Stone sword - if(!found) - { - ItemSpec specs[9]; - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[4] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("STSword", 0)); - found = true; - } - } - - // Steel sword - if(!found) - { - ItemSpec specs[9]; - specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[4] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[7] = ItemSpec(ITEM_CRAFT, "Stick"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new ToolItem("SteelSword", 0)); - found = true; - } - } - - // Chest - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - specs[8] = ItemSpec(ITEM_MATERIAL, CONTENT_WOOD); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new MaterialItem(CONTENT_CHEST, 1)); - found = true; - } - } - - // Furnace - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[1] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[2] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[3] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[5] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[6] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[7] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - specs[8] = ItemSpec(ITEM_MATERIAL, CONTENT_COBBLE); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new MaterialItem(CONTENT_FURNACE, 1)); - found = true; - } - } - - // Steel block - if(!found) - { - ItemSpec specs[9]; - specs[0] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[1] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[2] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[3] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[4] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[5] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[6] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[7] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - specs[8] = ItemSpec(ITEM_CRAFT, "steel_ingot"); - if(checkItemCombination(items, specs)) - { - rlist->addItem(new MaterialItem(CONTENT_STEEL, 1)); - found = true; - } - } + // Get result of crafting grid + InventoryItem *result = craft_get_result(items); + if(result) + rlist->addItem(result); } } // if creative_mode == false @@ -4206,97 +3884,6 @@ std::wstring Server::getStatusString() return os.str(); } - -void setCreativeInventory(Player *player) -{ - player->resetInventory(); - - // Give some good tools - { - InventoryItem *item = new ToolItem("MesePick", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("SteelPick", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("SteelAxe", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("SteelShovel", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - - /* - Give materials - */ - - // CONTENT_IGNORE-terminated list - u8 material_items[] = { - CONTENT_TORCH, - CONTENT_COBBLE, - CONTENT_MUD, - CONTENT_STONE, - CONTENT_SAND, - CONTENT_TREE, - CONTENT_LEAVES, - CONTENT_GLASS, - CONTENT_FENCE, - CONTENT_MESE, - CONTENT_WATERSOURCE, - CONTENT_CLOUD, - CONTENT_CHEST, - CONTENT_FURNACE, - CONTENT_SIGN_WALL, - CONTENT_IGNORE - }; - - u8 *mip = material_items; - for(u16 i=0; iinventory.addItem("main", item); - - mip++; - } - -#if 0 - assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE); - - // add torch first - InventoryItem *item = new MaterialItem(CONTENT_TORCH, 1); - player->inventory.addItem("main", item); - - // Then others - for(u16 i=0; iinventory.addItem("main", item); - } -#endif - - /*// Sign - { - InventoryItem *item = new MapBlockObjectItem("Sign Example text"); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - }*/ -} - v3f findSpawnPos(ServerMap &map) { //return v3f(50,50,50)*BS; @@ -4366,7 +3953,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id // Reset inventory to creative if in creative mode if(g_settings.getBool("creative_mode")) { - setCreativeInventory(player); + craft_set_creative_inventory(player); } return player; @@ -4419,78 +4006,11 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id if(g_settings.getBool("creative_mode")) { - setCreativeInventory(player); + craft_set_creative_inventory(player); } else if(g_settings.getBool("give_initial_stuff")) { - { - InventoryItem *item = new ToolItem("SteelPick", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new MaterialItem(CONTENT_TORCH, 99); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("SteelAxe", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("SteelShovel", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new MaterialItem(CONTENT_COBBLE, 99); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - /*{ - InventoryItem *item = new MaterialItem(CONTENT_MESE, 6); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new MaterialItem(CONTENT_COALSTONE, 6); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new MaterialItem(CONTENT_WOOD, 6); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new CraftItem("Stick", 4); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("WPick", 32000); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("STPick", 32000); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - }*/ - /*// and some signs - for(u16 i=0; i<4; i++) - { - InventoryItem *item = new MapBlockObjectItem("Sign Example text"); - bool r = player->inventory.addItem("main", item); - assert(r == true); - }*/ - /*// Give some other stuff - { - InventoryItem *item = new MaterialItem(CONTENT_TREE, 999); - bool r = player->inventory.addItem("main", item); - assert(r == true); - }*/ + craft_give_initial_stuff(player); } return player; -- cgit v1.2.3 From 931474658dacd32d1847b6718e3d5a33ca8f18ab Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 02:00:01 +0300 Subject: moved inventory menu definition of chest and furnace to content_nodemeta.{h,cpp} --- src/content_nodemeta.cpp | 16 +++++++++ src/content_nodemeta.h | 3 +- src/game.cpp | 87 +++++++++++++++++++----------------------------- src/guiInventoryMenu.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++ src/guiInventoryMenu.h | 6 ++++ src/main.cpp | 3 ++ src/nodemetadata.h | 3 ++ 7 files changed, 145 insertions(+), 54 deletions(-) (limited to 'src/game.cpp') diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp index 8627e18d0..92b2cbada 100644 --- a/src/content_nodemeta.cpp +++ b/src/content_nodemeta.cpp @@ -109,6 +109,13 @@ bool ChestNodeMetadata::nodeRemovalDisabled() return false; return true; } +std::string ChestNodeMetadata::getInventoryDrawSpecString() +{ + return + "invsize[8,9;]" + "list[current_name;0;0,0;8,4;]" + "list[current_player;main;0,5;8,4;]"; +} /* FurnaceNodeMetadata @@ -301,5 +308,14 @@ bool FurnaceNodeMetadata::step(float dtime) } return changed; } +std::string FurnaceNodeMetadata::getInventoryDrawSpecString() +{ + return + "invsize[8,9;]" + "list[current_name;fuel;2,4;1,1;]" + "list[current_name;src;2,1;1,1;]" + "list[current_name;dst;5,1;2,2;]" + "list[current_player;main;0,5;8,4;]"; +} diff --git a/src/content_nodemeta.h b/src/content_nodemeta.h index ed5d5f24e..84c3aed9d 100644 --- a/src/content_nodemeta.h +++ b/src/content_nodemeta.h @@ -55,8 +55,8 @@ public: virtual void serializeBody(std::ostream &os); virtual std::string infoText(); virtual Inventory* getInventory() {return m_inventory;} - virtual bool nodeRemovalDisabled(); + virtual std::string getInventoryDrawSpecString(); private: Inventory *m_inventory; @@ -76,6 +76,7 @@ public: virtual Inventory* getInventory() {return m_inventory;} virtual void inventoryModified(); virtual bool step(float dtime); + virtual std::string getInventoryDrawSpecString(); private: Inventory *m_inventory; diff --git a/src/game.cpp b/src/game.cpp index b11547679..c36688d12 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1709,75 +1709,56 @@ void the_game( { std::cout<typeId() == CONTENT_SIGN_WALL && !random_input) + // If metadata provides an inventory view, activate it + if(meta && meta->getInventoryDrawSpecString() != "" && !random_input) { - dstream<<"Sign node right-clicked"<getText()); - - (new GUITextInputMenu(guienv, guiroot, -1, - &g_menumgr, dest, - wtext))->drop(); - } - else if(meta && meta->typeId() == CONTENT_CHEST && !random_input) - { - dstream<<"Chest node right-clicked"< draw_spec; + v2s16 invsize = + GUIInventoryMenu::makeDrawSpecArrayFromString( + draw_spec, + meta->getInventoryDrawSpecString(), + current_name); + GUIInventoryMenu *menu = new GUIInventoryMenu(guienv, guiroot, -1, - &g_menumgr, v2s16(8,9), + &g_menumgr, invsize, client.getInventoryContext(), &client); - - core::array draw_spec; - - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", chest_inv_id, "0", - v2s32(0, 0), v2s32(8, 4))); - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", "current_player", "main", - v2s32(0, 5), v2s32(8, 4))); - menu->setDrawSpec(draw_spec); - menu->drop(); - } - else if(meta && meta->typeId() == CONTENT_FURNACE && !random_input) + else if(meta && meta->typeId() == CONTENT_SIGN_WALL && !random_input) { - dstream<<"Furnace node right-clicked"<drop(); + TextDest *dest = new TextDestSignNode(nodepos, &client); + + std::wstring wtext = + narrow_to_wide(signmeta->getText()); + (new GUITextInputMenu(guienv, guiroot, -1, + &g_menumgr, dest, + wtext))->drop(); } else { diff --git a/src/guiInventoryMenu.cpp b/src/guiInventoryMenu.cpp index a4ba472f8..786a4dd22 100644 --- a/src/guiInventoryMenu.cpp +++ b/src/guiInventoryMenu.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiInventoryMenu.h" #include "constants.h" #include "keycode.h" +#include "strfnd.h" void drawInventoryItem(video::IVideoDriver *driver, gui::IGUIFont *font, @@ -412,5 +413,85 @@ bool GUIInventoryMenu::OnEvent(const SEvent& event) return Parent ? Parent->OnEvent(event) : false; } +/* + Here is an example traditional set-up sequence for a DrawSpec list: + + std::string furnace_inv_id = "nodemetadata:0,1,2"; + core::array draw_spec; + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", furnace_inv_id, "fuel", + v2s32(2, 3), v2s32(1, 1))); + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", furnace_inv_id, "src", + v2s32(2, 1), v2s32(1, 1))); + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", furnace_inv_id, "dst", + v2s32(5, 1), v2s32(2, 2))); + draw_spec.push_back(GUIInventoryMenu::DrawSpec( + "list", "current_player", "main", + v2s32(0, 5), v2s32(8, 4))); + setDrawSpec(draw_spec); + + Here is the string for creating the same DrawSpec list (a single line, + spread to multiple lines here): + + GUIInventoryMenu::makeDrawSpecArrayFromString( + draw_spec, + "nodemetadata:0,1,2", + "invsize[8,9;]" + "list[current_name;fuel;2,3;1,1;]" + "list[current_name;src;2,1;1,1;]" + "list[current_name;dst;5,1;2,2;]" + "list[current_player;main;0,5;8,4;]"); + + Returns inventory menu size defined by invsize[]. +*/ +v2s16 GUIInventoryMenu::makeDrawSpecArrayFromString( + core::array &draw_spec, + const std::string &data, + const std::string ¤t_name) +{ + v2s16 invsize(8,9); + Strfnd f(data); + while(f.atend() == false) + { + std::string type = trim(f.next("[")); + //dstream<<"type="< &draw_spec, + const std::string &data, + const std::string ¤t_name); GUIInventoryMenu(gui::IGUIEnvironment* env, gui::IGUIElement* parent, s32 id, diff --git a/src/main.cpp b/src/main.cpp index 455e0ac9b..71ab5d037 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -335,6 +335,9 @@ Misc. stuff: - Finish the ActiveBlockModifier stuff and use it for something - Move mineral to param2, increment map serialization version, add conversion +TODO: Create a common interface-whatever-thing to implement custom + special blocks with an inventory menu + Making it more portable: ------------------------ diff --git a/src/nodemetadata.h b/src/nodemetadata.h index 8471e1d97..de682f9b6 100644 --- a/src/nodemetadata.h +++ b/src/nodemetadata.h @@ -62,6 +62,9 @@ public: // A step in time. Returns true if metadata changed. virtual bool step(float dtime) {return false;} virtual bool nodeRemovalDisabled(){return false;} + // Used to make custom inventory menus. + // See format in guiInventoryMenu.cpp. + virtual std::string getInventoryDrawSpecString(){return "";} protected: static void registerType(u16 id, Factory f); -- cgit v1.2.3 From c391bcee1698beabaec76ed13361d2930cb22f94 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 02:32:34 +0300 Subject: removed furnace menu because it is not needed anymore --- src/CMakeLists.txt | 1 - src/game.cpp | 1 - src/guiFurnaceMenu.cpp | 58 -------------------------------------------------- src/guiFurnaceMenu.h | 44 -------------------------------------- src/main.cpp | 3 --- 5 files changed, 107 deletions(-) delete mode 100644 src/guiFurnaceMenu.cpp delete mode 100644 src/guiFurnaceMenu.h (limited to 'src/game.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64e63e272..e6df823b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -95,7 +95,6 @@ set(minetest_SRCS keycode.cpp clouds.cpp clientobject.cpp - guiFurnaceMenu.cpp guiMainMenu.cpp guiMessageMenu.cpp guiTextInputMenu.cpp diff --git a/src/game.cpp b/src/game.cpp index c36688d12..d9bbe795e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -25,7 +25,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiPasswordChange.h" #include "guiInventoryMenu.h" #include "guiTextInputMenu.h" -#include "guiFurnaceMenu.h" #include "materials.h" #include "config.h" #include "clouds.h" diff --git a/src/guiFurnaceMenu.cpp b/src/guiFurnaceMenu.cpp deleted file mode 100644 index 9a998ce73..000000000 --- a/src/guiFurnaceMenu.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 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 General Public License for more details. - -You should have received a copy of the GNU 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 "guiFurnaceMenu.h" -#include "client.h" - -GUIFurnaceMenu::GUIFurnaceMenu( - gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, - IMenuManager *menumgr, - v3s16 nodepos, - Client *client - ): - GUIInventoryMenu(env, parent, id, menumgr, v2s16(8,9), - client->getInventoryContext(), client), - m_nodepos(nodepos), - m_client(client) -{ - std::string furnace_inv_id; - furnace_inv_id += "nodemeta:"; - furnace_inv_id += itos(nodepos.X); - furnace_inv_id += ","; - furnace_inv_id += itos(nodepos.Y); - furnace_inv_id += ","; - furnace_inv_id += itos(nodepos.Z); - - core::array draw_spec; - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", furnace_inv_id, "fuel", - v2s32(2, 3), v2s32(1, 1))); - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", furnace_inv_id, "src", - v2s32(2, 1), v2s32(1, 1))); - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", furnace_inv_id, "dst", - v2s32(5, 1), v2s32(2, 2))); - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", "current_player", "main", - v2s32(0, 5), v2s32(8, 4))); - setDrawSpec(draw_spec); -} - diff --git a/src/guiFurnaceMenu.h b/src/guiFurnaceMenu.h deleted file mode 100644 index ccc2e9dc0..000000000 --- a/src/guiFurnaceMenu.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 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 General Public License for more details. - -You should have received a copy of the GNU 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. -*/ - -#ifndef GUIFURNACEMENU_HEADER -#define GUIFURNACEMENU_HEADER - -#include "guiInventoryMenu.h" - -class Client; - -class GUIFurnaceMenu : public GUIInventoryMenu -{ -public: - GUIFurnaceMenu( - gui::IGUIEnvironment* env, - gui::IGUIElement* parent, s32 id, - IMenuManager *menumgr, - v3s16 nodepos, - Client *client - ); -private: - - v3s16 m_nodepos; - Client *m_client; -}; - -#endif - diff --git a/src/main.cpp b/src/main.cpp index 71ab5d037..455e0ac9b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -335,9 +335,6 @@ Misc. stuff: - Finish the ActiveBlockModifier stuff and use it for something - Move mineral to param2, increment map serialization version, add conversion -TODO: Create a common interface-whatever-thing to implement custom - special blocks with an inventory menu - Making it more portable: ------------------------ -- cgit v1.2.3 From 4a6e6cee2087deaf45d741154d03227774bb5168 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 08:50:14 +0300 Subject: enabled word wrap in chat --- src/game.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/game.cpp') diff --git a/src/game.cpp b/src/game.cpp index d9bbe795e..4d943f45f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -871,8 +871,8 @@ void the_game( gui::IGUIStaticText *guitext_chat = guienv->addStaticText( L"", core::rect(0,0,0,0), - false, false); // Disable word wrap as of now - //false, true); + //false, false); // Disable word wrap as of now + false, true); //guitext_chat->setBackgroundColor(video::SColor(96,0,0,0)); core::list chat_lines; @@ -1996,7 +1996,7 @@ void the_game( 10, 50, screensize.X - 10, - 50 + text_height*chat_lines.size() + 50 + guitext_chat->getTextHeight() ); guitext_chat->setRelativePosition(rect); -- cgit v1.2.3 From 0bd1b782d0134180ae1af692533f1c59e29a03de Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 09:04:31 +0300 Subject: modified health bar a bit --- data/heart.png | Bin 220 -> 308 bytes src/game.cpp | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/game.cpp') diff --git a/data/heart.png b/data/heart.png index ddd273dd2..6bc183e04 100644 Binary files a/data/heart.png and b/data/heart.png differ diff --git a/src/game.cpp b/src/game.cpp index 4d943f45f..7ad7746ad 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -362,7 +362,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font, core::rect(core::position2d(0,0), core::dimension2di(heart_texture->getOriginalSize())), NULL, colors, true); - p += v2s32(20,0); + p += v2s32(16,0); } if(halfheartcount % 2 == 1) { @@ -375,7 +375,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font, driver->draw2DImage(heart_texture, rect, core::rect(core::position2d(0,0), srcd), NULL, colors, true); - p += v2s32(20,0); + p += v2s32(16,0); } } } -- cgit v1.2.3 From 7773e68c2a42659b4a34af56e1fc799ffc9362ed Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 12:42:17 +0300 Subject: farmesh is now usable. --- src/client.h | 2 + src/defaultsettings.cpp | 4 +- src/farmesh.cpp | 228 ++++++++++++++++++++++++++++++++++++++++-------- src/farmesh.h | 22 ++--- src/game.cpp | 24 +++-- src/map.cpp | 37 ++++++-- src/map.h | 16 ++-- 7 files changed, 258 insertions(+), 75 deletions(-) (limited to 'src/game.cpp') diff --git a/src/client.h b/src/client.h index 1bfbe6296..a1b1c66b4 100644 --- a/src/client.h +++ b/src/client.h @@ -450,6 +450,8 @@ private: InventoryContext m_inventory_context; Queue m_client_event_queue; + + friend class FarMesh; }; #endif // !SERVER diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 8ae5694e5..209d20b63 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -49,7 +49,7 @@ void set_default_settings() g_settings.setDefault("wanted_fps", "30"); g_settings.setDefault("fps_max", "60"); g_settings.setDefault("viewing_range_nodes_max", "300"); - g_settings.setDefault("viewing_range_nodes_min", "35"); + g_settings.setDefault("viewing_range_nodes_min", "28"); g_settings.setDefault("screenW", "800"); g_settings.setDefault("screenH", "600"); g_settings.setDefault("address", ""); @@ -67,7 +67,7 @@ void set_default_settings() g_settings.setDefault("continuous_forward", "false"); g_settings.setDefault("fast_move", "false"); g_settings.setDefault("invert_mouse", "false"); - g_settings.setDefault("enable_farmesh", "false"); + g_settings.setDefault("enable_farmesh", "true"); g_settings.setDefault("enable_clouds", "true"); // Server stuff diff --git a/src/farmesh.cpp b/src/farmesh.cpp index e4847966f..3faac163d 100644 --- a/src/farmesh.cpp +++ b/src/farmesh.cpp @@ -27,26 +27,52 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "debug.h" #include "noise.h" #include "map.h" +#include "client.h" + +/* + Temporarily exposed map generator stuff + Should only be used for testing +*/ +extern double base_rock_level_2d(u64 seed, v2s16 p); +extern double get_mud_add_amount(u64 seed, v2s16 p); +extern bool get_have_sand(u64 seed, v2s16 p2d); +extern double tree_amount_2d(u64 seed, v2s16 p); + FarMesh::FarMesh( scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, - u64 seed + u64 seed, + Client *client ): scene::ISceneNode(parent, mgr, id), m_seed(seed), m_camera_pos(0,0), - m_time(0) + m_time(0), + m_client(client) { dstream<<__FUNCTION_NAME<getVideoDriver(); - m_material.setFlag(video::EMF_LIGHTING, false); - m_material.setFlag(video::EMF_BACK_FACE_CULLING, true); - m_material.setFlag(video::EMF_BILINEAR_FILTER, false); - m_material.setFlag(video::EMF_FOG_ENABLE, false); - //m_material.setFlag(video::EMF_ANTI_ALIASING, true); - //m_material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + m_materials[0].setFlag(video::EMF_LIGHTING, false); + m_materials[0].setFlag(video::EMF_BACK_FACE_CULLING, true); + //m_materials[0].setFlag(video::EMF_BACK_FACE_CULLING, false); + m_materials[0].setFlag(video::EMF_BILINEAR_FILTER, false); + m_materials[0].setFlag(video::EMF_FOG_ENABLE, false); + //m_materials[0].setFlag(video::EMF_ANTI_ALIASING, true); + //m_materials[0].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + m_materials[0].setFlag(video::EMF_FOG_ENABLE, true); + + m_materials[1].setFlag(video::EMF_LIGHTING, false); + m_materials[1].setFlag(video::EMF_BACK_FACE_CULLING, false); + m_materials[1].setFlag(video::EMF_BILINEAR_FILTER, false); + m_materials[1].setFlag(video::EMF_FOG_ENABLE, false); + m_materials[1].setTexture + (0, driver->getTexture(getTexturePath("treeprop.png").c_str())); + m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + m_materials[1].setFlag(video::EMF_FOG_ENABLE, true); m_box = core::aabbox3d(-BS*1000000,-BS*31000,-BS*1000000, BS*1000000,BS*31000,BS*1000000); @@ -58,13 +84,24 @@ FarMesh::~FarMesh() dstream<<__FUNCTION_NAME<registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); - //SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); - SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX); + SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); + //SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX); } ISceneNode::OnRegisterSceneNode(); @@ -73,18 +110,34 @@ void FarMesh::OnRegisterSceneNode() #define MYROUND(x) (x > 0.0 ? (int)x : (int)x - 1) // Temporary hack -core::map g_heights; +struct HeightPoint +{ + float gh; // ground height + float ma; // mud amount + float have_sand; + float tree_amount; +}; +core::map g_heights; -float ground_height(u64 seed, v2s16 p2d) +HeightPoint ground_height(u64 seed, v2s16 p2d) { - core::map::Node *n = g_heights.find(p2d); + core::map::Node *n = g_heights.find(p2d); if(n) return n->getValue(); - float avg_mud_amount = 4; - float gh = BS*base_rock_level_2d(seed, p2d) + avg_mud_amount*BS; - //gh *= 10; - g_heights[p2d] = gh; - return gh; + HeightPoint hp; + hp.gh = BS*base_rock_level_2d(seed, p2d); + hp.gh -= BS*2; // Lower a bit so that it is not that much in the way + hp.ma = BS*get_mud_add_amount(seed, p2d); + hp.have_sand = get_have_sand(seed, p2d); + if(hp.gh > BS*WATER_LEVEL) + hp.tree_amount = tree_amount_2d(seed, p2d); + else + hp.tree_amount = 0; + // No mud has been added if mud amount is less than 2 + if(hp.ma < 2.0*BS) + hp.ma = 0.0; + g_heights[p2d] = hp; + return hp; } void FarMesh::render() @@ -93,16 +146,17 @@ void FarMesh::render() /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) return;*/ - /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID) - return;*/ - if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SKY_BOX) + if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID) return; + /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SKY_BOX) + return;*/ driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); - driver->setMaterial(m_material); - const s16 grid_radius_i = 12; - const float grid_size = BS*50; + //const s16 grid_radius_i = 12; + //const float grid_size = BS*50; + const s16 grid_radius_i = 20; + const float grid_size = BS*MAP_BLOCKSIZE; const v2f grid_speed(-BS*0, 0); // Position of grid noise origin in world coordinates @@ -125,10 +179,19 @@ void FarMesh::render() for(s16 zi=-grid_radius_i; zi -dd && zi < dd && xi > -dd && xi < dd) + continue;*/ + v2s16 p_in_noise_i( xi+center_of_drawing_in_noise_i.X, zi+center_of_drawing_in_noise_i.Y ); + + // If sector was drawn, don't draw it this way + if(m_client->m_env.getClientMap().sectorWasDrawn(p_in_noise_i)) + continue; /*if((p_in_noise_i.X + p_in_noise_i.Y)%2==0) continue;*/ @@ -159,32 +222,50 @@ void FarMesh::render() (float)(p_in_noise_i.Y+0)*grid_size/BS/100, m_seed, 3, 0.5);*/ - float noise[4]; - noise[0] = ground_height(m_seed, v2s16( + HeightPoint hps[5]; + hps[0] = ground_height(m_seed, v2s16( (p_in_noise_i.X+0)*grid_size/BS, (p_in_noise_i.Y+0)*grid_size/BS)); - noise[1] = ground_height(m_seed, v2s16( + hps[1] = ground_height(m_seed, v2s16( (p_in_noise_i.X+0)*grid_size/BS, (p_in_noise_i.Y+1)*grid_size/BS)); - noise[2] = ground_height(m_seed, v2s16( + hps[2] = ground_height(m_seed, v2s16( (p_in_noise_i.X+1)*grid_size/BS, (p_in_noise_i.Y+1)*grid_size/BS)); - noise[3] = ground_height(m_seed, v2s16( + hps[3] = ground_height(m_seed, v2s16( (p_in_noise_i.X+1)*grid_size/BS, (p_in_noise_i.Y+0)*grid_size/BS)); - + v2s16 centerpoint( + (p_in_noise_i.X+0)*grid_size/BS+MAP_BLOCKSIZE/2, + (p_in_noise_i.Y+0)*grid_size/BS+MAP_BLOCKSIZE/2); + hps[4] = ground_height(m_seed, centerpoint); + + float noise[5]; float h_min = BS*65535; float h_max = -BS*65536; - for(u32 i=0; i<4; i++) + float ma_avg = 0; + float h_avg = 0; + u32 have_sand_count = 0; + float tree_amount_avg = 0; + for(u32 i=0; i<5; i++) { + noise[i] = hps[i].gh + hps[i].ma; if(noise[i] < h_min) h_min = noise[i]; if(noise[i] > h_max) h_max = noise[i]; + ma_avg += hps[i].ma; + h_avg += noise[i]; + if(hps[i].have_sand) + have_sand_count++; + tree_amount_avg += hps[i].tree_amount; } + ma_avg /= 5.0; + h_avg /= 5.0; + tree_amount_avg /= 5.0; + float steepness = (h_max - h_min)/grid_size; - float h_avg = (noise[0]+noise[1]+noise[2]+noise[3])/4.0; float light_f = noise[0]+noise[1]-noise[2]-noise[3]; light_f /= 100; if(light_f < -1.0) light_f = -1.0; @@ -198,7 +279,9 @@ void FarMesh::render() // Detect water if(h_avg < WATER_LEVEL*BS && h_max < (WATER_LEVEL+5)*BS) { - c = video::SColor(128,59,86,146); + //c = video::SColor(255,59,86,146); + c = video::SColor(255,82,120,204); + /*// Set to water level for(u32 i=0; i<4; i++) { @@ -207,10 +290,33 @@ void FarMesh::render() }*/ light_f = 0; } + // Steep cliffs else if(steepness > 2.0) - c = video::SColor(128,128,128,128); + { + c = video::SColor(255,128,128,128); + } + // Basic ground else - c = video::SColor(128,107,134,51); + { + if(ma_avg < 2.0*BS) + { + c = video::SColor(255,128,128,128); + } + else + { + if(h_avg <= 2.5*BS && have_sand_count >= 2) + c = video::SColor(255,210,194,156); + else + { + /*// Trees if there are over 0.01 trees per MapNode + if(tree_amount_avg > 0.01) + c = video::SColor(255,50,128,50); + else + c = video::SColor(255,107,134,51);*/ + c = video::SColor(255,107,134,51); + } + } + } // Set to water level for(u32 i=0; i<4; i++) @@ -223,7 +329,9 @@ void FarMesh::render() if(b < 0) b = 0; if(b > 2) b = 2; - c = video::SColor(128, b*c.getRed(), b*c.getGreen(), b*c.getBlue()); + c = video::SColor(255, b*c.getRed(), b*c.getGreen(), b*c.getBlue()); + + driver->setMaterial(m_materials[0]); video::S3DVertex vertices[4] = { @@ -235,9 +343,54 @@ void FarMesh::render() u16 indices[] = {0,1,2,2,3,0}; driver->drawVertexPrimitiveList(vertices, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); + + // Add some trees if appropriate + if(tree_amount_avg > 0.006 && steepness < 1.0 + && ma_avg >= 2.0*BS && have_sand_count <= 2) + { + driver->setMaterial(m_materials[1]); + + float b = m_brightness; + c = video::SColor(255, b*255, b*255, b*255); + + { + video::S3DVertex vertices[4] = + { + video::S3DVertex(p0.X,noise[0],p0.Y, + 0,0,0, c, 0,1), + video::S3DVertex(p0.X,noise[1]+BS*MAP_BLOCKSIZE,p0.Y, + 0,0,0, c, 0,0), + video::S3DVertex(p1.X,noise[2]+BS*MAP_BLOCKSIZE,p1.Y, + 0,0,0, c, 1,0), + video::S3DVertex(p1.X,noise[3],p1.Y, + 0,0,0, c, 1,1), + }; + u16 indices[] = {0,1,2,2,3,0}; + driver->drawVertexPrimitiveList(vertices, 4, indices, 2, + video::EVT_STANDARD, scene::EPT_TRIANGLES, + video::EIT_16BIT); + } + { + video::S3DVertex vertices[4] = + { + video::S3DVertex(p1.X,noise[0],p0.Y, + 0,0,0, c, 0,1), + video::S3DVertex(p1.X,noise[1]+BS*MAP_BLOCKSIZE,p0.Y, + 0,0,0, c, 0,0), + video::S3DVertex(p0.X,noise[2]+BS*MAP_BLOCKSIZE,p1.Y, + 0,0,0, c, 1,0), + video::S3DVertex(p0.X,noise[3],p1.Y, + 0,0,0, c, 1,1), + }; + u16 indices[] = {0,1,2,2,3,0}; + driver->drawVertexPrimitiveList(vertices, 4, indices, 2, + video::EVT_STANDARD, scene::EPT_TRIANGLES, + video::EIT_16BIT); + } + } } - driver->clearZBuffer(); + //driver->clearZBuffer(); } void FarMesh::step(float dtime) @@ -251,3 +404,4 @@ void FarMesh::update(v2f camera_p, float brightness) m_brightness = brightness; } + diff --git a/src/farmesh.h b/src/farmesh.h index 12f587942..aea806542 100644 --- a/src/farmesh.h +++ b/src/farmesh.h @@ -27,6 +27,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" +#define FARMESH_MATERIAL_COUNT 2 + +class Client; + class FarMesh : public scene::ISceneNode { public: @@ -34,7 +38,8 @@ public: scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, - u64 seed + u64 seed, + Client *client ); ~FarMesh(); @@ -52,15 +57,9 @@ public: return m_box; } - virtual u32 getMaterialCount() const - { - return 1; - } + virtual u32 getMaterialCount() const; - virtual video::SMaterial& getMaterial(u32 i) - { - return m_material; - } + virtual video::SMaterial& getMaterial(u32 i); /* Other stuff @@ -71,13 +70,14 @@ public: void update(v2f camera_p, float brightness); private: - video::SMaterial m_material; + video::SMaterial m_materials[FARMESH_MATERIAL_COUNT]; core::aabbox3d m_box; float m_cloud_y; float m_brightness; - u32 m_seed; + u64 m_seed; v2f m_camera_pos; float m_time; + Client *m_client; }; #endif diff --git a/src/game.cpp b/src/game.cpp index 7ad7746ad..237867be1 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -599,9 +599,9 @@ void update_skybox(video::IVideoDriver* driver, skybox->remove(); } - // Disable skybox if FarMesh is enabled + /*// Disable skybox if FarMesh is enabled if(g_settings.getBool("enable_farmesh")) - return; + return;*/ if(brightness >= 0.5) { @@ -836,7 +836,7 @@ void the_game( FarMesh *farmesh = NULL; if(g_settings.getBool("enable_farmesh")) { - farmesh = new FarMesh(smgr->getRootSceneNode(), smgr, -1, client.getMapSeed()); + farmesh = new FarMesh(smgr->getRootSceneNode(), smgr, -1, client.getMapSeed(), &client); } /* @@ -1844,11 +1844,19 @@ void the_game( if(g_settings.getBool("enable_fog") == true) { - f32 range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5; - if(draw_control.range_all) - range = 100000*BS; - if(range < 50*BS) - range = range * 0.5 + 25*BS; + f32 range; + if(farmesh) + { + range = BS*MAP_BLOCKSIZE*20; + } + else + { + range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5; + if(draw_control.range_all) + range = 100000*BS; + if(range < 50*BS) + range = range * 0.5 + 25*BS; + } driver->setFog( bgcolor, diff --git a/src/map.cpp b/src/map.cpp index 9a6cb003f..5cea4ebca 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2129,6 +2129,16 @@ double get_mud_add_amount(u64 seed, v2s16 p) seed+91013, 3, 0.55)); } +bool get_have_sand(u64 seed, v2s16 p2d) +{ + // Determine whether to have sand here + double sandnoise = noise2d_perlin( + 0.5+(float)p2d.X/500, 0.5+(float)p2d.Y/500, + seed+59420, 3, 0.50); + + return (sandnoise > -0.15); +} + /* Adds random objects to block, depending on the content of the block */ @@ -3118,12 +3128,7 @@ void makeChunk(ChunkMakeData *data) // Node position in 2d v2s16 p2d = data->sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z); - // Determine whether to have sand here - double sandnoise = noise2d_perlin( - 0.5+(float)p2d.X/500, 0.5+(float)p2d.Y/500, - data->seed+59420, 3, 0.50); - - bool have_sand = (sandnoise > -0.15); + bool have_sand = get_have_sand(data->seed, p2d); if(have_sand == false) continue; @@ -5658,6 +5663,14 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) DSTACK(__FUNCTION_NAME); bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT; + + /* + This is called two times per frame, reset on the non-transparent one + */ + if(pass == scene::ESNRP_SOLID) + { + m_last_drawn_sectors.clear(); + } /* Get time for measuring timeout. @@ -5706,9 +5719,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) u32 blocks_would_have_drawn = 0; u32 blocks_drawn = 0; - //NOTE: The sectors map should be locked but we're not doing it - // because it'd cause too much delays - int timecheck_counter = 0; core::map::Iterator si; si = m_sectors.getIterator(); @@ -5748,6 +5758,8 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) /* Draw blocks */ + + u32 sector_blocks_drawn = 0; core::list< MapBlock * >::Iterator i; for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++) @@ -5840,7 +5852,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) && m_control.range_all == false && d > m_control.wanted_min_range * BS) continue; + blocks_drawn++; + sector_blocks_drawn++; u32 c = mesh->getMeshBufferCount(); @@ -5866,6 +5880,11 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass) } } } // foreach sectorblocks + + if(sector_blocks_drawn != 0) + { + m_last_drawn_sectors[sp] = true; + } } m_control.blocks_drawn = blocks_drawn; diff --git a/src/map.h b/src/map.h index e74f89beb..691f3bdb4 100644 --- a/src/map.h +++ b/src/map.h @@ -41,13 +41,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapchunk.h" #include "nodemetadata.h" -/* - Temporarily exposed map generator stuff - Should only be used for testing -*/ - -double base_rock_level_2d(u64 seed, v2s16 p); - /* MapEditEvent */ @@ -751,6 +744,12 @@ public: // For debug printing virtual void PrintInfo(std::ostream &out); + // Check if sector was drawn on last render() + bool sectorWasDrawn(v2s16 p) + { + return (m_last_drawn_sectors.find(p) != NULL); + } + private: Client *m_client; @@ -765,7 +764,8 @@ private: v3f m_camera_position; v3f m_camera_direction; JMutex m_camera_mutex; - + + core::map m_last_drawn_sectors; }; #endif -- cgit v1.2.3 From c78d61061863559cc3daf6b838a0f936ce53acf9 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 18 Jun 2011 13:43:49 +0300 Subject: farmesh render range is now dynamic --- src/defaultsettings.cpp | 2 +- src/farmesh.cpp | 22 ++++++++++++---------- src/farmesh.h | 3 ++- src/game.cpp | 20 ++++++++++---------- 4 files changed, 25 insertions(+), 22 deletions(-) (limited to 'src/game.cpp') diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 209d20b63..6eff4ef70 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -49,7 +49,7 @@ void set_default_settings() g_settings.setDefault("wanted_fps", "30"); g_settings.setDefault("fps_max", "60"); g_settings.setDefault("viewing_range_nodes_max", "300"); - g_settings.setDefault("viewing_range_nodes_min", "28"); + g_settings.setDefault("viewing_range_nodes_min", "25"); g_settings.setDefault("screenW", "800"); g_settings.setDefault("screenH", "600"); g_settings.setDefault("address", ""); diff --git a/src/farmesh.cpp b/src/farmesh.cpp index efbbeb665..b46d84151 100644 --- a/src/farmesh.cpp +++ b/src/farmesh.cpp @@ -50,7 +50,8 @@ FarMesh::FarMesh( m_seed(seed), m_camera_pos(0,0), m_time(0), - m_client(client) + m_client(client), + m_render_range(20*MAP_BLOCKSIZE) { dstream<<__FUNCTION_NAME<= 0.005 && steepness < 1.0 + if(tree_amount_avg >= 0.0065 && steepness < 1.4 && ground_is_mud == true) { driver->setMaterial(m_materials[1]); @@ -367,11 +368,11 @@ void FarMesh::render() { video::S3DVertex(p0.X,noise[0],p0.Y, 0,0,0, c, 0,1), - video::S3DVertex(p0.X,noise[1]+BS*MAP_BLOCKSIZE,p0.Y, + video::S3DVertex(p0.X,noise[0]+BS*MAP_BLOCKSIZE,p0.Y, 0,0,0, c, 0,0), video::S3DVertex(p1.X,noise[2]+BS*MAP_BLOCKSIZE,p1.Y, 0,0,0, c, 1,0), - video::S3DVertex(p1.X,noise[3],p1.Y, + video::S3DVertex(p1.X,noise[2],p1.Y, 0,0,0, c, 1,1), }; u16 indices[] = {0,1,2,2,3,0}; @@ -382,13 +383,13 @@ void FarMesh::render() { video::S3DVertex vertices[4] = { - video::S3DVertex(p1.X,noise[0],p0.Y, + video::S3DVertex(p1.X,noise[3],p0.Y, 0,0,0, c, 0,1), - video::S3DVertex(p1.X,noise[1]+BS*MAP_BLOCKSIZE,p0.Y, + video::S3DVertex(p1.X,noise[3]+BS*MAP_BLOCKSIZE,p0.Y, 0,0,0, c, 0,0), - video::S3DVertex(p0.X,noise[2]+BS*MAP_BLOCKSIZE,p1.Y, + video::S3DVertex(p0.X,noise[1]+BS*MAP_BLOCKSIZE,p1.Y, 0,0,0, c, 1,0), - video::S3DVertex(p0.X,noise[3],p1.Y, + video::S3DVertex(p0.X,noise[1],p1.Y, 0,0,0, c, 1,1), }; u16 indices[] = {0,1,2,2,3,0}; @@ -407,10 +408,11 @@ void FarMesh::step(float dtime) m_time += dtime; } -void FarMesh::update(v2f camera_p, float brightness) +void FarMesh::update(v2f camera_p, float brightness, s16 render_range) { m_camera_pos = camera_p; m_brightness = brightness; + m_render_range = render_range; } diff --git a/src/farmesh.h b/src/farmesh.h index aea806542..0a30a8aef 100644 --- a/src/farmesh.h +++ b/src/farmesh.h @@ -67,7 +67,7 @@ public: void step(float dtime); - void update(v2f camera_p, float brightness); + void update(v2f camera_p, float brightness, s16 render_range); private: video::SMaterial m_materials[FARMESH_MATERIAL_COUNT]; @@ -78,6 +78,7 @@ private: v2f m_camera_pos; float m_time; Client *m_client; + s16 m_render_range; }; #endif diff --git a/src/game.cpp b/src/game.cpp index 237867be1..1ab3d7962 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -915,6 +915,7 @@ void the_game( core::list frametime_log; float damage_flash_timer = 0; + s16 farmesh_range = 20*MAP_BLOCKSIZE; bool invert_mouse = g_settings.getBool("invert_mouse"); @@ -1826,13 +1827,19 @@ void the_game( } /* - Update farmesh (TODO: Remove from here) + Update farmesh */ if(farmesh) { + farmesh_range = draw_control.wanted_range * 10; + if(draw_control.range_all && farmesh_range < 500) + farmesh_range = 500; + if(farmesh_range > 1000) + farmesh_range = 1000; + farmesh->step(dtime); farmesh->update(v2f(player_position.X, player_position.Z), - 0.05+brightness*0.95); + 0.05+brightness*0.95, farmesh_range); } // Store brightness value @@ -1847,7 +1854,7 @@ void the_game( f32 range; if(farmesh) { - range = BS*MAP_BLOCKSIZE*20; + range = BS*farmesh_range; } else { @@ -2054,13 +2061,6 @@ void the_game( beginscenetime = timer.stop(true); } - /* - Draw farmesh before everything else - */ - { - //farmesh->render(); - } - //timer3.stop(); //std::cout<drawAll()"< Date: Sat, 18 Jun 2011 18:44:01 +0300 Subject: Hand-picked Mac OSX cursor and bundle path fixes from https://bitbucket.org/toabi/minetest-mac --- src/game.cpp | 10 ++++++++-- src/porting.cpp | 24 +++++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'src/game.cpp') diff --git a/src/game.cpp b/src/game.cpp index 1ab3d7962..f3fac0c84 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1366,7 +1366,11 @@ void the_game( if((device->isWindowActive() && noMenuActive()) || random_input) { if(!random_input) - device->getCursorControl()->setVisible(false); + { + // Mac OSX gets upset if this is set every frame + if(device->getCursorControl()->isVisible()) + device->getCursorControl()->setVisible(false); + } if(first_loop_after_window_activation){ //std::cout<<"window active, first loop"<setMousePos(displaycenter.X, displaycenter.Y); } else{ - device->getCursorControl()->setVisible(true); + // Mac OSX gets upset if this is set every frame + if(device->getCursorControl()->isVisible() == false) + device->getCursorControl()->setVisible(true); //std::cout<<"window inactive"< - + #include "CoreFoundation/CoreFoundation.h" + + // Code based on + // http://stackoverflow.com/questions/516200/relative-paths-not-working-in-xcode-c + CFBundleRef main_bundle = CFBundleGetMainBundle(); + CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(main_bundle); + char path[PATH_MAX]; + if(CFURLGetFileSystemRepresentation(resources_url, TRUE, (UInt8 *)path, PATH_MAX)) + { + dstream<<"Bundle resource path: "<