aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
* Fix crash on can_bypass_userlimit returning non-booleanrubenwardy2018-01-03
|
* Mgv7 floatlands: Add exponent parameterparamat2018-01-03
| | | | | Allows more control over shape of floatland mountain terrain. Terrain shape is unchanged.
* Connected Nodeboxes: Add `disconnected` boxesThomas--S2018-01-03
| | | | | | | | | | | | | | | The `disconnected_*` boxes are the opposites of the `connect_*` ones, i.e. when a node has no suitable neighbours on the respective side, the according disconnected box is drawn. * disconnected_top * disconnected_bottom * disconnected_front * disconnected_left * disconnected_back * disconnected_right * disconnected (when there is *no* neighbour) * disconnected_sides (when there are *no* neighbours to the sides)
* Tool.cpp/.h, lua_api/l_util.cpp: Tidy up code and remove dead codeHybrid Dog2018-01-03
|
* Tool getDigParams: Fix selecting the best fitting timeHybrid Dog2018-01-03
| | | | | Previously, time was compared with result_time before dividing it by the level difference.
* Add unittests on ActiveObject and BanManager class (#6866)Loïc Blot2018-01-01
| | | | | | * Add unittests on ActiveObject and BanManager class This also permit to fix a bug in ban manager setting bans modified when no modification occurs
* Update README.md copyright notice tooLoïc Blot2018-01-01
|
* Happy new year 2018: update LICENSE.txtLoïc Blot2018-01-01
|
* Advanced settings: Add range check for float typeMuhammad Rifqi Priyo Susanto2017-12-26
|
* Fix rounding error in g/set_node caused by truncation to floatrubenwardy2017-12-26
|
* Add check to pause game on lost window focusrubenwardy2017-12-26
|
* Line_of_sight: Improve using VoxelLineIteratorDániel Juhász2017-12-26
| | | | | This commit rewrites line_of_sight with VoxelLineIterator. Stepsize is no longer needed, the results will be always accurate.
* Wireshark plugin: Complete all commands. (#6841)sofar2017-12-26
| | | | | This still leaves plenty of data undecoded, but just having the packet types all covered 100% for 0.4.16 will make looking at traces a lot simpler than seeing half the packets show up as unknown.
* Fix dancing textnumber Zero2017-12-25
|
* - Clear colors when reading property info.Rob Blanckaert2017-12-25
| | | | - Set vertex colors on upright_sprites.
* Fix error if setting menu_last_game is not a valid gamenOOb31672017-12-22
|
* Fix undefined behaviour on getting pointer to data in empty vectornOOb31672017-12-22
| | | | `&vector[0]` is undefined if vector.empty(), causing build failure on MSVC
* Fix wrong scrolling (#6809)Vitaliy2017-12-21
|
* Vector functions: Fix vector.direction() function, improve documentation (#6801)Paramat2017-12-21
| | | vector.direction() now returns a normalised vector with direction p1 to p2.
* Allow 'default' parameter in 'settings:get_bool' functionJordan Irwin2017-12-17
| | | | | | Default value is used when the setting key is not found in the config file. If default value is not set, 'nil' is returned. #6188
* Adjust default console heightEzhh2017-12-17
| | | #6797
* Give subgames the ability to disallow specific mapgens (#6792)Ezhh2017-12-16
|
* Fix items turning black (#6780)Vitaliy2017-12-16
|
* Change Normal Map setting to be less ambigousTre2017-12-16
|
* Zoom: Add 'disabled by game or mod' messageparamat2017-12-14
|
* Minimap messages: Improve 'disabled by server' messageparamat2017-12-14
|
* Add callback to preserve node metadata as item metadataashtrayoz2017-12-14
|
* Chat: Remove prompt history duplicates (#6762)SmallJoker2017-12-14
|
* directiontables: Fix MSVC compiler error (#6785)adrido2017-12-14
|
* Update light decoding table size (#6696)Vitaliy2017-12-12
| | | | Fix old undiminish_light bug
* Builtin: Fix handle_node_drops crash with nil diggerSmallJoker2017-12-12
|
* CSM fixes: load mods after flavours & add flavour to block mod loading (#6738)Loïc Blot2017-12-11
| | | | | | | | | | | | | | * CSM fixes: load mods after flavours & add flavour to block mod loading * Don't permit to load mods twice * Prepare builtin integrity global algorithm * Add missing doc & use a nicer byteflag for LOAD_CLIENT_MODS flavour * flag typo fix * Invert CSM_FL_LOOKUP_NODES & CSM_FL_LOAD_CLIENT_MODS ids
* Lua_api.txt: Fix a spelling errorashtrayoz2017-12-10
|
* F5 debug info: Add colons, use lowercase except for FPS and RTTThomasMonroe3142017-12-10
|
* Damage: Remove damage ignore timerSmallJoker2017-12-10
|
* Use std::vector instead of dynamic C-Array (#6744)adrido2017-12-10
|
* Pointed thing to face pos: Use 'eye height' object property (#6754)Paramat2017-12-09
|
* Add an active object step time budget #6721Lars Hofhansl2017-12-06
| | | | This can be set via the active_object_interval option.
* Add coloured logs (#4549)you2017-12-06
| | | The setting log_colour can be used to en-/disable or autodetect it.
* Auth handler: Player deletion & Iterator (#6741)sfan52017-12-06
| | | | | | | | * Add player deletion method to auth handler (fixes #6653) * Support iterating over the auth database There was no way to do this previously and a recent commit broke doing this the "hacky" way by accessing `core.auth_table`.
* Ensure no item stack is being held before crafting (#4779)Luis Cáceres2017-12-06
|
* Use Irrlicht's mesh cache for animated meshes.Lars Hofhansl2017-12-04
| | | | | | Fixes #6676. Allow animated meshes to be cached in Irrlicht's builtin mesh cache. Use Material.EmmissiveColor instead of manipulating the mesh' vertex colors.
* Zoom: Set zoom FOV per-player using a player object propertyparamat2017-12-04
| | | | | | | | | | | | | Remove player object property 'can zoom'. Add player object property 'zoom fov'. Remove clientside setting for 'zoom fov'. Object property default is 15 degrees in creative mode, zoom disabled in survival mode. Needed due to zoom now loading and/or generating distant world according to zoom FOV. Update object properties serialisation version to 3.
* Android: Update build system for ndk-r15xstujones112017-12-04
| | | | Add workarounds for ndk-r16.
* Document extended meaning of active_object_send_range_blocks setting.Lars Hofhansl2017-12-03
|
* Optionally extend the active object in a players camera direction.Lars Hofhansl2017-12-03
| | | | | | | | | See #6667 By setting active_object_send_range_blocks > active_block_range a server admin can allow clients to retrieve active objects futher out from the player at relatively low cost to the server (only objects in the players' view cone are considered).
* Shut down mapgen threads before other shutdown tasks (#6689)raymoo2017-12-03
| | | | | | Solves some issues with ModStorage functionality in mapgen threads that occurred when mapgen threads continued to run after the main server thread had stopped. Also shuts down mapgen threads before shutdown callbacks are called.
* Update documentation regarding authentication handler and related functionssfan52017-12-01
| | | | | | Properly document it instead of referencing the builtin handler as authoritative "example" code. Also adds definition of get_auth_handler() which was missing previously.
* Make core.auth_table private and structure builtin/auth.luasfan52017-12-01
| | | | If you give modders the ability to do something, they will...
* Lua_api.txt: Remove MT version, fix spelling and clean upezhh2017-12-01
| | | | | Removes references to MT version in intro section. Update bump_version.sh to no longer manage version information.
ass="hl kwd">writeU8(os, 2); // version else writeU8(os, 3); // version writeU8(os, type); os<<serializeString(name); os<<serializeString(description); os<<serializeString(inventory_image); os<<serializeString(wield_image); writeV3F1000(os, wield_scale); writeS16(os, stack_max); writeU8(os, usable); writeU8(os, liquids_pointable); std::string tool_capabilities_s = ""; if(tool_capabilities){ std::ostringstream tmp_os(std::ios::binary); tool_capabilities->serialize(tmp_os, protocol_version); tool_capabilities_s = tmp_os.str(); } os<<serializeString(tool_capabilities_s); writeU16(os, groups.size()); for(std::map<std::string, int>::const_iterator i = groups.begin(); i != groups.end(); ++i){ os<<serializeString(i->first); writeS16(os, i->second); } os<<serializeString(node_placement_prediction); if(protocol_version > 17){ //serializeSimpleSoundSpec(sound_place, os); os<<serializeString(sound_place.name); writeF1000(os, sound_place.gain); } if (protocol_version > 20) { writeF1000(os, range); os << serializeString(sound_place_failed.name); writeF1000(os, sound_place_failed.gain); } } void ItemDefinition::deSerialize(std::istream &is) { // Reset everything reset(); // Deserialize int version = readU8(is); if(version < 1 || version > 3) throw SerializationError("unsupported ItemDefinition version"); type = (enum ItemType)readU8(is); name = deSerializeString(is); description = deSerializeString(is); inventory_image = deSerializeString(is); wield_image = deSerializeString(is); wield_scale = readV3F1000(is); stack_max = readS16(is); usable = readU8(is); liquids_pointable = readU8(is); std::string tool_capabilities_s = deSerializeString(is); if(!tool_capabilities_s.empty()) { std::istringstream tmp_is(tool_capabilities_s, std::ios::binary); tool_capabilities = new ToolCapabilities; tool_capabilities->deSerialize(tmp_is); } groups.clear(); u32 groups_size = readU16(is); for(u32 i=0; i<groups_size; i++){ std::string name = deSerializeString(is); int value = readS16(is); groups[name] = value; } if(version == 1){ // We cant be sure that node_placement_prediction is send in version 1 try{ node_placement_prediction = deSerializeString(is); }catch(SerializationError &e) {}; // Set the old default sound sound_place.name = "default_place_node"; sound_place.gain = 0.5; } else if(version >= 2) { node_placement_prediction = deSerializeString(is); //deserializeSimpleSoundSpec(sound_place, is); sound_place.name = deSerializeString(is); sound_place.gain = readF1000(is); } if(version == 3) { range = readF1000(is); } // If you add anything here, insert it primarily inside the try-catch // block to not need to increase the version. try { sound_place_failed.name = deSerializeString(is); sound_place_failed.gain = readF1000(is); } catch(SerializationError &e) {}; } /* CItemDefManager */ // SUGG: Support chains of aliases? class CItemDefManager: public IWritableItemDefManager { #ifndef SERVER struct ClientCached { video::ITexture *inventory_texture; scene::IMesh *wield_mesh; ClientCached(): inventory_texture(NULL), wield_mesh(NULL) {} }; #endif public: CItemDefManager() { #ifndef SERVER m_main_thread = thr_get_current_thread_id(); #endif clear(); } virtual ~CItemDefManager() { #ifndef SERVER const std::vector<ClientCached*> &values = m_clientcached.getValues(); for(std::vector<ClientCached*>::const_iterator i = values.begin(); i != values.end(); ++i) { ClientCached *cc = *i; if (cc->wield_mesh) cc->wield_mesh->drop(); delete cc; } #endif for (std::map<std::string, ItemDefinition*>::iterator iter = m_item_definitions.begin(); iter != m_item_definitions.end(); ++iter) { delete iter->second; } m_item_definitions.clear(); } virtual const ItemDefinition& get(const std::string &name_) const { // Convert name according to possible alias std::string name = getAlias(name_); // Get the definition std::map<std::string, ItemDefinition*>::const_iterator i; i = m_item_definitions.find(name); if(i == m_item_definitions.end()) i = m_item_definitions.find("unknown"); assert(i != m_item_definitions.end()); return *(i->second); } virtual std::string getAlias(const std::string &name) const { StringMap::const_iterator it = m_aliases.find(name); if (it != m_aliases.end()) return it->second; return name; } virtual std::set<std::string> getAll() const { std::set<std::string> result; for(std::map<std::string, ItemDefinition *>::const_iterator it = m_item_definitions.begin(); it != m_item_definitions.end(); ++it) { result.insert(it->first); } for (StringMap::const_iterator it = m_aliases.begin(); it != m_aliases.end(); ++it) { result.insert(it->first); } return result; } virtual bool isKnown(const std::string &name_) const { // Convert name according to possible alias std::string name = getAlias(name_); // Get the definition std::map<std::string, ItemDefinition*>::const_iterator i; return m_item_definitions.find(name) != m_item_definitions.end(); } #ifndef SERVER public: ClientCached* createClientCachedDirect(const std::string &name, IGameDef *gamedef) const { infostream<<"Lazily creating item texture and mesh for \"" <<name<<"\""<<std::endl; // This is not thread-safe sanity_check(thr_is_current_thread(m_main_thread)); // Skip if already in cache ClientCached *cc = NULL; m_clientcached.get(name, &cc); if(cc) return cc; ITextureSource *tsrc = gamedef->getTextureSource(); const ItemDefinition &def = get(name); // Create new ClientCached cc = new ClientCached(); // Create an inventory texture cc->inventory_texture = NULL; if(def.inventory_image != "") cc->inventory_texture = tsrc->getTexture(def.inventory_image); ItemStack item = ItemStack(); item.name = def.name; scene::IMesh *mesh = getItemMesh(gamedef, item); cc->wield_mesh = mesh; // Put in cache m_clientcached.set(name, cc); return cc; } ClientCached* getClientCached(const std::string &name, IGameDef *gamedef) const { ClientCached *cc = NULL; m_clientcached.get(name, &cc); if(cc) return cc; if(thr_is_current_thread(m_main_thread)) { return createClientCachedDirect(name, gamedef); } else { // We're gonna ask the result to be put into here static ResultQueue<std::string, ClientCached*, u8, u8> result_queue; // Throw a request in m_get_clientcached_queue.add(name, 0, 0, &result_queue); try{ while(true) { // Wait result for a second GetResult<std::string, ClientCached*, u8, u8> result = result_queue.pop_front(1000); if (result.key == name) { return result.item; } } } catch(ItemNotFoundException &e) { errorstream<<"Waiting for clientcached " << name << " timed out."<<std::endl; return &m_dummy_clientcached; } } } // Get item inventory texture virtual video::ITexture* getInventoryTexture(const std::string &name, IGameDef *gamedef) const { ClientCached *cc = getClientCached(name, gamedef); if(!cc) return NULL; return cc->inventory_texture; } // Get item wield mesh virtual scene::IMesh* getWieldMesh(const std::string &name, IGameDef *gamedef) const { ClientCached *cc = getClientCached(name, gamedef); if(!cc) return NULL; return cc->wield_mesh; } #endif void clear() { for(std::map<std::string, ItemDefinition*>::const_iterator i = m_item_definitions.begin(); i != m_item_definitions.end(); ++i) { delete i->second; } m_item_definitions.clear(); m_aliases.clear(); // Add the four builtin items: // "" is the hand // "unknown" is returned whenever an undefined item // is accessed (is also the unknown node) // "air" is the air node // "ignore" is the ignore node ItemDefinition* hand_def = new ItemDefinition; hand_def->name = ""; hand_def->wield_image = "wieldhand.png"; hand_def->tool_capabilities = new ToolCapabilities; m_item_definitions.insert(std::make_pair("", hand_def)); ItemDefinition* unknown_def = new ItemDefinition; unknown_def->type = ITEM_NODE; unknown_def->name = "unknown"; m_item_definitions.insert(std::make_pair("unknown", unknown_def)); ItemDefinition* air_def = new ItemDefinition; air_def->type = ITEM_NODE; air_def->name = "air"; m_item_definitions.insert(std::make_pair("air", air_def)); ItemDefinition* ignore_def = new ItemDefinition; ignore_def->type = ITEM_NODE; ignore_def->name = "ignore"; m_item_definitions.insert(std::make_pair("ignore", ignore_def)); } virtual void registerItem(const ItemDefinition &def) { verbosestream<<"ItemDefManager: registering \""<<def.name<<"\""<<std::endl; // Ensure that the "" item (the hand) always has ToolCapabilities if(def.name == "") FATAL_ERROR_IF(!def.tool_capabilities, "Hand does not have ToolCapabilities"); if(m_item_definitions.count(def.name) == 0) m_item_definitions[def.name] = new ItemDefinition(def); else *(m_item_definitions[def.name]) = def; // Remove conflicting alias if it exists bool alias_removed = (m_aliases.erase(def.name) != 0); if(alias_removed) infostream<<"ItemDefManager: erased alias "<<def.name <<" because item was defined"<<std::endl; } virtual void registerAlias(const std::string &name, const std::string &convert_to) { if(m_item_definitions.find(name) == m_item_definitions.end()) { verbosestream<<"ItemDefManager: setting alias "<<name <<" -> "<<convert_to<<std::endl; m_aliases[name] = convert_to; } } void serialize(std::ostream &os, u16 protocol_version) { writeU8(os, 0); // version u16 count = m_item_definitions.size(); writeU16(os, count); for (std::map<std::string, ItemDefinition *>::const_iterator it = m_item_definitions.begin(); it != m_item_definitions.end(); ++it) { ItemDefinition *def = it->second; // Serialize ItemDefinition and write wrapped in a string std::ostringstream tmp_os(std::ios::binary); def->serialize(tmp_os, protocol_version); os << serializeString(tmp_os.str()); } writeU16(os, m_aliases.size()); for (StringMap::const_iterator it = m_aliases.begin(); it != m_aliases.end(); ++it) { os << serializeString(it->first); os << serializeString(it->second); } } void deSerialize(std::istream &is) { // Clear everything clear(); // Deserialize int version = readU8(is); if(version != 0) throw SerializationError("unsupported ItemDefManager version"); u16 count = readU16(is); for(u16 i=0; i<count; i++) { // Deserialize a string and grab an ItemDefinition from it std::istringstream tmp_is(deSerializeString(is), std::ios::binary); ItemDefinition def; def.deSerialize(tmp_is); // Register registerItem(def); } u16 num_aliases = readU16(is); for(u16 i=0; i<num_aliases; i++) { std::string name = deSerializeString(is); std::string convert_to = deSerializeString(is); registerAlias(name, convert_to); } } void processQueue(IGameDef *gamedef) { #ifndef SERVER //NOTE this is only thread safe for ONE consumer thread! while(!m_get_clientcached_queue.empty()) { GetRequest<std::string, ClientCached*, u8, u8> request = m_get_clientcached_queue.pop(); m_get_clientcached_queue.pushResult(request, createClientCachedDirect(request.key, gamedef)); } #endif } private: // Key is name std::map<std::string, ItemDefinition*> m_item_definitions; // Aliases StringMap m_aliases; #ifndef SERVER // The id of the thread that is allowed to use irrlicht directly threadid_t m_main_thread; // A reference to this can be returned when nothing is found, to avoid NULLs mutable ClientCached m_dummy_clientcached; // Cached textures and meshes mutable MutexedMap<std::string, ClientCached*> m_clientcached; // Queued clientcached fetches (to be processed by the main thread) mutable RequestQueue<std::string, ClientCached*, u8, u8> m_get_clientcached_queue; #endif }; IWritableItemDefManager* createItemDefManager() { return new CItemDefManager(); }