From 36f03a7f4ae81e8735328a38c9415b6e7081c37c Mon Sep 17 00:00:00 2001 From: RealBadAngel Date: Wed, 2 Jan 2013 00:03:47 +0100 Subject: [PATCH 01/66] Bugfixes to item_image formspec method --- src/guiFormSpecMenu.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp index 986f30494..ea537deb2 100644 --- a/src/guiFormSpecMenu.cpp +++ b/src/guiFormSpecMenu.cpp @@ -293,7 +293,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize) geom.X = stof(f.next(",")) * (float)imgsize.X; geom.Y = stof(f.next(";")) * (float)imgsize.Y; std::string name = f.next("]"); - errorstream<<"item name="<getOriginalSize())), NULL/*&AbsoluteClippingRect*/, colors, true); } - + + /* + Draw item images + */ + for(u32 i=0; iidef(); + ItemStack item; + item.deSerialize(spec.name, idef); + video::ITexture *texture = idef->getInventoryTexture(item.getDefinition(idef).name, m_gamedef); + // Image size on screen + core::rect imgrect(0, 0, spec.geom.X, spec.geom.Y); + // Image rectangle on screen + core::rect rect = imgrect + spec.pos; + const video::SColor color(255,255,255,255); + const video::SColor colors[] = {color,color,color,color}; + driver->draw2DImage(texture, rect, + core::rect(core::position2d(0,0), + core::dimension2di(texture->getOriginalSize())), + NULL/*&AbsoluteClippingRect*/, colors, true); + } + /* Draw items Phase 0: Item slot rectangles From da9707950e0f69d8a906572fc55f516277e057c4 Mon Sep 17 00:00:00 2001 From: sapier Date: Wed, 2 Jan 2013 19:45:04 +0000 Subject: [PATCH 02/66] Add TOCLIENT_SHOW_FORMSPEC to display formspecs at client from lua --- doc/lua_api.txt | 3 +++ src/client.cpp | 14 ++++++++++++++ src/client.h | 6 +++++- src/clientserver.h | 10 +++++++++- src/game.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++ src/scriptapi.cpp | 16 ++++++++++++++++ src/server.cpp | 32 +++++++++++++++++++++++++++++++ src/server.h | 2 ++ 8 files changed, 129 insertions(+), 2 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 117d4b24e..ebad1dad2 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -888,6 +888,9 @@ minetest.get_inventory(location) -> InvRef minetest.create_detached_inventory(name, callbacks) -> InvRef ^ callbacks: See "Detached inventory callbacks" ^ Creates a detached inventory. If it already exists, it is cleared. +minetest.show_formspec(playername, formspec) +^ playername: name of player to show formspec +^ formspec: formspec to display Item handling: minetest.inventorycube(img1, img2, img3) diff --git a/src/client.cpp b/src/client.cpp index cb7afe29f..216d86cd4 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1900,6 +1900,20 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) } inv->deSerialize(is); } + else if(command == TOCLIENT_SHOW_FORMSPEC) + { + std::string datastring((char*)&data[2], datasize-2); + std::istringstream is(datastring, std::ios_base::binary); + + std::string formspec = deSerializeLongString(is); + + ClientEvent event; + event.type = CE_SHOW_FORMSPEC; + // pointer is required as event is a struct only! + // adding a std:string to a struct isn't possible + event.show_formspec.formspec = new std::string(formspec); + m_client_event_queue.push_back(event); + } else { infostream<<"Client: Ignoring unknown command " diff --git a/src/client.h b/src/client.h index 155b4386b..e46da6b0e 100644 --- a/src/client.h +++ b/src/client.h @@ -154,7 +154,8 @@ enum ClientEventType CE_PLAYER_DAMAGE, CE_PLAYER_FORCE_MOVE, CE_DEATHSCREEN, - CE_TEXTURES_UPDATED + CE_TEXTURES_UPDATED, + CE_SHOW_FORMSPEC }; struct ClientEvent @@ -176,6 +177,9 @@ struct ClientEvent f32 camera_point_target_y; f32 camera_point_target_z; } deathscreen; + struct{ + std::string* formspec; + } show_formspec; struct{ } textures_updated; }; diff --git a/src/clientserver.h b/src/clientserver.h index db551a90c..bb7e1181e 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -77,9 +77,11 @@ SharedBuffer makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed); GENERIC_CMD_SET_ATTACHMENT PROTOCOL_VERSION 15: Serialization format changes + PROTOCOL_VERSION 16: + TOCLIENT_SHOW_FORMSPEC */ -#define LATEST_PROTOCOL_VERSION 15 +#define LATEST_PROTOCOL_VERSION 16 // Server's supported network protocol range #define SERVER_PROTOCOL_VERSION_MIN 13 @@ -354,6 +356,12 @@ enum ToClientCommand u8[len] name [2] serialized inventory */ + TOCLIENT_SHOW_FORMSPEC = 0x44, + /* + [0] u16 command + u16 len + u8[len] formspec + */ }; enum ToServerCommand diff --git a/src/game.cpp b/src/game.cpp index 541127f5d..15bf3f09f 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -192,6 +192,32 @@ public: Client *m_client; }; +class FormspecFormSource: public IFormSource +{ +public: + FormspecFormSource(std::string formspec,FormspecFormSource** game_formspec) + { + m_formspec = formspec; + m_game_formspec = game_formspec; + } + + ~FormspecFormSource() + { + *m_game_formspec = 0; + } + + void setForm(std::string formspec) { + m_formspec = formspec; + } + + std::string getForm() + { + return m_formspec; + } + + std::string m_formspec; + FormspecFormSource** m_game_formspec; +}; /* Hotbar draw routine */ @@ -901,6 +927,7 @@ void the_game( bool simple_singleplayer_mode ) { + FormspecFormSource* current_formspec = 0; video::IVideoDriver* driver = device->getVideoDriver(); scene::ISceneManager* smgr = device->getSceneManager(); @@ -2067,6 +2094,27 @@ void the_game( player->setPosition(player->getPosition() + v3f(0,-BS,0)); camera.update(player, busytime, screensize);*/ } + else if (event.type == CE_SHOW_FORMSPEC) + { + if (current_formspec == 0) + { + /* Create menu */ + current_formspec = new FormspecFormSource(*(event.show_formspec.formspec),¤t_formspec); + + GUIFormSpecMenu *menu = + new GUIFormSpecMenu(device, guiroot, -1, + &g_menumgr, + &client, gamedef); + menu->setFormSource(current_formspec); + menu->drop(); + } + else + { + /* update menu */ + current_formspec->setForm(*(event.show_formspec.formspec)); + } + delete(event.show_formspec.formspec); + } else if(event.type == CE_TEXTURES_UPDATED) { update_wielded_item_trigger = true; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index d086b7e51..83987fc9b 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -4899,6 +4899,21 @@ static int l_create_detached_inventory_raw(lua_State *L) return 1; } +// create_detached_formspec_raw(name) +static int l_show_formspec(lua_State *L) +{ + const char *playername = luaL_checkstring(L, 1); + const char *formspec = luaL_checkstring(L, 2); + + if(get_server(L)->showFormspec(playername,formspec)) + { + lua_pushboolean(L, true); + }else{ + lua_pushboolean(L, false); + } + return 1; +} + // get_dig_params(groups, tool_capabilities[, time_from_last_punch]) static int l_get_dig_params(lua_State *L) { @@ -5228,6 +5243,7 @@ static const struct luaL_Reg minetest_f [] = { {"unban_player_or_ip", l_unban_player_of_ip}, {"get_inventory", l_get_inventory}, {"create_detached_inventory_raw", l_create_detached_inventory_raw}, + {"show_formspec", l_show_formspec}, {"get_dig_params", l_get_dig_params}, {"get_hit_params", l_get_hit_params}, {"get_current_modname", l_get_current_modname}, diff --git a/src/server.cpp b/src/server.cpp index 39407f961..f4b5ee872 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -3638,6 +3638,24 @@ void Server::SendChatMessage(u16 peer_id, const std::wstring &message) // Send as reliable m_con.Send(peer_id, 0, data, true); } +void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec) +{ + DSTACK(__FUNCTION_NAME); + + std::ostringstream os(std::ios_base::binary); + u8 buf[12]; + + // Write command + writeU16(buf, TOCLIENT_SHOW_FORMSPEC); + os.write((char*)buf, 2); + os< data((u8*)s.c_str(), s.size()); + // Send as reliable + m_con.Send(peer_id, 0, data, true); +} void Server::BroadcastChatMessage(const std::wstring &message) { @@ -4578,6 +4596,20 @@ void Server::notifyPlayer(const char *name, const std::wstring msg) SendChatMessage(player->peer_id, std::wstring(L"Server: -!- ")+msg); } +bool Server::showFormspec(const char *playername, const std::string &formspec) +{ + Player *player = m_env->getPlayer(playername); + + if(!player) + { + infostream<<"showFormspec: couldn't find player:"<peer_id,formspec); + return true; +} + void Server::notifyPlayers(const std::wstring msg) { BroadcastChatMessage(msg); diff --git a/src/server.h b/src/server.h index ce826ae52..19c29cbd7 100644 --- a/src/server.h +++ b/src/server.h @@ -583,6 +583,7 @@ public: m_async_fatal_error.set(error); } + bool showFormspec(const char *name, const std::string &formspec); private: // con::PeerHandler implementation. @@ -620,6 +621,7 @@ private: void SendMovePlayer(u16 peer_id); void SendPlayerPrivileges(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id); + void SendShowFormspecMessage(u16 peer_id, const std::string formspec); /* Send a node removal/addition event to all clients except ignore_id. Additionally, if far_players!=NULL, players further away than From b7de864f2e2cc7bc45c39c4ce811dbec0aa7f98a Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Wed, 2 Jan 2013 21:02:29 +0200 Subject: [PATCH 03/66] Call this 0.4.4-d1 because it has a protocol addition since 0.4.4 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2de45d90f..fdb0347b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string") # Also remember to set PROTOCOL_VERSION in clientserver.h when releasing set(VERSION_MAJOR 0) set(VERSION_MINOR 4) -set(VERSION_PATCH 4) +set(VERSION_PATCH 4-d1) if(VERSION_EXTRA) set(VERSION_PATCH ${VERSION_PATCH}-${VERSION_EXTRA}) endif() From 69bd803a3221bf02672431390e672b0510695254 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Wed, 2 Jan 2013 22:53:55 +0200 Subject: [PATCH 04/66] Add InvRef:get_location() --- doc/lua_api.txt | 2 ++ src/scriptapi.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index ebad1dad2..124344cad 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1231,6 +1231,8 @@ methods: can be fully taken from the list remove_item(listname, stack): take as many items as specified from the list, returns the items that were actually removed (as an ItemStack) +- get_location() -> location compatible to minetest.get_inventory(location) + -> {type="undefined"} in case location is not known ItemStack: A stack of items. - Can be created via ItemStack(itemstack or itemstring or table or nil) diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 83987fc9b..a79622db3 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -2049,6 +2049,43 @@ private: return 1; } + // get_location() -> location (like minetest.get_inventory(location)) + static int l_get_location(lua_State *L) + { + InvRef *ref = checkobject(L, 1); + const InventoryLocation &loc = ref->m_loc; + switch(loc.type){ + case InventoryLocation::PLAYER: + lua_newtable(L); + lua_pushstring(L, "player"); + lua_setfield(L, -2, "type"); + lua_pushstring(L, loc.name.c_str()); + lua_setfield(L, -2, "name"); + return 1; + case InventoryLocation::NODEMETA: + lua_newtable(L); + lua_pushstring(L, "nodemeta"); + lua_setfield(L, -2, "type"); + push_v3s16(L, loc.p); + lua_setfield(L, -2, "name"); + return 1; + case InventoryLocation::DETACHED: + lua_newtable(L); + lua_pushstring(L, "detached"); + lua_setfield(L, -2, "type"); + lua_pushstring(L, loc.name.c_str()); + lua_setfield(L, -2, "name"); + return 1; + case InventoryLocation::UNDEFINED: + case InventoryLocation::CURRENT_PLAYER: + break; + } + lua_newtable(L); + lua_pushstring(L, "undefined"); + lua_setfield(L, -2, "type"); + return 1; + } + public: InvRef(const InventoryLocation &loc): m_loc(loc) @@ -2124,6 +2161,7 @@ const luaL_reg InvRef::methods[] = { method(InvRef, room_for_item), method(InvRef, contains_item), method(InvRef, remove_item), + method(InvRef, get_location), {0,0} }; From 2c472a66d1d605eefb167f51529c287f868ffa9b Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Wed, 2 Jan 2013 23:17:52 +0200 Subject: [PATCH 05/66] Add ServerEnvironment::setNode()/removeNode() to allow setting nodes from the C++ side with proper script-defined initialization/destruction --- src/environment.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/environment.h | 4 ++++ src/scriptapi.cpp | 29 ++--------------------------- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/environment.cpp b/src/environment.cpp index 5bf127a17..020d2b433 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -819,6 +819,45 @@ void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm) m_abms.push_back(ABMWithState(abm)); } +bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) +{ + INodeDefManager *ndef = m_gamedef->ndef(); + MapNode n_old = m_map->getNodeNoEx(p); + // Call destructor + if(ndef->get(n_old).has_on_destruct) + scriptapi_node_on_destruct(m_lua, p, n_old); + // Replace node + bool succeeded = m_map->addNodeWithEvent(p, n); + if(!succeeded) + return false; + // Call post-destructor + if(ndef->get(n_old).has_after_destruct) + scriptapi_node_after_destruct(m_lua, p, n_old); + // Call constructor + if(ndef->get(n).has_on_construct) + scriptapi_node_on_construct(m_lua, p, n); + return true; +} + +bool ServerEnvironment::removeNode(v3s16 p) +{ + INodeDefManager *ndef = m_gamedef->ndef(); + MapNode n_old = m_map->getNodeNoEx(p); + // Call destructor + if(ndef->get(n_old).has_on_destruct) + scriptapi_node_on_destruct(m_lua, p, n_old); + // Replace with air + // This is slightly optimized compared to addNodeWithEvent(air) + bool succeeded = m_map->removeNodeWithEvent(p); + if(!succeeded) + return false; + // Call post-destructor + if(ndef->get(n_old).has_after_destruct) + scriptapi_node_after_destruct(m_lua, p, n_old); + // Air doesn't require constructor + return true; +} + std::set ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius) { std::set objects; diff --git a/src/environment.h b/src/environment.h index 0cc53f9a6..d17edeacd 100644 --- a/src/environment.h +++ b/src/environment.h @@ -283,6 +283,10 @@ public: Other stuff ------------------------------------------- */ + + // Script-aware node setters + bool setNode(v3s16 p, const MapNode &n); + bool removeNode(v3s16 p); // Find all active objects inside a radius around a point std::set getObjectsInsideRadius(v3f pos, float radius); diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index a79622db3..04f741ad3 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -3540,20 +3540,7 @@ private: v3s16 pos = read_v3s16(L, 2); MapNode n = readnode(L, 3, ndef); // Do it - MapNode n_old = env->getMap().getNodeNoEx(pos); - // Call destructor - if(ndef->get(n_old).has_on_destruct) - scriptapi_node_on_destruct(L, pos, n_old); - // Replace node - bool succeeded = env->getMap().addNodeWithEvent(pos, n); - if(succeeded){ - // Call post-destructor - if(ndef->get(n_old).has_after_destruct) - scriptapi_node_after_destruct(L, pos, n_old); - // Call constructor - if(ndef->get(n).has_on_construct) - scriptapi_node_on_construct(L, pos, n); - } + bool succeeded = env->setNode(pos, n); lua_pushboolean(L, succeeded); return 1; } @@ -3574,20 +3561,8 @@ private: // parameters v3s16 pos = read_v3s16(L, 2); // Do it - MapNode n_old = env->getMap().getNodeNoEx(pos); - // Call destructor - if(ndef->get(n_old).has_on_destruct) - scriptapi_node_on_destruct(L, pos, n_old); - // Replace with air - // This is slightly optimized compared to addNodeWithEvent(air) - bool succeeded = env->getMap().removeNodeWithEvent(pos); - if(succeeded){ - // Call post-destructor - if(ndef->get(n_old).has_after_destruct) - scriptapi_node_after_destruct(L, pos, n_old); - } + bool succeeded = env->removeNode(pos); lua_pushboolean(L, succeeded); - // Air doesn't require constructor return 1; } From 8493979d8678f440e11a448349f4e0404e143e95 Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Wed, 2 Jan 2013 21:57:04 +0100 Subject: [PATCH 06/66] Replace constant red hurt screen with fade out red --- src/game.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 15bf3f09f..05f1da5e0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1307,7 +1307,7 @@ void the_game( bool digging = false; bool ldown_for_dig = false; - float damage_flash_timer = 0; + float damage_flash = 0; s16 farmesh_range = 20*MAP_BLOCKSIZE; const float object_hit_delay = 0.2; @@ -2055,10 +2055,8 @@ void the_game( { //u16 damage = event.player_damage.amount; //infostream<<"Player damage: "<= 2){ - damage_flash_timer += 0.05 * event.player_damage.amount; - } + damage_flash += 100.0; + damage_flash += 8.0 * event.player_damage.amount; } else if(event.type == CE_PLAYER_FORCE_MOVE) { @@ -2088,7 +2086,7 @@ void the_game( /* Handle visualization */ - damage_flash_timer = 0; + damage_flash = 0; /*LocalPlayer* player = client.getLocalPlayer(); player->setPosition(player->getPosition() + v3f(0,-BS,0)); @@ -3049,14 +3047,14 @@ void the_game( /* Damage flash */ - if(damage_flash_timer > 0.0) + if(damage_flash > 0.0) { - damage_flash_timer -= dtime; - - video::SColor color(128,255,0,0); + video::SColor color(std::min(damage_flash, 220.0f),180,0,0); driver->draw2DRectangle(color, core::rect(0,0,screensize.X,screensize.Y), NULL); + + damage_flash -= 100.0*dtime; } /* From 5a13c49492d466e35624bafba5ac74ad728fef4f Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Wed, 2 Jan 2013 22:03:36 +0100 Subject: [PATCH 07/66] Change the nodenames for dirt -> grass and sapling -> tree abms to match the mapgen aliases --- src/content_abm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content_abm.cpp b/src/content_abm.cpp index 0d0f0dedb..5812c7b50 100644 --- a/src/content_abm.cpp +++ b/src/content_abm.cpp @@ -37,7 +37,7 @@ public: virtual std::set getTriggerContents() { std::set s; - s.insert("dirt"); + s.insert("mapgen_dirt"); return s; } virtual float getTriggerInterval() @@ -67,7 +67,7 @@ public: virtual std::set getTriggerContents() { std::set s; - s.insert("dirt_with_grass"); + s.insert("mapgen_dirt_with_grass"); return s; } virtual float getTriggerInterval() From a27cdf16f40e3a3f4772b944ead8f1e4e5618359 Mon Sep 17 00:00:00 2001 From: Jeija Date: Sat, 28 Apr 2012 02:06:25 +0200 Subject: [PATCH 08/66] Tilt camera on player damage (tweaked by PilzAdam) --- src/camera.cpp | 7 +++++-- src/game.cpp | 23 +++++++++++++++++++++++ src/player.h | 3 +++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/camera.cpp b/src/camera.cpp index 1b9a8c763..33e85d069 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -233,9 +233,12 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize, m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0)); m_playernode->updateAbsolutePosition(); + //Get camera tilt timer (hurt animation) + float cameratilt = fabs(fabs(player->hurt_tilt_timer-0.75)-0.75); + // Set head node transformation - m_headnode->setPosition(player->getEyeOffset()); - m_headnode->setRotation(v3f(player->getPitch(), 0, 0)); + m_headnode->setPosition(player->getEyeOffset()+v3f(0,cameratilt*-player->hurt_tilt_strength,0)); + m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength)); m_headnode->updateAbsolutePosition(); // Compute relative camera position and target diff --git a/src/game.cpp b/src/game.cpp index 05f1da5e0..5a278a52e 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1356,6 +1356,10 @@ void the_game( // NOTE: So we have to use getTime() and call run()s between them u32 lasttime = device->getTimer()->getTime(); + LocalPlayer* player = client.getEnv().getLocalPlayer(); + player->hurt_tilt_timer = 0; + player->hurt_tilt_strength = 0; + for(;;) { if(device->run() == false || kill == true) @@ -2055,8 +2059,13 @@ void the_game( { //u16 damage = event.player_damage.amount; //infostream<<"Player damage: "<hurt_tilt_timer = 1.5; + player->hurt_tilt_strength = event.player_damage.amount/2; + player->hurt_tilt_strength = rangelim(player->hurt_tilt_strength, 2.0, 10.0); } else if(event.type == CE_PLAYER_FORCE_MOVE) { @@ -2088,6 +2097,10 @@ void the_game( damage_flash = 0; + LocalPlayer* player = client.getEnv().getLocalPlayer(); + player->hurt_tilt_timer = 0; + player->hurt_tilt_strength = 0; + /*LocalPlayer* player = client.getLocalPlayer(); player->setPosition(player->getPosition() + v3f(0,-BS,0)); camera.update(player, busytime, screensize);*/ @@ -3057,6 +3070,16 @@ void the_game( damage_flash -= 100.0*dtime; } + /* + Damage camera tilt + */ + if(player->hurt_tilt_timer > 0.0) + { + player->hurt_tilt_timer -= dtime*5; + if(player->hurt_tilt_timer < 0) + player->hurt_tilt_strength = 0; + } + /* Draw gui */ diff --git a/src/player.h b/src/player.h index 5a489e64f..67b02c344 100644 --- a/src/player.h +++ b/src/player.h @@ -209,6 +209,9 @@ public: u16 hp; + float hurt_tilt_timer; + float hurt_tilt_strength; + u16 peer_id; std::string inventory_formspec; From d2b1210376f6cc52fe031ac41d3bf54720ebd356 Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Thu, 3 Jan 2013 16:15:46 +0100 Subject: [PATCH 09/66] Adjust the maximum alpha of the red hurt screen --- src/game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game.cpp b/src/game.cpp index 5a278a52e..42863ff37 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3062,7 +3062,7 @@ void the_game( */ if(damage_flash > 0.0) { - video::SColor color(std::min(damage_flash, 220.0f),180,0,0); + video::SColor color(std::min(damage_flash, 180.0f),180,0,0); driver->draw2DRectangle(color, core::rect(0,0,screensize.X,screensize.Y), NULL); From 5bc14e2fe45f12cdb69d302807d05985ee5552ee Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Fri, 4 Jan 2013 00:05:56 +0100 Subject: [PATCH 10/66] Add on_rightclick(pos, node, clicker) callback for nodes --- builtin/item.lua | 15 +++++++++++++-- doc/lua_api.txt | 4 ++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/builtin/item.lua b/builtin/item.lua index acc1e6262..d36e8a758 100644 --- a/builtin/item.lua +++ b/builtin/item.lua @@ -231,9 +231,19 @@ function minetest.item_place_object(itemstack, placer, pointed_thing) end function minetest.item_place(itemstack, placer, pointed_thing) + -- Call on_rightclick if the pointed node defines it + if pointed_thing.type == "node" then + local n = minetest.env:get_node(pointed_thing.under) + local nn = n.name + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then + minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, n, placer) + return + end + end + if itemstack:get_definition().type == "node" then return minetest.item_place_node(itemstack, placer, pointed_thing) - else + elseif itemstack:get_definition().type ~= "none" then return minetest.item_place_object(itemstack, placer, pointed_thing) end end @@ -375,6 +385,7 @@ minetest.nodedef_default = { can_dig = nil, on_punch = redef_wrapper(minetest, 'node_punch'), -- minetest.node_punch + on_rightclick = nil, on_dig = redef_wrapper(minetest, 'node_dig'), -- minetest.node_dig on_receive_fields = nil, @@ -464,7 +475,7 @@ minetest.noneitemdef_default = { -- This is used for the hand and unknown items tool_capabilities = nil, -- Interaction callbacks - on_place = nil, + on_place = redef_wrapper(minetest, 'item_place'), on_drop = nil, on_use = nil, } diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 124344cad..f891b56f0 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -942,6 +942,8 @@ minetest.item_place_object(itemstack, placer, pointed_thing) ^ Place item as-is minetest.item_place(itemstack, placer, pointed_thing) ^ Use one of the above based on what the item is. +^ Calls on_rightclick of pointed_thing.under if defined instead +^ Note: is not called when wielded item overrides on_place minetest.item_drop(itemstack, dropper, pos) ^ Drop the item minetest.item_eat(hp_change, replace_with_item) @@ -1482,6 +1484,8 @@ Node definition (register_node) on_punch = func(pos, node, puncher), ^ default: minetest.node_punch ^ By default: does nothing + on_rightclick = func(pos, node, clicker), + ^ default: nil on_dig = func(pos, node, digger), ^ default: minetest.node_dig ^ By default: checks privileges, wears out tool and removes node From b50da63852f2a2360d07cc2f1e29fc6844b15ccc Mon Sep 17 00:00:00 2001 From: Jeija Date: Fri, 4 Jan 2013 15:19:16 +0100 Subject: [PATCH 11/66] Repeated right clicking when holding the right mouse button Configure using repeat_rightclick_time in minetest.conf --- minetest.conf.example | 3 +++ src/defaultsettings.cpp | 1 + src/game.cpp | 9 ++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/minetest.conf.example b/minetest.conf.example index 34a2acebc..5fb4244b2 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -146,6 +146,9 @@ # (1: low level shaders; not implemented) # 2: enable high level shaders #enable_shaders = 2 +# The time in seconds it takes between repeated +# right clicks when holding the right mouse button +#repeat_rightclick_time = 0.25 # will only work for servers which use remote_media setting # and only for clients compiled with cURL diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index f9c942590..cac3e568a 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -121,6 +121,7 @@ void set_default_settings(Settings *settings) settings->setDefault("trilinear_filter", "false"); settings->setDefault("preload_item_visuals", "true"); settings->setDefault("enable_shaders", "2"); + settings->setDefault("repeat_rightclick_time", "0.25"); settings->setDefault("media_fetch_threads", "8"); diff --git a/src/game.cpp b/src/game.cpp index 42863ff37..fdb083ff1 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1335,6 +1335,8 @@ void the_game( float time_of_day = 0; float time_of_day_smooth = 0; + float repeat_rightclick_timer = 0; + /* Shader constants */ @@ -2266,6 +2268,9 @@ void the_game( bool left_punch = false; soundmaker.m_player_leftpunch_sound.name = ""; + if(input->getRightState()) + repeat_rightclick_timer += dtime; + if(playeritem_usable && input->getLeftState()) { if(input->getLeftClicked()) @@ -2406,8 +2411,10 @@ void the_game( camera.setDigging(0); // left click animation } - if(input->getRightClicked()) + if(input->getRightClicked() || + repeat_rightclick_timer >= g_settings->getFloat("repeat_rightclick_time")) { + repeat_rightclick_timer = 0; infostream<<"Ground right-clicked"< Date: Thu, 3 Jan 2013 19:51:52 +0100 Subject: [PATCH 12/66] Switch to fly mode if spacebar is doubleclicked Can be turned off in the key change GUI or in minetest.conf via doubletab_space --- minetest.conf.example | 2 ++ src/defaultsettings.cpp | 1 + src/game.cpp | 35 +++++++++++++++++++++++++++++++++++ src/guiKeyChangeMenu.cpp | 20 ++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/minetest.conf.example b/minetest.conf.example index 5fb4244b2..a4448ab61 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -51,6 +51,8 @@ #keymap_screenshot = KEY_F12 # If true, keymap_special1 instead of keymap_sneak is used for climbing down and descending #aux1_descends = false +# Doubletabing the jump key toogles fly mode +#doubletab_jump = false # Some (temporary) keys for debugging #keymap_print_debug_stacks = KEY_KEY_P #keymap_quicktune_prev = KEY_HOME diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index cac3e568a..82783db0d 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -56,6 +56,7 @@ void set_default_settings(Settings *settings) settings->setDefault("anaglyph", "false"); settings->setDefault("anaglyph_strength", "0.1"); settings->setDefault("aux1_descends", "false"); + settings->setDefault("doubletab_jump", "false"); // Some (temporary) keys for debugging settings->setDefault("keymap_print_debug_stacks", "KEY_KEY_P"); diff --git a/src/game.cpp b/src/game.cpp index fdb083ff1..ab480c3db 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1310,6 +1310,9 @@ void the_game( float damage_flash = 0; s16 farmesh_range = 20*MAP_BLOCKSIZE; + float jump_timer = 0; + bool reset_jump_timer = false; + const float object_hit_delay = 0.2; float object_hit_delay_timer = 0.0; float time_from_last_punch = 10; @@ -1592,6 +1595,10 @@ void the_game( // Input handler step() (used by the random input generator) input->step(dtime); + // Increase timer for doubleclick of "jump" + if(g_settings->getBool("doubletab_jump") && jump_timer <= 0.2) + jump_timer += dtime; + /* Launch menus and trigger stuff according to keys */ @@ -1681,6 +1688,27 @@ void the_game( statustext += L" (note: no 'fly' privilege)"; } } + else if(input->wasKeyDown(getKeySetting("keymap_jump"))) + { + if(g_settings->getBool("doubletab_jump") && jump_timer < 0.2) + { + if(g_settings->getBool("free_move")) + { + g_settings->set("free_move","false"); + statustext = L"free_move disabled"; + statustext_time = 0; + } + else + { + g_settings->set("free_move","true"); + statustext = L"free_move enabled"; + statustext_time = 0; + if(!client.checkPrivilege("fly")) + statustext += L" (note: no 'fly' privilege)"; + } + } + reset_jump_timer = true; + } else if(input->wasKeyDown(getKeySetting("keymap_fastmove"))) { if(g_settings->getBool("fast_move")) @@ -1843,6 +1871,13 @@ void the_game( statustext_time = 0; } + // Reset jump_timer + if(!input->isKeyDown(getKeySetting("keymap_jump")) && reset_jump_timer) + { + reset_jump_timer = false; + jump_timer = 0.0; + } + // Handle QuicktuneShortcutter if(input->wasKeyDown(getKeySetting("keymap_quicktune_next"))) quicktune.next(); diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp index 8f7c7245c..336b13e07 100644 --- a/src/guiKeyChangeMenu.cpp +++ b/src/guiKeyChangeMenu.cpp @@ -57,6 +57,7 @@ enum GUI_ID_KEY_RANGE_BUTTON, // other GUI_ID_CB_AUX1_DESCENDS, + GUI_ID_CB_DOUBLETAB_JUMP, }; GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env, @@ -149,6 +150,20 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize) Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this, GUI_ID_CB_AUX1_DESCENDS, wgettext("\"Use\" = climb down")); } + offset += v2s32(0, 25); + } + + { + s32 option_x = offset.X + 10; + s32 option_y = offset.Y; + u32 option_w = 220; + { + core::rect rect(0, 0, option_w, 30); + rect += topleft + v2s32(option_x, option_y); + Environment->addCheckBox(g_settings->getBool("doubletab_jump"), rect, this, + GUI_ID_CB_DOUBLETAB_JUMP, wgettext("Doubltab \"jump\" to toogle fly")); + } + offset += v2s32(0, 25); } { @@ -197,6 +212,11 @@ bool GUIKeyChangeMenu::acceptInput() if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX) g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked()); } + { + gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAB_JUMP); + if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX) + g_settings->setBool("doubletab_jump", ((gui::IGUICheckBox*)e)->isChecked()); + } clearKeyCache(); return true; } From bc879a1453561259b69c9a6602f97062b710235d Mon Sep 17 00:00:00 2001 From: dannydark Date: Thu, 3 Jan 2013 22:32:31 +0000 Subject: [PATCH 13/66] Fixed content_abm aliases Since commit 5a13c49492 when I'm in a new area of the world that hasn't yet been generated the debug log gets flooded with the following error: Map::setNode(): Not allowing to place CONTENT_IGNORE while trying to replace "default:dirt_with_grass" at (729,1,-219) (block (45,0,-14)) This commit fixes that. --- src/content_abm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content_abm.cpp b/src/content_abm.cpp index 5812c7b50..9e65a7ab0 100644 --- a/src/content_abm.cpp +++ b/src/content_abm.cpp @@ -54,7 +54,7 @@ public: !ndef->get(n_top).isLiquid() && n_top.getLightBlend(env->getDayNightRatio(), ndef) >= 13) { - n.setContent(ndef->getId("dirt_with_grass")); + n.setContent(ndef->getId("mapgen_dirt_with_grass")); map->addNodeWithEvent(p, n); } } @@ -83,7 +83,7 @@ public: if(!ndef->get(n_top).light_propagates || ndef->get(n_top).isLiquid()) { - n.setContent(ndef->getId("dirt")); + n.setContent(ndef->getId("mapgen_dirt")); map->addNodeWithEvent(p, n); } } From 615fd498bc04fce67aa72549536d38b503d7d570 Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Fri, 4 Jan 2013 20:00:49 +0100 Subject: [PATCH 14/66] Fix typo doubletab -> doubletap --- minetest.conf.example | 4 ++-- src/defaultsettings.cpp | 2 +- src/game.cpp | 4 ++-- src/guiKeyChangeMenu.cpp | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/minetest.conf.example b/minetest.conf.example index a4448ab61..5bb75bde4 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -51,8 +51,8 @@ #keymap_screenshot = KEY_F12 # If true, keymap_special1 instead of keymap_sneak is used for climbing down and descending #aux1_descends = false -# Doubletabing the jump key toogles fly mode -#doubletab_jump = false +# Doubletaping the jump key toogles fly mode +#doubletap_jump = false # Some (temporary) keys for debugging #keymap_print_debug_stacks = KEY_KEY_P #keymap_quicktune_prev = KEY_HOME diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 82783db0d..75fea84c8 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -56,7 +56,7 @@ void set_default_settings(Settings *settings) settings->setDefault("anaglyph", "false"); settings->setDefault("anaglyph_strength", "0.1"); settings->setDefault("aux1_descends", "false"); - settings->setDefault("doubletab_jump", "false"); + settings->setDefault("doubletap_jump", "false"); // Some (temporary) keys for debugging settings->setDefault("keymap_print_debug_stacks", "KEY_KEY_P"); diff --git a/src/game.cpp b/src/game.cpp index ab480c3db..ca992c056 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1596,7 +1596,7 @@ void the_game( input->step(dtime); // Increase timer for doubleclick of "jump" - if(g_settings->getBool("doubletab_jump") && jump_timer <= 0.2) + if(g_settings->getBool("doubletap_jump") && jump_timer <= 0.2) jump_timer += dtime; /* @@ -1690,7 +1690,7 @@ void the_game( } else if(input->wasKeyDown(getKeySetting("keymap_jump"))) { - if(g_settings->getBool("doubletab_jump") && jump_timer < 0.2) + if(g_settings->getBool("doubletap_jump") && jump_timer < 0.2) { if(g_settings->getBool("free_move")) { diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp index 336b13e07..51a14d647 100644 --- a/src/guiKeyChangeMenu.cpp +++ b/src/guiKeyChangeMenu.cpp @@ -57,7 +57,7 @@ enum GUI_ID_KEY_RANGE_BUTTON, // other GUI_ID_CB_AUX1_DESCENDS, - GUI_ID_CB_DOUBLETAB_JUMP, + GUI_ID_CB_DOUBLETAP_JUMP, }; GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env, @@ -160,8 +160,8 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize) { core::rect rect(0, 0, option_w, 30); rect += topleft + v2s32(option_x, option_y); - Environment->addCheckBox(g_settings->getBool("doubletab_jump"), rect, this, - GUI_ID_CB_DOUBLETAB_JUMP, wgettext("Doubltab \"jump\" to toogle fly")); + Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this, + GUI_ID_CB_DOUBLETAP_JUMP, wgettext("Doubltap \"jump\" to toogle fly")); } offset += v2s32(0, 25); } @@ -213,9 +213,9 @@ bool GUIKeyChangeMenu::acceptInput() g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked()); } { - gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAB_JUMP); + gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAP_JUMP); if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX) - g_settings->setBool("doubletab_jump", ((gui::IGUICheckBox*)e)->isChecked()); + g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked()); } clearKeyCache(); return true; From 46d431e7c3cb1345c34613647a6eb61aabeb087a Mon Sep 17 00:00:00 2001 From: Jeija Date: Fri, 28 Dec 2012 09:52:21 +0100 Subject: [PATCH 15/66] Implement textarea in formspec, a multiline input field --- doc/lua_api.txt | 3 ++ src/guiFormSpecMenu.cpp | 78 ++++++++++++++++++++++++----------------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f891b56f0..34738974a 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -725,6 +725,9 @@ field[;