From 725edc78b214f8ffa5494ed846755083295c3feb Mon Sep 17 00:00:00 2001 From: Ekdohibs Date: Sun, 22 May 2016 20:33:06 +0200 Subject: Move updateTextures and fillTileAttribs to ContentFeatures --- src/nodedef.cpp | 534 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 273 insertions(+), 261 deletions(-) (limited to 'src/nodedef.cpp') diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 3a2cb00b1..1691289c2 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -247,6 +247,28 @@ static void deSerializeSimpleSoundSpec(SimpleSoundSpec &ss, std::istream &is) ss.gain = readF1000(is); } +void TextureSettings::readSettings() +{ + connected_glass = g_settings->getBool("connected_glass"); + opaque_water = g_settings->getBool("opaque_water"); + bool enable_shaders = g_settings->getBool("enable_shaders"); + bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping"); + bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion"); + enable_mesh_cache = g_settings->getBool("enable_mesh_cache"); + enable_minimap = g_settings->getBool("enable_minimap"); + std::string leaves_style_str = g_settings->get("leaves_style"); + + use_normal_texture = enable_shaders && + (enable_bumpmapping || enable_parallax_occlusion); + if (leaves_style_str == "fancy") { + leaves_style = LEAVES_FANCY; + } else if (leaves_style_str == "simple") { + leaves_style = LEAVES_SIMPLE; + } else { + leaves_style = LEAVES_OPAQUE; + } +} + /* ContentFeatures */ @@ -486,6 +508,254 @@ void ContentFeatures::deSerialize(std::istream &is) }catch(SerializationError &e) {}; } +#ifndef SERVER +void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, + TileDef *tiledef, u32 shader_id, bool use_normal_texture, + bool backface_culling, u8 alpha, u8 material_type) +{ + tile->shader_id = shader_id; + tile->texture = tsrc->getTextureForMesh(tiledef->name, &tile->texture_id); + tile->alpha = alpha; + tile->material_type = material_type; + + // Normal texture and shader flags texture + if (use_normal_texture) { + tile->normal_texture = tsrc->getNormalTexture(tiledef->name); + } + tile->flags_texture = tsrc->getShaderFlagsTexture(tile->normal_texture ? true : false); + + // Material flags + tile->material_flags = 0; + if (backface_culling) + tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; + if (tiledef->animation.type == TAT_VERTICAL_FRAMES) + tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + if (tiledef->tileable_horizontal) + tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; + if (tiledef->tileable_vertical) + tile->material_flags |= MATERIAL_FLAG_TILEABLE_VERTICAL; + + // Animation parameters + int frame_count = 1; + if (tile->material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) { + // Get texture size to determine frame count by aspect ratio + v2u32 size = tile->texture->getOriginalSize(); + int frame_height = (float)size.X / + (float)tiledef->animation.aspect_w * + (float)tiledef->animation.aspect_h; + frame_count = size.Y / frame_height; + int frame_length_ms = 1000.0 * tiledef->animation.length / frame_count; + tile->animation_frame_count = frame_count; + tile->animation_frame_length_ms = frame_length_ms; + } + + if (frame_count == 1) { + tile->material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; + } else { + std::ostringstream os(std::ios::binary); + tile->frames.resize(frame_count); + + for (int i = 0; i < frame_count; i++) { + + FrameSpec frame; + + os.str(""); + os << tiledef->name << "^[verticalframe:" + << frame_count << ":" << i; + + frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id); + if (tile->normal_texture) + frame.normal_texture = tsrc->getNormalTexture(os.str()); + frame.flags_texture = tile->flags_texture; + tile->frames[i] = frame; + } + } +} +#endif + +#ifndef SERVER +void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc, + scene::ISceneManager *smgr, scene::IMeshManipulator *meshmanip, + IGameDef *gamedef, const TextureSettings &tsettings) +{ + // minimap pixel color - the average color of a texture + if (tsettings.enable_minimap && tiledef[0].name != "") + minimap_color = tsrc->getTextureAverageColor(tiledef[0].name); + + // Figure out the actual tiles to use + TileDef tdef[6]; + for (u32 j = 0; j < 6; j++) { + tdef[j] = tiledef[j]; + if (tdef[j].name == "") + tdef[j].name = "unknown_node.png"; + } + + bool is_liquid = false; + bool is_water_surface = false; + + u8 material_type = (alpha == 255) ? + TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA; + + switch (drawtype) { + default: + case NDT_NORMAL: + solidness = 2; + break; + case NDT_AIRLIKE: + solidness = 0; + break; + case NDT_LIQUID: + assert(liquid_type == LIQUID_SOURCE); + if (tsettings.opaque_water) + alpha = 255; + solidness = 1; + is_liquid = true; + break; + case NDT_FLOWINGLIQUID: + assert(liquid_type == LIQUID_FLOWING); + solidness = 0; + if (tsettings.opaque_water) + alpha = 255; + is_liquid = true; + break; + case NDT_GLASSLIKE: + solidness = 0; + visual_solidness = 1; + break; + case NDT_GLASSLIKE_FRAMED: + solidness = 0; + visual_solidness = 1; + break; + case NDT_GLASSLIKE_FRAMED_OPTIONAL: + solidness = 0; + visual_solidness = 1; + drawtype = tsettings.connected_glass ? NDT_GLASSLIKE_FRAMED : NDT_GLASSLIKE; + break; + case NDT_ALLFACES: + solidness = 0; + visual_solidness = 1; + break; + case NDT_ALLFACES_OPTIONAL: + if (tsettings.leaves_style == LEAVES_FANCY) { + drawtype = NDT_ALLFACES; + solidness = 0; + visual_solidness = 1; + } else if (tsettings.leaves_style == LEAVES_SIMPLE) { + for (u32 j = 0; j < 6; j++) { + if (tiledef_special[j].name != "") + tdef[j].name = tiledef_special[j].name; + } + drawtype = NDT_GLASSLIKE; + solidness = 0; + visual_solidness = 1; + } else { + drawtype = NDT_NORMAL; + solidness = 2; + for (u32 i = 0; i < 6; i++) + tdef[i].name += std::string("^[noalpha"); + } + if (waving == 1) + material_type = TILE_MATERIAL_WAVING_LEAVES; + break; + case NDT_PLANTLIKE: + solidness = 0; + if (waving == 1) + material_type = TILE_MATERIAL_WAVING_PLANTS; + break; + case NDT_FIRELIKE: + solidness = 0; + break; + case NDT_MESH: + solidness = 0; + break; + case NDT_TORCHLIKE: + case NDT_SIGNLIKE: + case NDT_FENCELIKE: + case NDT_RAILLIKE: + case NDT_NODEBOX: + solidness = 0; + break; + } + + if (is_liquid) { + material_type = (alpha == 255) ? + TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT; + if (name == "default:water_source") + is_water_surface = true; + } + + u32 tile_shader[6]; + for (u16 j = 0; j < 6; j++) { + tile_shader[j] = shdsrc->getShader("nodes_shader", + material_type, drawtype); + } + + if (is_water_surface) { + tile_shader[0] = shdsrc->getShader("water_surface_shader", + material_type, drawtype); + } + + // Tiles (fill in f->tiles[]) + for (u16 j = 0; j < 6; j++) { + fillTileAttribs(tsrc, &tiles[j], &tdef[j], tile_shader[j], + tsettings.use_normal_texture, + tiledef[j].backface_culling, alpha, material_type); + } + + // Special tiles (fill in f->special_tiles[]) + for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) { + fillTileAttribs(tsrc, &special_tiles[j], &tiledef_special[j], + tile_shader[j], tsettings.use_normal_texture, + tiledef_special[j].backface_culling, alpha, material_type); + } + + if ((drawtype == NDT_MESH) && (mesh != "")) { + // Meshnode drawtype + // Read the mesh and apply scale + mesh_ptr[0] = gamedef->getMesh(mesh); + if (mesh_ptr[0]){ + v3f scale = v3f(1.0, 1.0, 1.0) * BS * visual_scale; + scaleMesh(mesh_ptr[0], scale); + recalculateBoundingBox(mesh_ptr[0]); + meshmanip->recalculateNormals(mesh_ptr[0], true, false); + } + } else if ((drawtype == NDT_NODEBOX) && + ((node_box.type == NODEBOX_REGULAR) || + (node_box.type == NODEBOX_FIXED)) && + (!node_box.fixed.empty())) { + //Convert regular nodebox nodes to meshnodes + //Change the drawtype and apply scale + drawtype = NDT_MESH; + mesh_ptr[0] = convertNodeboxesToMesh(node_box.fixed); + v3f scale = v3f(1.0, 1.0, 1.0) * visual_scale; + scaleMesh(mesh_ptr[0], scale); + recalculateBoundingBox(mesh_ptr[0]); + meshmanip->recalculateNormals(mesh_ptr[0], true, false); + } + + //Cache 6dfacedir and wallmounted rotated clones of meshes + if (tsettings.enable_mesh_cache && mesh_ptr[0] && (param_type_2 == CPT2_FACEDIR)) { + for (u16 j = 1; j < 24; j++) { + mesh_ptr[j] = cloneMesh(mesh_ptr[0]); + rotateMeshBy6dFacedir(mesh_ptr[j], j); + recalculateBoundingBox(mesh_ptr[j]); + meshmanip->recalculateNormals(mesh_ptr[j], true, false); + } + } else if (tsettings.enable_mesh_cache && mesh_ptr[0] && (param_type_2 == CPT2_WALLMOUNTED)) { + static const u8 wm_to_6d[6] = {20, 0, 16+1, 12+3, 8, 4+2}; + for (u16 j = 1; j < 6; j++) { + mesh_ptr[j] = cloneMesh(mesh_ptr[0]); + rotateMeshBy6dFacedir(mesh_ptr[j], wm_to_6d[j]); + recalculateBoundingBox(mesh_ptr[j]); + meshmanip->recalculateNormals(mesh_ptr[j], true, false); + } + rotateMeshBy6dFacedir(mesh_ptr[0], wm_to_6d[0]); + recalculateBoundingBox(mesh_ptr[0]); + meshmanip->recalculateNormals(mesh_ptr[0], true, false); + } +} +#endif + /* CNodeDefManager */ @@ -525,11 +795,6 @@ public: private: void addNameIdMapping(content_t i, std::string name); -#ifndef SERVER - void fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, TileDef *tiledef, - u32 shader_id, bool use_normal_texture, bool backface_culling, - u8 alpha, u8 material_type); -#endif // Features indexed by id std::vector m_content_features; @@ -890,271 +1155,18 @@ void CNodeDefManager::updateTextures(IGameDef *gamedef, IShaderSource *shdsrc = gamedef->getShaderSource(); scene::ISceneManager* smgr = gamedef->getSceneManager(); scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator(); - - bool connected_glass = g_settings->getBool("connected_glass"); - bool opaque_water = g_settings->getBool("opaque_water"); - bool enable_shaders = g_settings->getBool("enable_shaders"); - bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping"); - bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion"); - bool enable_mesh_cache = g_settings->getBool("enable_mesh_cache"); - bool enable_minimap = g_settings->getBool("enable_minimap"); - std::string leaves_style = g_settings->get("leaves_style"); - - bool use_normal_texture = enable_shaders && - (enable_bumpmapping || enable_parallax_occlusion); + TextureSettings tsettings; + tsettings.readSettings(); u32 size = m_content_features.size(); for (u32 i = 0; i < size; i++) { - ContentFeatures *f = &m_content_features[i]; - - // minimap pixel color - the average color of a texture - if (enable_minimap && f->tiledef[0].name != "") - f->minimap_color = tsrc->getTextureAverageColor(f->tiledef[0].name); - - // Figure out the actual tiles to use - TileDef tiledef[6]; - for (u32 j = 0; j < 6; j++) { - tiledef[j] = f->tiledef[j]; - if (tiledef[j].name == "") - tiledef[j].name = "unknown_node.png"; - } - - bool is_liquid = false; - bool is_water_surface = false; - - u8 material_type = (f->alpha == 255) ? - TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA; - - switch (f->drawtype) { - default: - case NDT_NORMAL: - f->solidness = 2; - break; - case NDT_AIRLIKE: - f->solidness = 0; - break; - case NDT_LIQUID: - assert(f->liquid_type == LIQUID_SOURCE); - if (opaque_water) - f->alpha = 255; - f->solidness = 1; - is_liquid = true; - break; - case NDT_FLOWINGLIQUID: - assert(f->liquid_type == LIQUID_FLOWING); - f->solidness = 0; - if (opaque_water) - f->alpha = 255; - is_liquid = true; - break; - case NDT_GLASSLIKE: - f->solidness = 0; - f->visual_solidness = 1; - break; - case NDT_GLASSLIKE_FRAMED: - f->solidness = 0; - f->visual_solidness = 1; - break; - case NDT_GLASSLIKE_FRAMED_OPTIONAL: - f->solidness = 0; - f->visual_solidness = 1; - f->drawtype = connected_glass ? NDT_GLASSLIKE_FRAMED : NDT_GLASSLIKE; - break; - case NDT_ALLFACES: - f->solidness = 0; - f->visual_solidness = 1; - break; - case NDT_ALLFACES_OPTIONAL: - if (leaves_style == "fancy") { - f->drawtype = NDT_ALLFACES; - f->solidness = 0; - f->visual_solidness = 1; - } else if (leaves_style == "simple") { - for (u32 j = 0; j < 6; j++) { - if (f->tiledef_special[j].name != "") - tiledef[j].name = f->tiledef_special[j].name; - } - f->drawtype = NDT_GLASSLIKE; - f->solidness = 0; - f->visual_solidness = 1; - } else { - f->drawtype = NDT_NORMAL; - f->solidness = 2; - for (u32 i = 0; i < 6; i++) - tiledef[i].name += std::string("^[noalpha"); - } - if (f->waving == 1) - material_type = TILE_MATERIAL_WAVING_LEAVES; - break; - case NDT_PLANTLIKE: - f->solidness = 0; - if (f->waving == 1) - material_type = TILE_MATERIAL_WAVING_PLANTS; - break; - case NDT_FIRELIKE: - f->solidness = 0; - break; - case NDT_MESH: - f->solidness = 0; - break; - case NDT_TORCHLIKE: - case NDT_SIGNLIKE: - case NDT_FENCELIKE: - case NDT_RAILLIKE: - case NDT_NODEBOX: - f->solidness = 0; - break; - } - - if (is_liquid) { - material_type = (f->alpha == 255) ? - TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT; - if (f->name == "default:water_source") - is_water_surface = true; - } - - u32 tile_shader[6]; - for (u16 j = 0; j < 6; j++) { - tile_shader[j] = shdsrc->getShader("nodes_shader", - material_type, f->drawtype); - } - - if (is_water_surface) { - tile_shader[0] = shdsrc->getShader("water_surface_shader", - material_type, f->drawtype); - } - - // Tiles (fill in f->tiles[]) - for (u16 j = 0; j < 6; j++) { - fillTileAttribs(tsrc, &f->tiles[j], &tiledef[j], tile_shader[j], - use_normal_texture, f->tiledef[j].backface_culling, f->alpha, material_type); - } - - // Special tiles (fill in f->special_tiles[]) - for (u16 j = 0; j < CF_SPECIAL_COUNT; j++) { - fillTileAttribs(tsrc, &f->special_tiles[j], &f->tiledef_special[j], - tile_shader[j], use_normal_texture, - f->tiledef_special[j].backface_culling, f->alpha, material_type); - } - - if ((f->drawtype == NDT_MESH) && (f->mesh != "")) { - // Meshnode drawtype - // Read the mesh and apply scale - f->mesh_ptr[0] = gamedef->getMesh(f->mesh); - if (f->mesh_ptr[0]){ - v3f scale = v3f(1.0, 1.0, 1.0) * BS * f->visual_scale; - scaleMesh(f->mesh_ptr[0], scale); - recalculateBoundingBox(f->mesh_ptr[0]); - meshmanip->recalculateNormals(f->mesh_ptr[0], true, false); - } - } else if ((f->drawtype == NDT_NODEBOX) && - ((f->node_box.type == NODEBOX_REGULAR) || - (f->node_box.type == NODEBOX_FIXED)) && - (!f->node_box.fixed.empty())) { - //Convert regular nodebox nodes to meshnodes - //Change the drawtype and apply scale - f->drawtype = NDT_MESH; - f->mesh_ptr[0] = convertNodeboxesToMesh(f->node_box.fixed); - v3f scale = v3f(1.0, 1.0, 1.0) * f->visual_scale; - scaleMesh(f->mesh_ptr[0], scale); - recalculateBoundingBox(f->mesh_ptr[0]); - meshmanip->recalculateNormals(f->mesh_ptr[0], true, false); - } - - //Cache 6dfacedir and wallmounted rotated clones of meshes - if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_FACEDIR)) { - for (u16 j = 1; j < 24; j++) { - f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]); - rotateMeshBy6dFacedir(f->mesh_ptr[j], j); - recalculateBoundingBox(f->mesh_ptr[j]); - meshmanip->recalculateNormals(f->mesh_ptr[j], true, false); - } - } else if (enable_mesh_cache && f->mesh_ptr[0] && (f->param_type_2 == CPT2_WALLMOUNTED)) { - static const u8 wm_to_6d[6] = {20, 0, 16+1, 12+3, 8, 4+2}; - for (u16 j = 1; j < 6; j++) { - f->mesh_ptr[j] = cloneMesh(f->mesh_ptr[0]); - rotateMeshBy6dFacedir(f->mesh_ptr[j], wm_to_6d[j]); - recalculateBoundingBox(f->mesh_ptr[j]); - meshmanip->recalculateNormals(f->mesh_ptr[j], true, false); - } - rotateMeshBy6dFacedir(f->mesh_ptr[0], wm_to_6d[0]); - recalculateBoundingBox(f->mesh_ptr[0]); - meshmanip->recalculateNormals(f->mesh_ptr[0], true, false); - } - + m_content_features[i].updateTextures(tsrc, shdsrc, smgr, meshmanip, gamedef, tsettings); progress_callback(progress_callback_args, i, size); } #endif } - -#ifndef SERVER -void CNodeDefManager::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, - TileDef *tiledef, u32 shader_id, bool use_normal_texture, - bool backface_culling, u8 alpha, u8 material_type) -{ - tile->shader_id = shader_id; - tile->texture = tsrc->getTextureForMesh(tiledef->name, &tile->texture_id); - tile->alpha = alpha; - tile->material_type = material_type; - - // Normal texture and shader flags texture - if (use_normal_texture) { - tile->normal_texture = tsrc->getNormalTexture(tiledef->name); - } - tile->flags_texture = tsrc->getShaderFlagsTexture(tile->normal_texture ? true : false); - - // Material flags - tile->material_flags = 0; - if (backface_culling) - tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; - if (tiledef->animation.type == TAT_VERTICAL_FRAMES) - tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; - if (tiledef->tileable_horizontal) - tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; - if (tiledef->tileable_vertical) - tile->material_flags |= MATERIAL_FLAG_TILEABLE_VERTICAL; - - // Animation parameters - int frame_count = 1; - if (tile->material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) { - // Get texture size to determine frame count by aspect ratio - v2u32 size = tile->texture->getOriginalSize(); - int frame_height = (float)size.X / - (float)tiledef->animation.aspect_w * - (float)tiledef->animation.aspect_h; - frame_count = size.Y / frame_height; - int frame_length_ms = 1000.0 * tiledef->animation.length / frame_count; - tile->animation_frame_count = frame_count; - tile->animation_frame_length_ms = frame_length_ms; - } - - if (frame_count == 1) { - tile->material_flags &= ~MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; - } else { - std::ostringstream os(std::ios::binary); - tile->frames.resize(frame_count); - - for (int i = 0; i < frame_count; i++) { - - FrameSpec frame; - - os.str(""); - os << tiledef->name << "^[verticalframe:" - << frame_count << ":" << i; - - frame.texture = tsrc->getTextureForMesh(os.str(), &frame.texture_id); - if (tile->normal_texture) - frame.normal_texture = tsrc->getNormalTexture(os.str()); - frame.flags_texture = tile->flags_texture; - tile->frames[i] = frame; - } - } -} -#endif - - void CNodeDefManager::serialize(std::ostream &os, u16 protocol_version) const { writeU8(os, 1); // version -- cgit v1.2.3 From 1b8dbf072ad042542b6bfb29eaed81b8a21ac38c Mon Sep 17 00:00:00 2001 From: Yutao Yuan Date: Tue, 14 Jun 2016 06:29:15 +0800 Subject: Move unknown node message when applying texture overrides to infostream (#4218) Texture packs have no way to know what nodes are available, so this shouldn't be a error message. --- src/nodedef.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nodedef.cpp') diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 1691289c2..764203efc 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1107,7 +1107,7 @@ void CNodeDefManager::applyTextureOverrides(const std::string &override_filepath content_t id; if (!getId(splitted[0], id)) { - errorstream << override_filepath + infostream << override_filepath << ":" << line_c << " Could not apply texture override \"" << line << "\": Unknown node \"" << splitted[0] << "\"" << std::endl; -- cgit v1.2.3 From e58a55aa82dfc66325a694dcc3519d3c0f3388a6 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 10 Dec 2015 22:58:11 -0800 Subject: Make plantlike drawtype more fun Adds several new ways that the plantlike drawtype mesh can be changed. This requires paramtype2 = "meshoptions" to be set in the node definition. The drawtype for these nodes should be "plantlike". These modifications are all done using param2. This field is now a complex bitfield that allows some or more of the combinations to be chosen, and the mesh draw code will choose the options based as neeeded for each plantlike node. bit layout: bits 0, 1 and 2 (values 0x1 through 0x7) are for choosing the plant mesh shape: 0 - ordinary plantlike plant ("x" shaped) 1 - ordinary plant, but rotated 45 degrees ("+" shaped) 2 - a plant with 3 faces ("*" shaped) 3 - a plant with 4 faces ("#" shaped) 4 - a plant with 4 faces ("#" shaped, leaning outwards) 5 through 7 are unused and reserved for future mesh shapes. bit 3 (0x8) causes the plant to be randomly offset in the x,z plane. The plant should fall within the 1x1x1 nodebox if regularly sized. bit 4 (0x10) causes the plant mesh to grow by sqrt(2), and will cause the plant mesh to fill out 1x1x1, and appear slightly larger. Texture makers will want to make their plant texture 23x16 pixels to have the best visual fit in 1x1x1 size. bit 5 (0x20) causes each face of the plant to have a slight negative Y offset in position, descending up to 0.125 downwards into the node below. Because this is per face, this causes the plant model to be less symmetric. bit 6 (0x40) through bit 7 (0x80) are unused and reserved for future use. !(https://youtu.be/qWuI664krsI) --- doc/lua_api.txt | 16 +++++ src/content_mapblock.cpp | 152 +++++++++++++++++++++++++++++++++++++++--- src/network/networkprotocol.h | 4 +- src/nodedef.cpp | 5 +- src/nodedef.h | 2 + src/script/cpp_api/s_node.cpp | 1 + 6 files changed, 167 insertions(+), 13 deletions(-) (limited to 'src/nodedef.cpp') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 38f19aadc..440edd963 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -578,6 +578,22 @@ node definition: ^ The rotation of this node is stored in param2. Plants are rotated this way. Values range 0 - 179. The value stored in param2 is multiplied by two to get the actual rotation of the node. + paramtype2 == "meshoptions" + ^ Only valid for "plantlike". The value of param2 becomes a bitfield which can + be used to change how the client draws plantlike nodes. Bits 0, 1 and 2 form + a mesh selector. Currently the following meshes are choosable: + 0 = a "x" shaped plant (ordinary plant) + 1 = a "+" shaped plant (just rotated 45 degrees) + 2 = a "*" shaped plant with 3 faces instead of 2 + 3 = a "#" shaped plant with 4 faces instead of 2 + 4 = a "#" shaped plant with 4 faces that lean outwards + 5-7 are unused and reserved for future meshes. + Bits 3 through 7 are optional flags that can be combined and give these + effects: + bit 3 (0x08) - Makes the plant slightly vary placement horizontally + bit 4 (0x10) - Makes the plant mesh 1.4x larger + bit 5 (0x20) - Moves each face randomly a small bit down (1/8 max) + bits 6-7 are reserved for future use. collision_box = { type = "fixed", fixed = { diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 6a83bd8f3..b86b97822 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "gamedef.h" #include "log.h" +#include "noise.h" // Create a cuboid. @@ -1104,6 +1105,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data, break;} case NDT_PLANTLIKE: { + PseudoRandom rng(x<<8 | z | y<<16); + TileSpec tile = getNodeTileN(n, p, 0, data); tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; @@ -1111,9 +1114,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::SColor c = MapBlock_LightColor(255, l, f.light_source); float s = BS / 2 * f.visual_scale; + // add sqrt(2) visual scale + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x10) != 0)) + s *= 1.41421; + + float random_offset_X = .0; + float random_offset_Z = .0; + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x8) != 0)) { + random_offset_X = BS * ((rng.next() % 16 / 16.0) * 0.29 - 0.145); + random_offset_Z = BS * ((rng.next() % 16 / 16.0) * 0.29 - 0.145); + } - for (int j = 0; j < 2; j++) - { + for (int j = 0; j < 4; j++) { video::S3DVertex vertices[4] = { video::S3DVertex(-s,-BS/2, 0, 0,0,0, c, 0,1), @@ -1121,28 +1133,146 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex( s,-BS/2 + s*2,0, 0,0,0, c, 1,0), video::S3DVertex(-s,-BS/2 + s*2,0, 0,0,0, c, 0,0), }; + float rotate_degree = 0; + u8 p2mesh = 0; if (f.param_type_2 == CPT2_DEGROTATE) rotate_degree = n.param2 * 2; - - if (j == 0) { - for(u16 i = 0; i < 4; i++) - vertices[i].Pos.rotateXZBy(46 + rotate_degree); - } else if (j == 1) { - for(u16 i = 0; i < 4; i++) - vertices[i].Pos.rotateXZBy(-44 + rotate_degree); + else if (f.param_type_2 != CPT2_MESHOPTIONS) { + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(46 + rotate_degree); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(-44 + rotate_degree); + } + } else { + p2mesh = n.param2 & 0x7; + switch (p2mesh) { + case 0: + // x + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(46); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(-44); + } + break; + case 1: + // + + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(91); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(1); + } + break; + case 2: + // * + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(121); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(241); + } else { // (j == 2) + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(1); + } + break; + case 3: + // # + switch (j) { + case 0: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(1); + vertices[i].Pos.Z += BS / 4; + } + break; + case 1: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(91); + vertices[i].Pos.X += BS / 4; + } + break; + case 2: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(181); + vertices[i].Pos.Z -= BS / 4; + } + break; + case 3: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(271); + vertices[i].Pos.X -= BS / 4; + } + break; + } + break; + case 4: + // outward leaning #-like + switch (j) { + case 0: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(1); + break; + case 1: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(91); + break; + case 2: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(181); + break; + case 3: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(271); + break; + } + break; + } } - for (int i = 0; i < 4; i++) - { + for (int i = 0; i < 4; i++) { vertices[i].Pos *= f.visual_scale; vertices[i].Pos.Y += BS/2 * (f.visual_scale - 1); vertices[i].Pos += intToFloat(p, BS); + // move to a random spot to avoid moire + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x8) != 0)) { + vertices[i].Pos.X += random_offset_X; + vertices[i].Pos.Z += random_offset_Z; + } + // randomly move each face up/down + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x20) != 0)) { + PseudoRandom yrng(j | x<<16 | z<<8 | y<<24 ); + vertices[i].Pos.Y -= BS * ((yrng.next() % 16 / 16.0) * 0.125); + } } u16 indices[] = {0, 1, 2, 2, 3, 0}; // Add to mesh collector collector.append(tile, vertices, 4, indices, 6); + + // stop adding faces for meshes with less than 4 faces + if (f.param_type_2 == CPT2_MESHOPTIONS) { + if (((p2mesh == 0) || (p2mesh == 1)) && (j == 1)) + break; + else if ((p2mesh == 2) && (j == 2)) + break; + } else if (j == 1) { + break; + } + } break;} case NDT_FIRELIKE: diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 3a9483efb..e3fcae0c6 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -136,9 +136,11 @@ with this program; if not, write to the Free Software Foundation, Inc., backface_culling: backwards compatibility for playing with newer client on pre-27 servers. Add nodedef v3 - connected nodeboxes + PROTOCOL_VERSION 28: + CPT2_MESHOPTIONS */ -#define LATEST_PROTOCOL_VERSION 27 +#define LATEST_PROTOCOL_VERSION 28 // Server's supported network protocol range #define SERVER_PROTOCOL_VERSION_MIN 13 diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 764203efc..646375575 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -387,7 +387,10 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const writeU8(os, post_effect_color.getGreen()); writeU8(os, post_effect_color.getBlue()); writeU8(os, param_type); - writeU8(os, param_type_2); + if ((protocol_version < 28) && (param_type_2 == CPT2_MESHOPTIONS)) + writeU8(os, CPT2_NONE); + else + writeU8(os, param_type_2); writeU8(os, is_ground_content); writeU8(os, light_propagates); writeU8(os, sunlight_propagates); diff --git a/src/nodedef.h b/src/nodedef.h index 1c2f792d8..f17c53727 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -65,6 +65,8 @@ enum ContentParamType2 CPT2_LEVELED, // 2D rotation for things like plants CPT2_DEGROTATE, + // Mesh options for plants + CPT2_MESHOPTIONS }; enum LiquidType diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index 17f0f0dac..379ed773f 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -58,6 +58,7 @@ struct EnumString ScriptApiNode::es_ContentParamType2[] = {CPT2_WALLMOUNTED, "wallmounted"}, {CPT2_LEVELED, "leveled"}, {CPT2_DEGROTATE, "degrotate"}, + {CPT2_MESHOPTIONS, "meshoptions"}, {0, NULL}, }; -- cgit v1.2.3 From aa33166386f737f213f1f3005ffd6a6adfd2d97f Mon Sep 17 00:00:00 2001 From: paly2 Date: Sun, 10 Jul 2016 15:15:43 +0200 Subject: Add minetest.unregister_item and minetest.register_alias_force --- builtin/game/register.lua | 38 ++++++++++++++++++++++++++++++++++++++ doc/lua_api.txt | 15 ++++++++++++++- src/itemdef.cpp | 10 ++++++++-- src/itemdef.h | 1 + src/nodedef.cpp | 35 +++++++++++++++++++++++++++++++++++ src/nodedef.h | 2 ++ src/script/lua_api/l_item.cpp | 22 ++++++++++++++++++++++ src/script/lua_api/l_item.h | 1 + 8 files changed, 121 insertions(+), 3 deletions(-) (limited to 'src/nodedef.cpp') diff --git a/builtin/game/register.lua b/builtin/game/register.lua index f330491a2..05dc5fef8 100644 --- a/builtin/game/register.lua +++ b/builtin/game/register.lua @@ -7,6 +7,9 @@ local register_item_raw = core.register_item_raw core.register_item_raw = nil +local unregister_item_raw = core.unregister_item_raw +core.unregister_item_raw = nil + local register_alias_raw = core.register_alias_raw core.register_alias_raw = nil @@ -172,6 +175,27 @@ function core.register_item(name, itemdef) register_item_raw(itemdef) end +function core.unregister_item(name) + if not core.registered_items[name] then + core.log("warning", "Not unregistering item " ..name.. + " because it doesn't exist.") + return + end + -- Erase from registered_* table + local type = core.registered_items[name].type + if type == "node" then + core.registered_nodes[name] = nil + elseif type == "craft" then + core.registered_craftitems[name] = nil + elseif type == "tool" then + core.registered_tools[name] = nil + end + core.registered_items[name] = nil + + + unregister_item_raw(name) +end + function core.register_node(name, nodedef) nodedef.type = "node" core.register_item(name, nodedef) @@ -242,6 +266,20 @@ function core.register_alias(name, convert_to) end end +function core.register_alias_force(name, convert_to) + if forbidden_item_names[name] then + error("Unable to register alias: Name is forbidden: " .. name) + end + if core.registered_items[name] ~= nil then + core.unregister_item(name) + core.log("info", "Removed item " ..name.. + " while attempting to force add an alias") + end + --core.log("Registering alias: " .. name .. " -> " .. convert_to) + core.registered_aliases[name] = convert_to + register_alias_raw(name, convert_to) +end + function core.on_craft(itemstack, player, old_craft_list, craft_inv) for _, func in ipairs(core.registered_on_crafts) do itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 579fe796e..da9ebb9f1 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -208,11 +208,17 @@ when registering it. The `:` prefix can also be used for maintaining backwards compatibility. ### Aliases -Aliases can be added by using `minetest.register_alias(name, convert_to)`. +Aliases can be added by using `minetest.register_alias(name, convert_to)` or +`minetest.register_alias_force(name, convert_to). This will make Minetest to convert things called name to things called `convert_to`. +The only difference between `minetest.register_alias` and +`minetest.register_alias_force` is that if an item called `name` exists, +`minetest.register_alias` will do nothing while +`minetest.register_alias_force` will unregister it. + This can be used for maintaining backwards compatibility. This can be also used for setting quick access names for things, e.g. if @@ -464,6 +470,11 @@ the global `minetest.registered_*` tables. * `minetest.register_craftitem(name, item definition)` * added to `minetest.registered_items[name]` +* `minetest.unregister_item(name)` + * Unregisters the item name from engine, and deletes the entry with key + * `name` from `minetest.registered_items` and from the associated item + * table according to its nature: minetest.registered_nodes[] etc + * `minetest.register_biome(biome definition)` * returns an integer uniquely identifying the registered biome * added to `minetest.registered_biome` with the key of `biome.name` @@ -1883,7 +1894,9 @@ Call these functions only at load time! * `minetest.register_node(name, node definition)` * `minetest.register_tool(name, item definition)` * `minetest.register_craftitem(name, item definition)` +* `minetest.unregister_item(name)` * `minetest.register_alias(name, convert_to)` +* `minetest.register_alias_force(name, convert_to)` * `minetest.register_craft(recipe)` * Check recipe table syntax for different types below. * `minetest.clear_craft(recipe)` diff --git a/src/itemdef.cpp b/src/itemdef.cpp index a618ad631..a6c627a03 100644 --- a/src/itemdef.cpp +++ b/src/itemdef.cpp @@ -466,11 +466,17 @@ public: infostream<<"ItemDefManager: erased alias "< "< will load as . // Alias is not set if has already been defined. // Alias will be removed if is defined at a later point of time. diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 646375575..bfb2999bd 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -778,6 +778,7 @@ public: content_t allocateId(); virtual content_t set(const std::string &name, const ContentFeatures &def); virtual content_t allocateDummy(const std::string &name); + virtual void removeNode(const std::string &name); virtual void updateAliases(IItemDefManager *idef); virtual void applyTextureOverrides(const std::string &override_filepath); virtual void updateTextures(IGameDef *gamedef, @@ -1072,6 +1073,40 @@ content_t CNodeDefManager::allocateDummy(const std::string &name) } +void CNodeDefManager::removeNode(const std::string &name) +{ + // Pre-condition + assert(name != ""); + + // Erase name from name ID mapping + content_t id = CONTENT_IGNORE; + if (m_name_id_mapping.getId(name, id)) { + m_name_id_mapping.eraseName(name); + m_name_id_mapping_with_aliases.erase(name); + } + + // Erase node content from all groups it belongs to + for (std::map::iterator iter_groups = + m_group_to_items.begin(); + iter_groups != m_group_to_items.end();) { + GroupItems &items = iter_groups->second; + for (GroupItems::iterator iter_groupitems = items.begin(); + iter_groupitems != items.end();) { + if (iter_groupitems->first == id) + items.erase(iter_groupitems++); + else + iter_groupitems++; + } + + // Check if group is empty + if (items.size() == 0) + m_group_to_items.erase(iter_groups++); + else + iter_groups++; + } +} + + void CNodeDefManager::updateAliases(IItemDefManager *idef) { std::set all = idef->getAll(); diff --git a/src/nodedef.h b/src/nodedef.h index f17c53727..80396f992 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -384,6 +384,8 @@ public: const ContentFeatures &def)=0; // If returns CONTENT_IGNORE, could not allocate id virtual content_t allocateDummy(const std::string &name)=0; + // Remove a node + virtual void removeNode(const std::string &name)=0; /* Update item alias mapping. diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index 5381cba76..ff0baea14 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -525,6 +525,27 @@ int ModApiItemMod::l_register_item_raw(lua_State *L) return 0; /* number of results */ } +// unregister_item(name) +int ModApiItemMod::l_unregister_item_raw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + std::string name = luaL_checkstring(L, 1); + + IWritableItemDefManager *idef = + getServer(L)->getWritableItemDefManager(); + + // Unregister the node + if (idef->get(name).type == ITEM_NODE) { + IWritableNodeDefManager *ndef = + getServer(L)->getWritableNodeDefManager(); + ndef->removeNode(name); + } + + idef->unregisterItem(name); + + return 0; /* number of results */ +} + // register_alias_raw(name, convert_to_name) int ModApiItemMod::l_register_alias_raw(lua_State *L) { @@ -570,6 +591,7 @@ int ModApiItemMod::l_get_name_from_content_id(lua_State *L) void ModApiItemMod::Initialize(lua_State *L, int top) { API_FCT(register_item_raw); + API_FCT(unregister_item_raw); API_FCT(register_alias_raw); API_FCT(get_content_id); API_FCT(get_name_from_content_id); diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index 0f9e4ba9b..be919b701 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -135,6 +135,7 @@ public: class ModApiItemMod : public ModApiBase { private: static int l_register_item_raw(lua_State *L); + static int l_unregister_item_raw(lua_State *L); static int l_register_alias_raw(lua_State *L); static int l_get_content_id(lua_State *L); static int l_get_name_from_content_id(lua_State *L); -- cgit v1.2.3 From d4a2e23793d2260f263396480b6552a37c8ebf6b Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Sun, 17 Jul 2016 22:26:23 +0200 Subject: Textures: Ignore unknown node in override.txt --- src/nodedef.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/nodedef.cpp') diff --git a/src/nodedef.cpp b/src/nodedef.cpp index bfb2999bd..fa2e621f2 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -1144,13 +1144,8 @@ void CNodeDefManager::applyTextureOverrides(const std::string &override_filepath } content_t id; - if (!getId(splitted[0], id)) { - infostream << override_filepath - << ":" << line_c << " Could not apply texture override \"" - << line << "\": Unknown node \"" - << splitted[0] << "\"" << std::endl; - continue; - } + if (!getId(splitted[0], id)) + continue; // Ignore unknown node ContentFeatures &nodedef = m_content_features[id]; -- cgit v1.2.3 From 9393e4a0a8e32905d32a9dc58131218aee318686 Mon Sep 17 00:00:00 2001 From: gregorycu Date: Sun, 9 Oct 2016 00:08:35 +1100 Subject: Speed up emerge thread by using unordered map in a few places. Looking at 25% speedup in Emerge thread on Just Test. --- src/nodedef.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nodedef.cpp') diff --git a/src/nodedef.cpp b/src/nodedef.cpp index fa2e621f2..39ea1a60e 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -810,12 +810,12 @@ private: // item aliases too. Updated by updateAliases() // Note: Not serialized. - std::map m_name_id_mapping_with_aliases; + UNORDERED_MAP m_name_id_mapping_with_aliases; // A mapping from groups to a list of content_ts (and their levels) // that belong to it. Necessary for a direct lookup in getIds(). // Note: Not serialized. - std::map m_group_to_items; + UNORDERED_MAP m_group_to_items; // Next possibly free id content_t m_next_id; @@ -938,7 +938,7 @@ inline const ContentFeatures& CNodeDefManager::get(const MapNode &n) const bool CNodeDefManager::getId(const std::string &name, content_t &result) const { - std::map::const_iterator + UNORDERED_MAP::const_iterator i = m_name_id_mapping_with_aliases.find(name); if(i == m_name_id_mapping_with_aliases.end()) return false; @@ -968,7 +968,7 @@ bool CNodeDefManager::getIds(const std::string &name, } std::string group = name.substr(6); - std::map::const_iterator + UNORDERED_MAP::const_iterator i = m_group_to_items.find(group); if (i == m_group_to_items.end()) return true; @@ -1050,7 +1050,7 @@ content_t CNodeDefManager::set(const std::string &name, const ContentFeatures &d i != def.groups.end(); ++i) { std::string group_name = i->first; - std::map::iterator + UNORDERED_MAP::iterator j = m_group_to_items.find(group_name); if (j == m_group_to_items.end()) { m_group_to_items[group_name].push_back( @@ -1086,7 +1086,7 @@ void CNodeDefManager::removeNode(const std::string &name) } // Erase node content from all groups it belongs to - for (std::map::iterator iter_groups = + for (UNORDERED_MAP::iterator iter_groups = m_group_to_items.begin(); iter_groups != m_group_to_items.end();) { GroupItems &items = iter_groups->second; -- cgit v1.2.3 From 93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 14 Nov 2016 18:09:59 +0400 Subject: Adding particle blend, glow and animation (#4705) --- builtin/common/misc_helpers.lua | 37 +++++++ doc/lua_api.txt | 189 ++++++++++++++++++++++++++++++++- src/client.h | 18 ++++ src/network/clientpackethandler.cpp | 111 ++++++++++++++------ src/nodedef.cpp | 4 +- src/nodedef.h | 11 +- src/particles.cpp | 203 +++++++++++++++++++++++++++++++++--- src/particles.h | 32 +++++- src/script/common/c_content.cpp | 13 +-- src/script/common/c_content.h | 2 +- src/script/common/c_converter.cpp | 22 ++++ src/script/common/c_converter.h | 2 + src/script/lua_api/l_particles.cpp | 166 ++++++++++++++++++++++++++++- src/server.cpp | 44 ++++++-- src/server.h | 27 ++++- 15 files changed, 800 insertions(+), 81 deletions(-) (limited to 'src/nodedef.cpp') diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index c2dc7514d..a495058d9 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -237,6 +237,43 @@ function math.sign(x, tolerance) return 0 end +-------------------------------------------------------------------------------- +-- Video enums and pack function + +-- E_BLEND_FACTOR +minetest.ebf = { + zero = 0, -- src & dest (0, 0, 0, 0) + one = 1, -- src & dest (1, 1, 1, 1) + dst_color = 2, -- src (destR, destG, destB, destA) + one_minus_dst_color = 3, -- src (1-destR, 1-destG, 1-destB, 1-destA) + src_color = 4, -- dest (srcR, srcG, srcB, srcA) + one_minus_src_color = 5, -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) + src_alpha = 6, -- src & dest (srcA, srcA, srcA, srcA) + one_minus_src_alpha = 7, -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) + dst_alpha = 8, -- src & dest (destA, destA, destA, destA) + one_minus_dst_alpha = 9, -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) + src_alpha_saturate = 10,-- src (min(srcA, 1-destA), idem, ...) +} + +-- E_MODULATE_FUNC +minetest.emfn = { + modulate_1x = 1, + modulate_2x = 2, + modulate_4x = 4, +} + +-- E_ALPHA_SOURCE +minetest.eas = { + none = 0, + vertex_color = 1, + texture = 2, +} + +-- BlendFunc = source * sourceFactor + dest * destFactor +function minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource) + return alphaSource * 4096 + modulate * 256 + srcFact * 16 + dstFact +end + -------------------------------------------------------------------------------- function get_last_folder(text,count) local parts = text:split(DIR_DELIM) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 7d552c980..3b3f17634 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -414,6 +414,119 @@ the word "`alpha`", then each texture pixel will contain the RGB of `` and the alpha of `` multiplied by the alpha of the texture pixel. +Particle blend +-------------- +Blend function is defined by integer number. +There is a huge number of acceptable blend modificators. +Colour of a resulting pixel calculated using formulae: + + red = source_red * source_factor + destination_red * destination_factor + +and so on for every channel. + +Here is a some examples: + +Default value: + + material_type_param = 0, + +Use this value to disable blending. Texture will be applied to existing pixels +using alpha channel of it. Its recomended to use 1-bit alpha +in that case. This value will leave z-buffer writeable. + +Additive blend: + + material_type_param = 12641, + +Source = src_alpha, destination = one, alpha source is a texture and +vertex_color, modulate_1x. +Black color is completely transparent, white color is completely opaque. +Alpha channel still used to calculate result color, but not nessesary. +'destination = one' means that resulting color will be calculated using +overwritten pixels values. +For example with color of source (our texture) RGBA = (0,192,255,63) +"blue-cyan", 1/4 opaque. +and already rendered pixel color (40,192,0) "dark lime green" we will get color: + +R = source_red(0) * source_factor(src_alpha=63/255) + + destination_red(40) * destination_factor(one) = + 0 * 63/255 + 40 * 1 = 40 + +G = 192 * 63/255 + 192 * 1 = 239 +B = 255 * 63/255 + 0 * 1 = 63 + +Result: (40,239,63), "green" (a kind of). +Note, if you made a texture with some kind of shape with colour 662211h +it will appear dark red with a single particle, then yellow with a +several of them and white if player looking thru a lot of them. With +this you could made a nice-looking fire. + +Substractive blend: + + material_type_param = 12548, + +Source = zero, destination = src_color, alpha source is a texture and +vertex_color, modulate_1x. +Texture darkness act like an alpha channel. +Black color is completely opaque, white color is completely transparent. +'destination = src_color' means that destination in multiplied by +a source values. 'source = zero' means that source values ignored +(multiplied by 0). + +Invert blend: + + material_type_param = 12597, + +Source = one_minus_dst_color, destination = one_minus_src_alpha, alpha source +is a texture and vertex_color, modulate_1x. +Pixels invert color if source color value is big enough. If not, they just +black. +'destination = one_minus_src_alpha' means, that effect is masked by a +source alpha channel. + +You can design and use your own blend using those enum values and function +'minetest.pack_texture_blend_func'. Returned value of a function is +your 'material_type_param'. + +A values in a brackets is a multiplicators of a red, green, blue +and alpha channels respectively. + +* 'minetest.ebf': global table, containing blend factor enum values. Such as: + * zero = 0 -- src & dest (0, 0, 0, 0) + * one = 1 -- src & dest (1, 1, 1, 1) + * dst_color = 2 -- src (destR, destG, destB, destA) + * one_minus_dst_color = 3 -- src (1-destR, 1-destG, 1-destB, 1-destA) + * src_color = 4 -- dest (srcR, srcG, srcB, srcA) + * one_minus_src_color = 5 -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) + * src_alpha = 6 -- src & dest (srcA, srcA, srcA, srcA) + * one_minus_src_alpha = 7 -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) + * dst_alpha = 8 -- src & dest (destA, destA, destA, destA) + * one_minus_dst_alpha = 9 -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) + * src_alpha_saturate = 10 -- src (min(srcA, 1-destA), idem, ...) + +* 'minetest.emfn': global table, containing modulate enum values. + * Multiply the components of the arguments, and shift the products to the + * left by x bits for brightening. Contain: + * modulate_1x = 1 -- no bit shift + * modulate_2x = 2 -- 1 bits shift + * modulate_4x = 4 -- 2 bits shift + +'modulate_4x' is quite useful when you want to make additive blend stronger +with a lower amount of particles. + +* 'minetest.eas': global table, containing alpha source enum values. Such as: + * none = 0 -- do not use alpha. + * vertex_color = 1 -- use vertex color alpha. + * texture = 2 -- use texture alpha. + +You can use both 'vertex_color' and 'texture' source by using value 3. + +* 'minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource)': return integer + * Pack texture blend funcion variable. Depending from that variable blend + * function will be applied in time of a render poligons with selected material. + * Therefore resulting pixel will be 'source * srcFact + destination * dstFact' + * Use result of this function as 'material_type_param'. + Sounds ------ Only Ogg Vorbis files are supported. @@ -3650,7 +3763,7 @@ Definition tables ### Tile definition * `"image.png"` -* `{name="image.png", animation={Tile Animation definition}}` +* `{name="image.png", animation={Animation definition}}` * `{name="image.png", backface_culling=bool, tileable_vertical=bool, tileable_horizontal=bool}` * backface culling enabled by default for most nodes @@ -3661,8 +3774,50 @@ Definition tables * deprecated, yet still supported field names: * `image` (name) -### Tile animation definition -* `{type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}` +### Animation definition + +#### Node animation, particle and particle spawners +* `{ type="vertical_frames", + aspect_w=16, + -- ^ specify width of a picture in pixels. + aspect_h=16, + -- ^ specify height of a frame in pixels. + length=3.0 + -- ^ specify full loop length. + first_frame = 0, -- <- only for particles, use + min_first_frame = 0, -- <- for particle spawners + max_first_frame = 0, + loop_animation = true, -- <- only for particles and particle spawners + -- specify if animation should start from beginning after last frame. +}` + +#### Particle and particle spawners only +* `{ + type="2d_animation_sheet", -- <- only for particles and particle spawners + vertical_frame_num = 1, + horizontal_frame_num = 1, + -- ^ specify amount of frames in texture. + -- Can be used both for animation or for texture transform + -- together with first_frame variable. + -- A animation texture separated on equal parts of frames, + -- by horizontal and vertical numbers. For example with + -- vertical_frame_num = 4 and horizontal_frame_num = 3 we got + -- 4*3 = 12 frames in total. Animation sequence start from + -- left top frame and go on to the right until reach end of + -- row. Next row also start from left frame. + first_frame = 0, -- <- only for particles, use + min_first_frame = 0, -- <- for particle spawners + max_first_frame = 0, + -- ^ specify first frame to start animation. + frame_length = -1, + -- ^ specify length of a frame in seconds. Negative and zero values + -- disable animation. A sequence with vertical_frame_num = 4 and + -- horizontal_frame_num = 3, first_frame = 4 and frame_length = 0.1 + -- will end in (4*3-4)*0.1 = 0.8 seconds. + loop_animation = true, + -- specify if animation should start from beginning after last frame. +}` + * All settings are optional. Default values is located in this example. ### Node definition (`register_node`) @@ -4117,6 +4272,20 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ optional, if specified spawns particle only on the player's client + material_type_param = 12641, + -- ^ optional, if specified spawns particle with + -- specified material type param and disable z-buffer. + -- Some examples: + -- Default value: 0, + -- Additive blend: 12641, + -- Substractive blend: 12548, + -- Invert blend: 12597, + -- See also "Particle blend". + animation = {Animation definition}, + -- ^ see above. Note, that particle and particle spawners have differences. + glow = 15, + -- ^ optional, specify particle self-luminescence in darkness. + values may vary from 0 (no glow) to 15 (bright glow). } ### `ParticleSpawner` definition (`add_particlespawner`) @@ -4151,6 +4320,20 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ Playername is optional, if specified spawns particle only on the player's client + material_type_param = 12641, + -- ^ optional, if specified spawns particle with specified material type + -- param and disable z-buffer. + -- Some examples: + -- Default value: 0, + -- Additive blend: 12641, + -- Substractive blend: 12548, + -- Invert blend: 12597, + -- See also "Particle blend". + animation = {Animation definition}, + -- ^ see above. Note, that particle and particle spawners have differences. + glow = 15, + -- ^ optional, specify particle self-luminescence in darkness. + values may vary from 0 (no glow) to 15 (bright glow). } ### `HTTPRequest` definition (`HTTPApiTable.fetch_async`, `HTTPApiTable.fetch_async`) diff --git a/src/client.h b/src/client.h index 9f5bda059..c51daf7bc 100644 --- a/src/client.h +++ b/src/client.h @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "particles.h" #include "network/networkpacket.h" +#include "nodedef.h" // AnimationType struct MeshMakeData; class MapBlockMesh; @@ -185,6 +186,14 @@ struct ClientEvent bool collision_removal; bool vertical; std::string *texture; + u32 material_type_param; + AnimationType animation_type; + u16 vertical_frame_num; + u16 horizontal_frame_num; + u16 first_frame; + float frame_length; + bool loop_animation; + u8 glow; } spawn_particle; struct{ u16 amount; @@ -205,6 +214,15 @@ struct ClientEvent bool vertical; std::string *texture; u32 id; + u32 material_type_param; + AnimationType animation_type; + u16 vertical_frame_num; + u16 horizontal_frame_num; + u16 min_first_frame; + u16 max_first_frame; + float frame_length; + bool loop_animation; + u8 glow; } add_particlespawner; struct{ u32 id; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 411982f69..03baf078a 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -896,23 +896,46 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) std::string texture = deSerializeLongString(is); bool vertical = false; bool collision_removal = false; + u32 material_type_param = 0; + AnimationType animation_type = AT_NONE; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u16 first_frame = 0; + float frame_length = -1; + bool loop_animation = true; + u8 glow = 0; try { vertical = readU8(is); collision_removal = readU8(is); + material_type_param = readU32(is); + animation_type = (AnimationType)readU8(is); + vertical_frame_num = readU16(is); + horizontal_frame_num = readU16(is); + first_frame = readU16(is); + frame_length = readF1000(is); + loop_animation = readU8(is); + glow = readU8(is); } catch (...) {} ClientEvent event; - event.type = CE_SPAWN_PARTICLE; - event.spawn_particle.pos = new v3f (pos); - event.spawn_particle.vel = new v3f (vel); - event.spawn_particle.acc = new v3f (acc); - event.spawn_particle.expirationtime = expirationtime; - event.spawn_particle.size = size; - event.spawn_particle.collisiondetection = collisiondetection; - event.spawn_particle.collision_removal = collision_removal; - event.spawn_particle.vertical = vertical; - event.spawn_particle.texture = new std::string(texture); - + event.type = CE_SPAWN_PARTICLE; + event.spawn_particle.pos = new v3f (pos); + event.spawn_particle.vel = new v3f (vel); + event.spawn_particle.acc = new v3f (acc); + event.spawn_particle.expirationtime = expirationtime; + event.spawn_particle.size = size; + event.spawn_particle.collisiondetection = collisiondetection; + event.spawn_particle.collision_removal = collision_removal; + event.spawn_particle.vertical = vertical; + event.spawn_particle.texture = new std::string(texture); + event.spawn_particle.material_type_param = material_type_param; + event.spawn_particle.animation_type = animation_type; + event.spawn_particle.vertical_frame_num = vertical_frame_num; + event.spawn_particle.horizontal_frame_num = horizontal_frame_num; + event.spawn_particle.first_frame = first_frame; + event.spawn_particle.frame_length = frame_length; + event.spawn_particle.loop_animation = loop_animation; + event.spawn_particle.glow = glow; m_client_event_queue.push(event); } @@ -932,6 +955,15 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) float maxsize; bool collisiondetection; u32 id; + u32 material_type_param = 0; + u8 animation_type = (u8)AT_NONE; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u16 min_first_frame = 0; + u16 max_first_frame = 0; + float frame_length = -1; + bool loop_animation = true; + u8 glow = 0; *pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel >> minacc >> maxacc >> minexptime >> maxexptime >> minsize @@ -948,29 +980,46 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) *pkt >> vertical; *pkt >> collision_removal; *pkt >> attached_id; - + *pkt >> material_type_param; + *pkt >> animation_type; + *pkt >> vertical_frame_num; + *pkt >> horizontal_frame_num; + *pkt >> min_first_frame; + *pkt >> max_first_frame; + *pkt >> frame_length; + *pkt >> loop_animation; + *pkt >> glow; } catch (...) {} ClientEvent event; - event.type = CE_ADD_PARTICLESPAWNER; - event.add_particlespawner.amount = amount; - event.add_particlespawner.spawntime = spawntime; - event.add_particlespawner.minpos = new v3f (minpos); - event.add_particlespawner.maxpos = new v3f (maxpos); - event.add_particlespawner.minvel = new v3f (minvel); - event.add_particlespawner.maxvel = new v3f (maxvel); - event.add_particlespawner.minacc = new v3f (minacc); - event.add_particlespawner.maxacc = new v3f (maxacc); - event.add_particlespawner.minexptime = minexptime; - event.add_particlespawner.maxexptime = maxexptime; - event.add_particlespawner.minsize = minsize; - event.add_particlespawner.maxsize = maxsize; - event.add_particlespawner.collisiondetection = collisiondetection; - event.add_particlespawner.collision_removal = collision_removal; - event.add_particlespawner.attached_id = attached_id; - event.add_particlespawner.vertical = vertical; - event.add_particlespawner.texture = new std::string(texture); - event.add_particlespawner.id = id; + event.type = CE_ADD_PARTICLESPAWNER; + event.add_particlespawner.amount = amount; + event.add_particlespawner.spawntime = spawntime; + event.add_particlespawner.minpos = new v3f (minpos); + event.add_particlespawner.maxpos = new v3f (maxpos); + event.add_particlespawner.minvel = new v3f (minvel); + event.add_particlespawner.maxvel = new v3f (maxvel); + event.add_particlespawner.minacc = new v3f (minacc); + event.add_particlespawner.maxacc = new v3f (maxacc); + event.add_particlespawner.minexptime = minexptime; + event.add_particlespawner.maxexptime = maxexptime; + event.add_particlespawner.minsize = minsize; + event.add_particlespawner.maxsize = maxsize; + event.add_particlespawner.collisiondetection = collisiondetection; + event.add_particlespawner.collision_removal = collision_removal; + event.add_particlespawner.attached_id = attached_id; + event.add_particlespawner.vertical = vertical; + event.add_particlespawner.texture = new std::string(texture); + event.add_particlespawner.id = id; + event.add_particlespawner.material_type_param = material_type_param; + event.add_particlespawner.animation_type = (AnimationType)animation_type; + event.add_particlespawner.vertical_frame_num = vertical_frame_num; + event.add_particlespawner.horizontal_frame_num = horizontal_frame_num; + event.add_particlespawner.min_first_frame = min_first_frame; + event.add_particlespawner.max_first_frame = max_first_frame; + event.add_particlespawner.frame_length = frame_length; + event.add_particlespawner.loop_animation = loop_animation; + event.add_particlespawner.glow = glow; m_client_event_queue.push(event); } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 39ea1a60e..c690e6720 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -211,7 +211,7 @@ void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, con { int version = readU8(is); name = deSerializeString(is); - animation.type = (TileAnimationType)readU8(is); + animation.type = (AnimationType)readU8(is); animation.aspect_w = readU16(is); animation.aspect_h = readU16(is); animation.length = readF1000(is); @@ -531,7 +531,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, tile->material_flags = 0; if (backface_culling) tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; - if (tiledef->animation.type == TAT_VERTICAL_FRAMES) + if (tiledef->animation.type == AT_VERTICAL_FRAMES) tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; if (tiledef->tileable_horizontal) tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; diff --git a/src/nodedef.h b/src/nodedef.h index 80396f992..f47517c4a 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -161,9 +161,10 @@ enum NodeDrawType /* Stand-alone definition of a TileSpec (basically a server-side TileSpec) */ -enum TileAnimationType{ - TAT_NONE=0, - TAT_VERTICAL_FRAMES=1, +enum AnimationType{ + AT_NONE = 0, + AT_VERTICAL_FRAMES = 1, + AT_2D_ANIMATION_SHEET = 2, }; struct TileDef { @@ -172,7 +173,7 @@ struct TileDef bool tileable_horizontal; bool tileable_vertical; struct{ - enum TileAnimationType type; + enum AnimationType type; int aspect_w; // width for aspect ratio int aspect_h; // height for aspect ratio float length; // seconds @@ -184,7 +185,7 @@ struct TileDef backface_culling = true; tileable_horizontal = true; tileable_vertical = true; - animation.type = TAT_NONE; + animation.type = AT_NONE; animation.aspect_w = 1; animation.aspect_h = 1; animation.length = 1.0; diff --git a/src/particles.cpp b/src/particles.cpp index f20fb4083..538487028 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -43,6 +43,22 @@ v3f random_v3f(v3f min, v3f max) rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z); } +u32 check_material_type_param(u32 material_type_param) +{ + u32 alphaSource = (material_type_param & 0x0000F000) >> 12; + u32 modulo = (material_type_param & 0x00000F00) >> 8; + u32 srcFact = (material_type_param & 0x000000F0) >> 4; + u32 dstFact = material_type_param & 0x0000000F; + if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { + return material_type_param; + } else { + errorstream << "Server send incorrect "; + errorstream << "material_type_param value for particle."; + errorstream << std::endl; + return 0; + } +} + Particle::Particle( IGameDef *gamedef, scene::ISceneManager* smgr, @@ -58,7 +74,14 @@ Particle::Particle( bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize + v2f texsize, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 first_frame, + float frame_length, + bool loop_animation, + u8 glow ): scene::ISceneNode(smgr->getRootSceneNode(), smgr) { @@ -71,11 +94,26 @@ Particle::Particle( m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, true); - m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + if (material_type_param != 0) { + m_material.MaterialType = video::EMT_ONETEXTURE_BLEND; + m_material.MaterialTypeParam = irr::core::FR(material_type_param); + // We must disable z-buffer if we want to avoid transparent pixels + // to overlap pixels with lower z-value. + m_material.setFlag(video::EMF_ZWRITE_ENABLE, false); + } else { + m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + } m_material.setTexture(0, texture); + m_texpos = texpos; m_texsize = texsize; - + m_vertical_frame_num = vertical_frame_num; + m_horizontal_frame_num = horizontal_frame_num; + m_first_frame = first_frame; + m_frame_length = frame_length; + m_loop_animation = loop_animation; + m_texsize.Y /= m_vertical_frame_num; + m_texsize.X /= m_horizontal_frame_num; // Particle related m_pos = pos; @@ -88,6 +126,7 @@ Particle::Particle( m_collisiondetection = collisiondetection; m_collision_removal = collision_removal; m_vertical = vertical; + m_glow = glow; // Irrlicht stuff m_collisionbox = aabb3f @@ -170,16 +209,29 @@ void Particle::updateLight() else light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0); - m_light = decode_light(light); + m_light = decode_light(light + m_glow); } void Particle::updateVertices() { video::SColor c(255, m_light, m_light, m_light); - f32 tx0 = m_texpos.X; - f32 tx1 = m_texpos.X + m_texsize.X; - f32 ty0 = m_texpos.Y; - f32 ty1 = m_texpos.Y + m_texsize.Y; + u16 frame = m_first_frame; + if (m_frame_length > 0) { + if (m_loop_animation) + frame = m_first_frame + (u32)(m_time / m_frame_length) + % (m_vertical_frame_num * + m_horizontal_frame_num - m_first_frame); + else if (m_time >= + (m_vertical_frame_num * m_horizontal_frame_num + - m_first_frame) * m_frame_length) + frame = m_vertical_frame_num * m_horizontal_frame_num - 1; + else + frame = m_first_frame + (u16)(m_time / m_frame_length); + } + f32 tx0 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num); + f32 tx1 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num + 1); + f32 ty0 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num); + f32 ty1 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num + 1); m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0, c, tx0, ty1); @@ -214,7 +266,16 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, bool vertical, - video::ITexture *texture, u32 id, ParticleManager *p_manager) : + video::ITexture *texture, u32 id, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 min_first_frame, + u16 max_first_frame, + float frame_length, + bool loop_animation, + u8 glow, + ParticleManager *p_manager) : m_particlemanager(p_manager) { m_gamedef = gamedef; @@ -238,6 +299,14 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, m_vertical = vertical; m_texture = texture; m_time = 0; + m_vertical_frame_num = vertical_frame_num; + m_horizontal_frame_num = horizontal_frame_num; + m_min_first_frame = min_first_frame; + m_max_first_frame = max_first_frame; + m_frame_length = frame_length; + m_loop_animation = loop_animation; + m_material_type_param = material_type_param; + m_glow = glow; for (u16 i = 0; i<=m_amount; i++) { @@ -251,7 +320,6 @@ ParticleSpawner::~ParticleSpawner() {} void ParticleSpawner::step(float dtime, ClientEnvironment* env) { m_time += dtime; - bool unloaded = false; v3f attached_offset = v3f(0,0,0); if (m_attached_id != 0) { @@ -285,7 +353,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - + u16 first_frame = m_min_first_frame + + rand() % + (m_max_first_frame - + m_min_first_frame + 1); Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -301,7 +372,14 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0)); + v2f(1.0, 1.0), + m_material_type_param, + m_vertical_frame_num, + m_horizontal_frame_num, + first_frame, + m_frame_length, + m_loop_animation, + m_glow); m_particlemanager->addParticle(toadd); } i = m_spawntimes.erase(i); @@ -331,7 +409,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - + u16 first_frame = m_min_first_frame + + rand() % + (m_max_first_frame - + m_min_first_frame + 1); Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -347,7 +428,14 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0)); + v2f(1.0, 1.0), + m_material_type_param, + m_vertical_frame_num, + m_horizontal_frame_num, + first_frame, + m_frame_length, + m_loop_animation, + m_glow); m_particlemanager->addParticle(toadd); } } @@ -459,6 +547,39 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture)); + float frame_length = -1; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u32 material_type_param = + check_material_type_param(event->add_particlespawner.material_type_param); + + switch (event->add_particlespawner.animation_type) { + case AT_NONE: + break; + case AT_VERTICAL_FRAMES: { + v2u32 size = texture->getOriginalSize(); + int frame_height = (float)size.X / + (float)event->add_particlespawner.vertical_frame_num * + (float)event->add_particlespawner.horizontal_frame_num; + vertical_frame_num = size.Y / frame_height; + frame_length = + event->add_particlespawner.frame_length / + vertical_frame_num; + break; + } + case AT_2D_ANIMATION_SHEET: { + vertical_frame_num = + event->add_particlespawner.vertical_frame_num; + horizontal_frame_num = + event->add_particlespawner.horizontal_frame_num; + frame_length = + event->add_particlespawner.frame_length; + break; + } + default: + break; + } + ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player, event->add_particlespawner.amount, event->add_particlespawner.spawntime, @@ -478,6 +599,14 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->add_particlespawner.vertical, texture, event->add_particlespawner.id, + material_type_param, + vertical_frame_num, + horizontal_frame_num, + event->add_particlespawner.min_first_frame, + event->add_particlespawner.max_first_frame, + frame_length, + event->add_particlespawner.loop_animation, + event->add_particlespawner.glow, this); /* delete allocated content of event */ @@ -502,6 +631,39 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture)); + float frame_length = -1; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u32 material_type_param = + check_material_type_param(event->spawn_particle.material_type_param); + + switch (event->spawn_particle.animation_type) { + case AT_NONE: + break; + case AT_VERTICAL_FRAMES: { + v2u32 size = texture->getOriginalSize(); + int frame_height = (float)size.X / + (float)event->spawn_particle.vertical_frame_num * + (float)event->spawn_particle.horizontal_frame_num; + vertical_frame_num = size.Y / frame_height; + frame_length = + event->spawn_particle.frame_length / + vertical_frame_num; + break; + } + case AT_2D_ANIMATION_SHEET: { + vertical_frame_num = + event->spawn_particle.vertical_frame_num; + horizontal_frame_num = + event->spawn_particle.horizontal_frame_num; + frame_length = + event->spawn_particle.frame_length; + break; + } + default: + break; + } + Particle* toadd = new Particle(gamedef, smgr, player, m_env, *event->spawn_particle.pos, *event->spawn_particle.vel, @@ -513,13 +675,21 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->spawn_particle.vertical, texture, v2f(0.0, 0.0), - v2f(1.0, 1.0)); + v2f(1.0, 1.0), + material_type_param, + vertical_frame_num, + horizontal_frame_num, + event->spawn_particle.first_frame, + frame_length, + event->spawn_particle.loop_animation, + event->spawn_particle.glow); addParticle(toadd); delete event->spawn_particle.pos; delete event->spawn_particle.vel; delete event->spawn_particle.acc; + delete event->spawn_particle.texture; break; } @@ -588,7 +758,8 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s false, texture, texpos, - texsize); + texsize, + 0, 1, 1, 0, -1, true, 0); addParticle(toadd); } diff --git a/src/particles.h b/src/particles.h index eb8c6665d..6d8c6139f 100644 --- a/src/particles.h +++ b/src/particles.h @@ -50,7 +50,14 @@ class Particle : public scene::ISceneNode bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize + v2f texsize, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 first_frame, + float frame_length, + bool loop_animation, + u8 glow ); ~Particle(); @@ -102,6 +109,12 @@ private: bool m_collision_removal; bool m_vertical; v3s16 m_camera_offset; + u16 m_vertical_frame_num; + u16 m_horizontal_frame_num; + u16 m_first_frame; + float m_frame_length; + bool m_loop_animation; + u8 m_glow; }; class ParticleSpawner @@ -123,8 +136,15 @@ class ParticleSpawner bool vertical, video::ITexture *texture, u32 id, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 min_first_frame, + u16 max_first_frame, + float frame_length, + bool loop_animation, + u8 glow, ParticleManager* p_manager); - ~ParticleSpawner(); void step(float dtime, ClientEnvironment *env); @@ -156,6 +176,14 @@ class ParticleSpawner bool m_collision_removal; bool m_vertical; u16 m_attached_id; + u32 m_material_type_param; + u16 m_vertical_frame_num; + u16 m_horizontal_frame_num; + u16 m_min_first_frame; + u16 m_max_first_frame; + float m_frame_length; + bool m_loop_animation; + u8 m_glow; }; /** diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index f20a65903..d4a25b68b 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -35,10 +35,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "noise.h" #include -struct EnumString es_TileAnimationType[] = +struct EnumString es_AnimationType[] = { - {TAT_NONE, "none"}, - {TAT_VERTICAL_FRAMES, "vertical_frames"}, + {AT_NONE, "none"}, + {AT_VERTICAL_FRAMES, "vertical_frames"}, + {AT_2D_ANIMATION_SHEET, "2d_animation_sheet"}, {0, NULL}, }; @@ -335,9 +336,9 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} - tiledef.animation.type = (TileAnimationType) - getenumfield(L, -1, "type", es_TileAnimationType, - TAT_NONE); + tiledef.animation.type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 2a2228b6d..32fdb4f04 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -159,6 +159,6 @@ bool push_json_value (lua_State *L, void read_json_value (lua_State *L, Json::Value &root, int index, u8 recursion = 0); -extern struct EnumString es_TileAnimationType[]; +extern struct EnumString es_AnimationType[]; #endif /* C_CONTENT_H_ */ diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index f36298915..cfb5e26db 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -513,6 +513,28 @@ int getintfield_default(lua_State *L, int table, return result; } +int check_material_type_param(lua_State *L, int table, + const char *fieldname, int default_) +{ + int material_type_param = + getintfield_default(L, table, fieldname, default_); + u32 alphaSource = (material_type_param & 0x0000F000) >> 12; + u32 modulo = (material_type_param & 0x00000F00) >> 8; + u32 srcFact = (material_type_param & 0x000000F0) >> 4; + u32 dstFact = material_type_param & 0x0000000F; + if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { + return material_type_param; + } else { + std::ostringstream error_text; + error_text << "Incorrect material_type_param value "; + error_text << "for particle or particle spawner."; + error_text << std::endl; + throw LuaError(error_text.str()); + return 0; + } +} + + float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_) { diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index a5fbee765..71ac735c1 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -45,6 +45,8 @@ float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_); int getintfield_default (lua_State *L, int table, const char *fieldname, int default_); +int check_material_type_param(lua_State *L, int table, + const char *fieldname, int default_); bool getstringfield(lua_State *L, int table, const char *fieldname, std::string &result); diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index 667ac7272..b0a57ce6d 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_object.h" #include "lua_api/l_internal.h" #include "common/c_converter.h" +#include "common/c_content.h" #include "server.h" #include "particles.h" @@ -34,6 +35,9 @@ with this program; if not, write to the Free Software Foundation, Inc., // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" +// material_type_param = num +// animation = animation definition +// glow = indexed color or color string int ModApiParticles::l_add_particle(lua_State *L) { MAP_LOCK_REQUIRED; @@ -44,13 +48,24 @@ int ModApiParticles::l_add_particle(lua_State *L) float expirationtime, size; expirationtime = size = 1; + float frame_or_loop_length = -1; + + AnimationType animation_type = AT_NONE; + + u16 vertical_frame_num_or_aspect = 1; + u16 horizontal_frame_num_or_aspect = 1; + u16 first_frame = 0; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; + bool loop_animation = true; std::string texture = ""; std::string playername = ""; + u32 material_type_param = 0; + u8 glow = 0; + if (lua_gettop(L) > 1) // deprecated { log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition"); @@ -94,8 +109,61 @@ int ModApiParticles::l_add_particle(lua_State *L) acc = lua_istable(L, -1) ? check_v3f(L, -1) : acc; lua_pop(L, 1); - expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); + expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); size = getfloatfield_default(L, 1, "size", 1); + + lua_getfield(L, 1, "animation"); + if (lua_istable(L, -1)) { + animation_type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); + } + switch (animation_type) { + case AT_NONE: + break; + case AT_2D_ANIMATION_SHEET: + frame_or_loop_length = + getfloatfield_default(L, -1, "frame_length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "vertical_frame_num", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "horizontal_frame_num", 1); + first_frame = + getintfield_default(L, -1, "first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + case AT_VERTICAL_FRAMES: + frame_or_loop_length = + getfloatfield_default(L, -1, "length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_w", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_h", 1); + first_frame = + getintfield_default(L, -1, "first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + default: + break; + } + lua_pop(L, 1); + + if (animation_type == AT_2D_ANIMATION_SHEET && + first_frame >= vertical_frame_num_or_aspect * + horizontal_frame_num_or_aspect) { + std::ostringstream error_text; + error_text << "first_frame should be lower, than " + << "vertical_frame_num * horizontal_frame_num. " + << "Got first_frame=" << first_frame + << ", vertical_frame_num=" + << vertical_frame_num_or_aspect + << " and horizontal_frame_num=" + << horizontal_frame_num_or_aspect << std::endl; + throw LuaError(error_text.str()); + } + collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -103,9 +171,16 @@ int ModApiParticles::l_add_particle(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); + material_type_param = check_material_type_param(L, 1, "material_type_param", 0); + glow = getintfield_default (L, 1, "glow", 0); } - getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, - collisiondetection, collision_removal, vertical, texture); + getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, + size, collisiondetection, collision_removal, vertical, + texture, material_type_param, + animation_type, + vertical_frame_num_or_aspect, + horizontal_frame_num_or_aspect, + first_frame, frame_or_loop_length, loop_animation, glow); return 1; } @@ -127,21 +202,33 @@ int ModApiParticles::l_add_particle(lua_State *L) // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" +// material_type_param = num +// animation = animation definition +// glow = indexed color or color string int ModApiParticles::l_add_particlespawner(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters u16 amount = 1; + u16 vertical_frame_num_or_aspect = 1; + u16 horizontal_frame_num_or_aspect = 1; + u16 min_first_frame = 0; + u16 max_first_frame = 0; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; + AnimationType animation_type = AT_NONE; + float frame_or_loop_length = -1; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; + bool loop_animation = true; ServerActiveObject *attached = NULL; std::string texture = ""; std::string playername = ""; + u32 material_type_param = 0; + u8 glow = 0; if (lua_gettop(L) > 1) //deprecated { @@ -196,6 +283,65 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); + + + lua_getfield(L, 1, "animation"); + if (lua_istable(L, -1)) { + animation_type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); + } + switch (animation_type) { + case AT_NONE: + break; + case AT_2D_ANIMATION_SHEET: + frame_or_loop_length = + getfloatfield_default(L, -1, "frame_length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "vertical_frame_num", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "horizontal_frame_num", 1); + min_first_frame = + getintfield_default(L, -1, "min_first_frame", 0); + max_first_frame = + getintfield_default(L, -1, "max_first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + case AT_VERTICAL_FRAMES: + frame_or_loop_length = + getfloatfield_default(L, -1, "length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_w", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_h", 1); + min_first_frame = + getintfield_default(L, -1, "min_first_frame", 0); + max_first_frame = + getintfield_default(L, -1, "max_first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + default: + break; + } + lua_pop(L, 1); + + if (animation_type == AT_2D_ANIMATION_SHEET && + max_first_frame >= vertical_frame_num_or_aspect * + horizontal_frame_num_or_aspect) { + std::ostringstream error_text; + error_text << "max_first_frame should be lower, than " + << "vertical_frame_num * horizontal_frame_num. " + << "Got max_first_frame=" + << max_first_frame + << ", vertical_frame_num=" + << vertical_frame_num_or_aspect + << " and horizontal_frame_num=" + << horizontal_frame_num_or_aspect << std::endl; + throw LuaError(error_text.str()); + } + collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -211,6 +357,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); + material_type_param = check_material_type_param(L, 1, "material_type_param", 0); + glow = getintfield_default(L, 1, "glow", 0); } u32 id = getServer(L)->addParticleSpawner(amount, time, @@ -223,9 +371,17 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) collision_removal, attached, vertical, - texture, playername); + texture, + playername, + material_type_param, + animation_type, + vertical_frame_num_or_aspect, + horizontal_frame_num_or_aspect, + min_first_frame, max_first_frame, + frame_or_loop_length, + loop_animation, + glow); lua_pushnumber(L, id); - return 1; } diff --git a/src/server.cpp b/src/server.cpp index 48331e4f8..cef57be88 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1658,7 +1658,11 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture) + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow) { DSTACK(FUNCTION_NAME); @@ -1670,6 +1674,12 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat pkt << vertical; pkt << collision_removal; + pkt << material_type_param + << (u8)animation_type + << vertical_frame_num + << horizontal_frame_num << first_frame + << frame_length << loop_animation << glow; + if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -1682,7 +1692,10 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, - u16 attached_id, bool vertical, const std::string &texture, u32 id) + u16 attached_id, bool vertical, const std::string &texture, u32 id, + u32 material_type_param, AnimationType animation_type, u16 vertical_frame_num, u16 horizontal_frame_num, + u16 min_first_frame, u16 max_first_frame, float frame_length, + bool loop_animation, u8 glow) { DSTACK(FUNCTION_NAME); @@ -1698,6 +1711,12 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3 pkt << collision_removal; pkt << attached_id; + pkt << material_type_param + << (u8)animation_type + << vertical_frame_num << horizontal_frame_num + << min_first_frame << max_first_frame + << frame_length << loop_animation << glow; + if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -3147,7 +3166,11 @@ void Server::spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture) + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3163,7 +3186,11 @@ void Server::spawnParticle(const std::string &playername, v3f pos, SendSpawnParticle(peer_id, pos, velocity, acceleration, expirationtime, size, collisiondetection, - collision_removal, vertical, texture); + collision_removal, vertical, texture, + material_type_param, animation_type, + vertical_frame_num, horizontal_frame_num, + first_frame, frame_length, loop_animation, + glow); } u32 Server::addParticleSpawner(u16 amount, float spawntime, @@ -3171,7 +3198,9 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername) + const std::string &playername, u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 min_first_frame, u16 max_first_frame, + float frame_length, bool loop_animation, u8 glow) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3197,7 +3226,10 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, collision_removal, attached_id, vertical, - texture, id); + texture, id, material_type_param, animation_type, + vertical_frame_num, horizontal_frame_num, + min_first_frame, max_first_frame, frame_length, loop_animation, + glow); return id; } diff --git a/src/server.h b/src/server.h index 9e844e36c..9a8d22b2e 100644 --- a/src/server.h +++ b/src/server.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "gamedef.h" #include "serialization.h" // For SER_FMT_VER_INVALID +#include "nodedef.h" // AnimationType #include "mods.h" #include "inventorymanager.h" #include "subgame.h" @@ -254,7 +255,11 @@ public: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture); + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow); u32 addParticleSpawner(u16 amount, float spawntime, v3f minpos, v3f maxpos, @@ -265,7 +270,12 @@ public: bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername); + const std::string &playername, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, + u16 min_first_frame, u16 max_first_frame, + float frame_length, bool loop_animation, + u8 glow); void deleteParticleSpawner(const std::string &playername, u32 id); @@ -441,7 +451,12 @@ private: float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, - bool vertical, const std::string &texture, u32 id); + bool vertical, const std::string &texture, u32 id, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, + u16 min_first_frame, u16 max_first_frame, + float frame_length, bool loop_animation, + u8 glow); void SendDeleteParticleSpawner(u16 peer_id, u32 id); @@ -450,7 +465,11 @@ private: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture); + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow); u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas); void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true); -- cgit v1.2.3 From 5fd1ef9b589419e2464f5599ea47a2f28f4d7b7b Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 14 Nov 2016 15:28:06 +0100 Subject: Revert "Adding particle blend, glow and animation (#4705)" This reverts commit 93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef. --- builtin/common/misc_helpers.lua | 37 ------- doc/lua_api.txt | 189 +-------------------------------- src/client.h | 18 ---- src/network/clientpackethandler.cpp | 111 ++++++-------------- src/nodedef.cpp | 4 +- src/nodedef.h | 11 +- src/particles.cpp | 203 +++--------------------------------- src/particles.h | 32 +----- src/script/common/c_content.cpp | 13 ++- src/script/common/c_content.h | 2 +- src/script/common/c_converter.cpp | 22 ---- src/script/common/c_converter.h | 2 - src/script/lua_api/l_particles.cpp | 166 +---------------------------- src/server.cpp | 44 ++------ src/server.h | 27 +---- 15 files changed, 81 insertions(+), 800 deletions(-) (limited to 'src/nodedef.cpp') diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index a495058d9..c2dc7514d 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -237,43 +237,6 @@ function math.sign(x, tolerance) return 0 end --------------------------------------------------------------------------------- --- Video enums and pack function - --- E_BLEND_FACTOR -minetest.ebf = { - zero = 0, -- src & dest (0, 0, 0, 0) - one = 1, -- src & dest (1, 1, 1, 1) - dst_color = 2, -- src (destR, destG, destB, destA) - one_minus_dst_color = 3, -- src (1-destR, 1-destG, 1-destB, 1-destA) - src_color = 4, -- dest (srcR, srcG, srcB, srcA) - one_minus_src_color = 5, -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) - src_alpha = 6, -- src & dest (srcA, srcA, srcA, srcA) - one_minus_src_alpha = 7, -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) - dst_alpha = 8, -- src & dest (destA, destA, destA, destA) - one_minus_dst_alpha = 9, -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) - src_alpha_saturate = 10,-- src (min(srcA, 1-destA), idem, ...) -} - --- E_MODULATE_FUNC -minetest.emfn = { - modulate_1x = 1, - modulate_2x = 2, - modulate_4x = 4, -} - --- E_ALPHA_SOURCE -minetest.eas = { - none = 0, - vertex_color = 1, - texture = 2, -} - --- BlendFunc = source * sourceFactor + dest * destFactor -function minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource) - return alphaSource * 4096 + modulate * 256 + srcFact * 16 + dstFact -end - -------------------------------------------------------------------------------- function get_last_folder(text,count) local parts = text:split(DIR_DELIM) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 3b3f17634..7d552c980 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -414,119 +414,6 @@ the word "`alpha`", then each texture pixel will contain the RGB of `` and the alpha of `` multiplied by the alpha of the texture pixel. -Particle blend --------------- -Blend function is defined by integer number. -There is a huge number of acceptable blend modificators. -Colour of a resulting pixel calculated using formulae: - - red = source_red * source_factor + destination_red * destination_factor - -and so on for every channel. - -Here is a some examples: - -Default value: - - material_type_param = 0, - -Use this value to disable blending. Texture will be applied to existing pixels -using alpha channel of it. Its recomended to use 1-bit alpha -in that case. This value will leave z-buffer writeable. - -Additive blend: - - material_type_param = 12641, - -Source = src_alpha, destination = one, alpha source is a texture and -vertex_color, modulate_1x. -Black color is completely transparent, white color is completely opaque. -Alpha channel still used to calculate result color, but not nessesary. -'destination = one' means that resulting color will be calculated using -overwritten pixels values. -For example with color of source (our texture) RGBA = (0,192,255,63) -"blue-cyan", 1/4 opaque. -and already rendered pixel color (40,192,0) "dark lime green" we will get color: - -R = source_red(0) * source_factor(src_alpha=63/255) + - destination_red(40) * destination_factor(one) = - 0 * 63/255 + 40 * 1 = 40 - -G = 192 * 63/255 + 192 * 1 = 239 -B = 255 * 63/255 + 0 * 1 = 63 - -Result: (40,239,63), "green" (a kind of). -Note, if you made a texture with some kind of shape with colour 662211h -it will appear dark red with a single particle, then yellow with a -several of them and white if player looking thru a lot of them. With -this you could made a nice-looking fire. - -Substractive blend: - - material_type_param = 12548, - -Source = zero, destination = src_color, alpha source is a texture and -vertex_color, modulate_1x. -Texture darkness act like an alpha channel. -Black color is completely opaque, white color is completely transparent. -'destination = src_color' means that destination in multiplied by -a source values. 'source = zero' means that source values ignored -(multiplied by 0). - -Invert blend: - - material_type_param = 12597, - -Source = one_minus_dst_color, destination = one_minus_src_alpha, alpha source -is a texture and vertex_color, modulate_1x. -Pixels invert color if source color value is big enough. If not, they just -black. -'destination = one_minus_src_alpha' means, that effect is masked by a -source alpha channel. - -You can design and use your own blend using those enum values and function -'minetest.pack_texture_blend_func'. Returned value of a function is -your 'material_type_param'. - -A values in a brackets is a multiplicators of a red, green, blue -and alpha channels respectively. - -* 'minetest.ebf': global table, containing blend factor enum values. Such as: - * zero = 0 -- src & dest (0, 0, 0, 0) - * one = 1 -- src & dest (1, 1, 1, 1) - * dst_color = 2 -- src (destR, destG, destB, destA) - * one_minus_dst_color = 3 -- src (1-destR, 1-destG, 1-destB, 1-destA) - * src_color = 4 -- dest (srcR, srcG, srcB, srcA) - * one_minus_src_color = 5 -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) - * src_alpha = 6 -- src & dest (srcA, srcA, srcA, srcA) - * one_minus_src_alpha = 7 -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) - * dst_alpha = 8 -- src & dest (destA, destA, destA, destA) - * one_minus_dst_alpha = 9 -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) - * src_alpha_saturate = 10 -- src (min(srcA, 1-destA), idem, ...) - -* 'minetest.emfn': global table, containing modulate enum values. - * Multiply the components of the arguments, and shift the products to the - * left by x bits for brightening. Contain: - * modulate_1x = 1 -- no bit shift - * modulate_2x = 2 -- 1 bits shift - * modulate_4x = 4 -- 2 bits shift - -'modulate_4x' is quite useful when you want to make additive blend stronger -with a lower amount of particles. - -* 'minetest.eas': global table, containing alpha source enum values. Such as: - * none = 0 -- do not use alpha. - * vertex_color = 1 -- use vertex color alpha. - * texture = 2 -- use texture alpha. - -You can use both 'vertex_color' and 'texture' source by using value 3. - -* 'minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource)': return integer - * Pack texture blend funcion variable. Depending from that variable blend - * function will be applied in time of a render poligons with selected material. - * Therefore resulting pixel will be 'source * srcFact + destination * dstFact' - * Use result of this function as 'material_type_param'. - Sounds ------ Only Ogg Vorbis files are supported. @@ -3763,7 +3650,7 @@ Definition tables ### Tile definition * `"image.png"` -* `{name="image.png", animation={Animation definition}}` +* `{name="image.png", animation={Tile Animation definition}}` * `{name="image.png", backface_culling=bool, tileable_vertical=bool, tileable_horizontal=bool}` * backface culling enabled by default for most nodes @@ -3774,50 +3661,8 @@ Definition tables * deprecated, yet still supported field names: * `image` (name) -### Animation definition - -#### Node animation, particle and particle spawners -* `{ type="vertical_frames", - aspect_w=16, - -- ^ specify width of a picture in pixels. - aspect_h=16, - -- ^ specify height of a frame in pixels. - length=3.0 - -- ^ specify full loop length. - first_frame = 0, -- <- only for particles, use - min_first_frame = 0, -- <- for particle spawners - max_first_frame = 0, - loop_animation = true, -- <- only for particles and particle spawners - -- specify if animation should start from beginning after last frame. -}` - -#### Particle and particle spawners only -* `{ - type="2d_animation_sheet", -- <- only for particles and particle spawners - vertical_frame_num = 1, - horizontal_frame_num = 1, - -- ^ specify amount of frames in texture. - -- Can be used both for animation or for texture transform - -- together with first_frame variable. - -- A animation texture separated on equal parts of frames, - -- by horizontal and vertical numbers. For example with - -- vertical_frame_num = 4 and horizontal_frame_num = 3 we got - -- 4*3 = 12 frames in total. Animation sequence start from - -- left top frame and go on to the right until reach end of - -- row. Next row also start from left frame. - first_frame = 0, -- <- only for particles, use - min_first_frame = 0, -- <- for particle spawners - max_first_frame = 0, - -- ^ specify first frame to start animation. - frame_length = -1, - -- ^ specify length of a frame in seconds. Negative and zero values - -- disable animation. A sequence with vertical_frame_num = 4 and - -- horizontal_frame_num = 3, first_frame = 4 and frame_length = 0.1 - -- will end in (4*3-4)*0.1 = 0.8 seconds. - loop_animation = true, - -- specify if animation should start from beginning after last frame. -}` - * All settings are optional. Default values is located in this example. +### Tile animation definition +* `{type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}` ### Node definition (`register_node`) @@ -4272,20 +4117,6 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ optional, if specified spawns particle only on the player's client - material_type_param = 12641, - -- ^ optional, if specified spawns particle with - -- specified material type param and disable z-buffer. - -- Some examples: - -- Default value: 0, - -- Additive blend: 12641, - -- Substractive blend: 12548, - -- Invert blend: 12597, - -- See also "Particle blend". - animation = {Animation definition}, - -- ^ see above. Note, that particle and particle spawners have differences. - glow = 15, - -- ^ optional, specify particle self-luminescence in darkness. - values may vary from 0 (no glow) to 15 (bright glow). } ### `ParticleSpawner` definition (`add_particlespawner`) @@ -4320,20 +4151,6 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ Playername is optional, if specified spawns particle only on the player's client - material_type_param = 12641, - -- ^ optional, if specified spawns particle with specified material type - -- param and disable z-buffer. - -- Some examples: - -- Default value: 0, - -- Additive blend: 12641, - -- Substractive blend: 12548, - -- Invert blend: 12597, - -- See also "Particle blend". - animation = {Animation definition}, - -- ^ see above. Note, that particle and particle spawners have differences. - glow = 15, - -- ^ optional, specify particle self-luminescence in darkness. - values may vary from 0 (no glow) to 15 (bright glow). } ### `HTTPRequest` definition (`HTTPApiTable.fetch_async`, `HTTPApiTable.fetch_async`) diff --git a/src/client.h b/src/client.h index c51daf7bc..9f5bda059 100644 --- a/src/client.h +++ b/src/client.h @@ -35,7 +35,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "particles.h" #include "network/networkpacket.h" -#include "nodedef.h" // AnimationType struct MeshMakeData; class MapBlockMesh; @@ -186,14 +185,6 @@ struct ClientEvent bool collision_removal; bool vertical; std::string *texture; - u32 material_type_param; - AnimationType animation_type; - u16 vertical_frame_num; - u16 horizontal_frame_num; - u16 first_frame; - float frame_length; - bool loop_animation; - u8 glow; } spawn_particle; struct{ u16 amount; @@ -214,15 +205,6 @@ struct ClientEvent bool vertical; std::string *texture; u32 id; - u32 material_type_param; - AnimationType animation_type; - u16 vertical_frame_num; - u16 horizontal_frame_num; - u16 min_first_frame; - u16 max_first_frame; - float frame_length; - bool loop_animation; - u8 glow; } add_particlespawner; struct{ u32 id; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 03baf078a..411982f69 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -896,46 +896,23 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) std::string texture = deSerializeLongString(is); bool vertical = false; bool collision_removal = false; - u32 material_type_param = 0; - AnimationType animation_type = AT_NONE; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u16 first_frame = 0; - float frame_length = -1; - bool loop_animation = true; - u8 glow = 0; try { vertical = readU8(is); collision_removal = readU8(is); - material_type_param = readU32(is); - animation_type = (AnimationType)readU8(is); - vertical_frame_num = readU16(is); - horizontal_frame_num = readU16(is); - first_frame = readU16(is); - frame_length = readF1000(is); - loop_animation = readU8(is); - glow = readU8(is); } catch (...) {} ClientEvent event; - event.type = CE_SPAWN_PARTICLE; - event.spawn_particle.pos = new v3f (pos); - event.spawn_particle.vel = new v3f (vel); - event.spawn_particle.acc = new v3f (acc); - event.spawn_particle.expirationtime = expirationtime; - event.spawn_particle.size = size; - event.spawn_particle.collisiondetection = collisiondetection; - event.spawn_particle.collision_removal = collision_removal; - event.spawn_particle.vertical = vertical; - event.spawn_particle.texture = new std::string(texture); - event.spawn_particle.material_type_param = material_type_param; - event.spawn_particle.animation_type = animation_type; - event.spawn_particle.vertical_frame_num = vertical_frame_num; - event.spawn_particle.horizontal_frame_num = horizontal_frame_num; - event.spawn_particle.first_frame = first_frame; - event.spawn_particle.frame_length = frame_length; - event.spawn_particle.loop_animation = loop_animation; - event.spawn_particle.glow = glow; + event.type = CE_SPAWN_PARTICLE; + event.spawn_particle.pos = new v3f (pos); + event.spawn_particle.vel = new v3f (vel); + event.spawn_particle.acc = new v3f (acc); + event.spawn_particle.expirationtime = expirationtime; + event.spawn_particle.size = size; + event.spawn_particle.collisiondetection = collisiondetection; + event.spawn_particle.collision_removal = collision_removal; + event.spawn_particle.vertical = vertical; + event.spawn_particle.texture = new std::string(texture); + m_client_event_queue.push(event); } @@ -955,15 +932,6 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) float maxsize; bool collisiondetection; u32 id; - u32 material_type_param = 0; - u8 animation_type = (u8)AT_NONE; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u16 min_first_frame = 0; - u16 max_first_frame = 0; - float frame_length = -1; - bool loop_animation = true; - u8 glow = 0; *pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel >> minacc >> maxacc >> minexptime >> maxexptime >> minsize @@ -980,46 +948,29 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) *pkt >> vertical; *pkt >> collision_removal; *pkt >> attached_id; - *pkt >> material_type_param; - *pkt >> animation_type; - *pkt >> vertical_frame_num; - *pkt >> horizontal_frame_num; - *pkt >> min_first_frame; - *pkt >> max_first_frame; - *pkt >> frame_length; - *pkt >> loop_animation; - *pkt >> glow; + } catch (...) {} ClientEvent event; - event.type = CE_ADD_PARTICLESPAWNER; - event.add_particlespawner.amount = amount; - event.add_particlespawner.spawntime = spawntime; - event.add_particlespawner.minpos = new v3f (minpos); - event.add_particlespawner.maxpos = new v3f (maxpos); - event.add_particlespawner.minvel = new v3f (minvel); - event.add_particlespawner.maxvel = new v3f (maxvel); - event.add_particlespawner.minacc = new v3f (minacc); - event.add_particlespawner.maxacc = new v3f (maxacc); - event.add_particlespawner.minexptime = minexptime; - event.add_particlespawner.maxexptime = maxexptime; - event.add_particlespawner.minsize = minsize; - event.add_particlespawner.maxsize = maxsize; - event.add_particlespawner.collisiondetection = collisiondetection; - event.add_particlespawner.collision_removal = collision_removal; - event.add_particlespawner.attached_id = attached_id; - event.add_particlespawner.vertical = vertical; - event.add_particlespawner.texture = new std::string(texture); - event.add_particlespawner.id = id; - event.add_particlespawner.material_type_param = material_type_param; - event.add_particlespawner.animation_type = (AnimationType)animation_type; - event.add_particlespawner.vertical_frame_num = vertical_frame_num; - event.add_particlespawner.horizontal_frame_num = horizontal_frame_num; - event.add_particlespawner.min_first_frame = min_first_frame; - event.add_particlespawner.max_first_frame = max_first_frame; - event.add_particlespawner.frame_length = frame_length; - event.add_particlespawner.loop_animation = loop_animation; - event.add_particlespawner.glow = glow; + event.type = CE_ADD_PARTICLESPAWNER; + event.add_particlespawner.amount = amount; + event.add_particlespawner.spawntime = spawntime; + event.add_particlespawner.minpos = new v3f (minpos); + event.add_particlespawner.maxpos = new v3f (maxpos); + event.add_particlespawner.minvel = new v3f (minvel); + event.add_particlespawner.maxvel = new v3f (maxvel); + event.add_particlespawner.minacc = new v3f (minacc); + event.add_particlespawner.maxacc = new v3f (maxacc); + event.add_particlespawner.minexptime = minexptime; + event.add_particlespawner.maxexptime = maxexptime; + event.add_particlespawner.minsize = minsize; + event.add_particlespawner.maxsize = maxsize; + event.add_particlespawner.collisiondetection = collisiondetection; + event.add_particlespawner.collision_removal = collision_removal; + event.add_particlespawner.attached_id = attached_id; + event.add_particlespawner.vertical = vertical; + event.add_particlespawner.texture = new std::string(texture); + event.add_particlespawner.id = id; m_client_event_queue.push(event); } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index c690e6720..39ea1a60e 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -211,7 +211,7 @@ void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, con { int version = readU8(is); name = deSerializeString(is); - animation.type = (AnimationType)readU8(is); + animation.type = (TileAnimationType)readU8(is); animation.aspect_w = readU16(is); animation.aspect_h = readU16(is); animation.length = readF1000(is); @@ -531,7 +531,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, tile->material_flags = 0; if (backface_culling) tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; - if (tiledef->animation.type == AT_VERTICAL_FRAMES) + if (tiledef->animation.type == TAT_VERTICAL_FRAMES) tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; if (tiledef->tileable_horizontal) tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; diff --git a/src/nodedef.h b/src/nodedef.h index f47517c4a..80396f992 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -161,10 +161,9 @@ enum NodeDrawType /* Stand-alone definition of a TileSpec (basically a server-side TileSpec) */ -enum AnimationType{ - AT_NONE = 0, - AT_VERTICAL_FRAMES = 1, - AT_2D_ANIMATION_SHEET = 2, +enum TileAnimationType{ + TAT_NONE=0, + TAT_VERTICAL_FRAMES=1, }; struct TileDef { @@ -173,7 +172,7 @@ struct TileDef bool tileable_horizontal; bool tileable_vertical; struct{ - enum AnimationType type; + enum TileAnimationType type; int aspect_w; // width for aspect ratio int aspect_h; // height for aspect ratio float length; // seconds @@ -185,7 +184,7 @@ struct TileDef backface_culling = true; tileable_horizontal = true; tileable_vertical = true; - animation.type = AT_NONE; + animation.type = TAT_NONE; animation.aspect_w = 1; animation.aspect_h = 1; animation.length = 1.0; diff --git a/src/particles.cpp b/src/particles.cpp index 538487028..f20fb4083 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -43,22 +43,6 @@ v3f random_v3f(v3f min, v3f max) rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z); } -u32 check_material_type_param(u32 material_type_param) -{ - u32 alphaSource = (material_type_param & 0x0000F000) >> 12; - u32 modulo = (material_type_param & 0x00000F00) >> 8; - u32 srcFact = (material_type_param & 0x000000F0) >> 4; - u32 dstFact = material_type_param & 0x0000000F; - if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { - return material_type_param; - } else { - errorstream << "Server send incorrect "; - errorstream << "material_type_param value for particle."; - errorstream << std::endl; - return 0; - } -} - Particle::Particle( IGameDef *gamedef, scene::ISceneManager* smgr, @@ -74,14 +58,7 @@ Particle::Particle( bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 first_frame, - float frame_length, - bool loop_animation, - u8 glow + v2f texsize ): scene::ISceneNode(smgr->getRootSceneNode(), smgr) { @@ -94,26 +71,11 @@ Particle::Particle( m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, true); - if (material_type_param != 0) { - m_material.MaterialType = video::EMT_ONETEXTURE_BLEND; - m_material.MaterialTypeParam = irr::core::FR(material_type_param); - // We must disable z-buffer if we want to avoid transparent pixels - // to overlap pixels with lower z-value. - m_material.setFlag(video::EMF_ZWRITE_ENABLE, false); - } else { - m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - } + m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m_material.setTexture(0, texture); - m_texpos = texpos; m_texsize = texsize; - m_vertical_frame_num = vertical_frame_num; - m_horizontal_frame_num = horizontal_frame_num; - m_first_frame = first_frame; - m_frame_length = frame_length; - m_loop_animation = loop_animation; - m_texsize.Y /= m_vertical_frame_num; - m_texsize.X /= m_horizontal_frame_num; + // Particle related m_pos = pos; @@ -126,7 +88,6 @@ Particle::Particle( m_collisiondetection = collisiondetection; m_collision_removal = collision_removal; m_vertical = vertical; - m_glow = glow; // Irrlicht stuff m_collisionbox = aabb3f @@ -209,29 +170,16 @@ void Particle::updateLight() else light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0); - m_light = decode_light(light + m_glow); + m_light = decode_light(light); } void Particle::updateVertices() { video::SColor c(255, m_light, m_light, m_light); - u16 frame = m_first_frame; - if (m_frame_length > 0) { - if (m_loop_animation) - frame = m_first_frame + (u32)(m_time / m_frame_length) - % (m_vertical_frame_num * - m_horizontal_frame_num - m_first_frame); - else if (m_time >= - (m_vertical_frame_num * m_horizontal_frame_num - - m_first_frame) * m_frame_length) - frame = m_vertical_frame_num * m_horizontal_frame_num - 1; - else - frame = m_first_frame + (u16)(m_time / m_frame_length); - } - f32 tx0 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num); - f32 tx1 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num + 1); - f32 ty0 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num); - f32 ty1 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num + 1); + f32 tx0 = m_texpos.X; + f32 tx1 = m_texpos.X + m_texsize.X; + f32 ty0 = m_texpos.Y; + f32 ty1 = m_texpos.Y + m_texsize.Y; m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0, c, tx0, ty1); @@ -266,16 +214,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, bool vertical, - video::ITexture *texture, u32 id, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 min_first_frame, - u16 max_first_frame, - float frame_length, - bool loop_animation, - u8 glow, - ParticleManager *p_manager) : + video::ITexture *texture, u32 id, ParticleManager *p_manager) : m_particlemanager(p_manager) { m_gamedef = gamedef; @@ -299,14 +238,6 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, m_vertical = vertical; m_texture = texture; m_time = 0; - m_vertical_frame_num = vertical_frame_num; - m_horizontal_frame_num = horizontal_frame_num; - m_min_first_frame = min_first_frame; - m_max_first_frame = max_first_frame; - m_frame_length = frame_length; - m_loop_animation = loop_animation; - m_material_type_param = material_type_param; - m_glow = glow; for (u16 i = 0; i<=m_amount; i++) { @@ -320,6 +251,7 @@ ParticleSpawner::~ParticleSpawner() {} void ParticleSpawner::step(float dtime, ClientEnvironment* env) { m_time += dtime; + bool unloaded = false; v3f attached_offset = v3f(0,0,0); if (m_attached_id != 0) { @@ -353,10 +285,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - u16 first_frame = m_min_first_frame + - rand() % - (m_max_first_frame - - m_min_first_frame + 1); + Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -372,14 +301,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0), - m_material_type_param, - m_vertical_frame_num, - m_horizontal_frame_num, - first_frame, - m_frame_length, - m_loop_animation, - m_glow); + v2f(1.0, 1.0)); m_particlemanager->addParticle(toadd); } i = m_spawntimes.erase(i); @@ -409,10 +331,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - u16 first_frame = m_min_first_frame + - rand() % - (m_max_first_frame - - m_min_first_frame + 1); + Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -428,14 +347,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0), - m_material_type_param, - m_vertical_frame_num, - m_horizontal_frame_num, - first_frame, - m_frame_length, - m_loop_animation, - m_glow); + v2f(1.0, 1.0)); m_particlemanager->addParticle(toadd); } } @@ -547,39 +459,6 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture)); - float frame_length = -1; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u32 material_type_param = - check_material_type_param(event->add_particlespawner.material_type_param); - - switch (event->add_particlespawner.animation_type) { - case AT_NONE: - break; - case AT_VERTICAL_FRAMES: { - v2u32 size = texture->getOriginalSize(); - int frame_height = (float)size.X / - (float)event->add_particlespawner.vertical_frame_num * - (float)event->add_particlespawner.horizontal_frame_num; - vertical_frame_num = size.Y / frame_height; - frame_length = - event->add_particlespawner.frame_length / - vertical_frame_num; - break; - } - case AT_2D_ANIMATION_SHEET: { - vertical_frame_num = - event->add_particlespawner.vertical_frame_num; - horizontal_frame_num = - event->add_particlespawner.horizontal_frame_num; - frame_length = - event->add_particlespawner.frame_length; - break; - } - default: - break; - } - ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player, event->add_particlespawner.amount, event->add_particlespawner.spawntime, @@ -599,14 +478,6 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->add_particlespawner.vertical, texture, event->add_particlespawner.id, - material_type_param, - vertical_frame_num, - horizontal_frame_num, - event->add_particlespawner.min_first_frame, - event->add_particlespawner.max_first_frame, - frame_length, - event->add_particlespawner.loop_animation, - event->add_particlespawner.glow, this); /* delete allocated content of event */ @@ -631,39 +502,6 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture)); - float frame_length = -1; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u32 material_type_param = - check_material_type_param(event->spawn_particle.material_type_param); - - switch (event->spawn_particle.animation_type) { - case AT_NONE: - break; - case AT_VERTICAL_FRAMES: { - v2u32 size = texture->getOriginalSize(); - int frame_height = (float)size.X / - (float)event->spawn_particle.vertical_frame_num * - (float)event->spawn_particle.horizontal_frame_num; - vertical_frame_num = size.Y / frame_height; - frame_length = - event->spawn_particle.frame_length / - vertical_frame_num; - break; - } - case AT_2D_ANIMATION_SHEET: { - vertical_frame_num = - event->spawn_particle.vertical_frame_num; - horizontal_frame_num = - event->spawn_particle.horizontal_frame_num; - frame_length = - event->spawn_particle.frame_length; - break; - } - default: - break; - } - Particle* toadd = new Particle(gamedef, smgr, player, m_env, *event->spawn_particle.pos, *event->spawn_particle.vel, @@ -675,21 +513,13 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->spawn_particle.vertical, texture, v2f(0.0, 0.0), - v2f(1.0, 1.0), - material_type_param, - vertical_frame_num, - horizontal_frame_num, - event->spawn_particle.first_frame, - frame_length, - event->spawn_particle.loop_animation, - event->spawn_particle.glow); + v2f(1.0, 1.0)); addParticle(toadd); delete event->spawn_particle.pos; delete event->spawn_particle.vel; delete event->spawn_particle.acc; - delete event->spawn_particle.texture; break; } @@ -758,8 +588,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s false, texture, texpos, - texsize, - 0, 1, 1, 0, -1, true, 0); + texsize); addParticle(toadd); } diff --git a/src/particles.h b/src/particles.h index 6d8c6139f..eb8c6665d 100644 --- a/src/particles.h +++ b/src/particles.h @@ -50,14 +50,7 @@ class Particle : public scene::ISceneNode bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 first_frame, - float frame_length, - bool loop_animation, - u8 glow + v2f texsize ); ~Particle(); @@ -109,12 +102,6 @@ private: bool m_collision_removal; bool m_vertical; v3s16 m_camera_offset; - u16 m_vertical_frame_num; - u16 m_horizontal_frame_num; - u16 m_first_frame; - float m_frame_length; - bool m_loop_animation; - u8 m_glow; }; class ParticleSpawner @@ -136,15 +123,8 @@ class ParticleSpawner bool vertical, video::ITexture *texture, u32 id, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 min_first_frame, - u16 max_first_frame, - float frame_length, - bool loop_animation, - u8 glow, ParticleManager* p_manager); + ~ParticleSpawner(); void step(float dtime, ClientEnvironment *env); @@ -176,14 +156,6 @@ class ParticleSpawner bool m_collision_removal; bool m_vertical; u16 m_attached_id; - u32 m_material_type_param; - u16 m_vertical_frame_num; - u16 m_horizontal_frame_num; - u16 m_min_first_frame; - u16 m_max_first_frame; - float m_frame_length; - bool m_loop_animation; - u8 m_glow; }; /** diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index d4a25b68b..f20a65903 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -35,11 +35,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "noise.h" #include -struct EnumString es_AnimationType[] = +struct EnumString es_TileAnimationType[] = { - {AT_NONE, "none"}, - {AT_VERTICAL_FRAMES, "vertical_frames"}, - {AT_2D_ANIMATION_SHEET, "2d_animation_sheet"}, + {TAT_NONE, "none"}, + {TAT_VERTICAL_FRAMES, "vertical_frames"}, {0, NULL}, }; @@ -336,9 +335,9 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} - tiledef.animation.type = (AnimationType) - getenumfield(L, -1, "type", es_AnimationType, - AT_NONE); + tiledef.animation.type = (TileAnimationType) + getenumfield(L, -1, "type", es_TileAnimationType, + TAT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 32fdb4f04..2a2228b6d 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -159,6 +159,6 @@ bool push_json_value (lua_State *L, void read_json_value (lua_State *L, Json::Value &root, int index, u8 recursion = 0); -extern struct EnumString es_AnimationType[]; +extern struct EnumString es_TileAnimationType[]; #endif /* C_CONTENT_H_ */ diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index cfb5e26db..f36298915 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -513,28 +513,6 @@ int getintfield_default(lua_State *L, int table, return result; } -int check_material_type_param(lua_State *L, int table, - const char *fieldname, int default_) -{ - int material_type_param = - getintfield_default(L, table, fieldname, default_); - u32 alphaSource = (material_type_param & 0x0000F000) >> 12; - u32 modulo = (material_type_param & 0x00000F00) >> 8; - u32 srcFact = (material_type_param & 0x000000F0) >> 4; - u32 dstFact = material_type_param & 0x0000000F; - if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { - return material_type_param; - } else { - std::ostringstream error_text; - error_text << "Incorrect material_type_param value "; - error_text << "for particle or particle spawner."; - error_text << std::endl; - throw LuaError(error_text.str()); - return 0; - } -} - - float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_) { diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index 71ac735c1..a5fbee765 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -45,8 +45,6 @@ float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_); int getintfield_default (lua_State *L, int table, const char *fieldname, int default_); -int check_material_type_param(lua_State *L, int table, - const char *fieldname, int default_); bool getstringfield(lua_State *L, int table, const char *fieldname, std::string &result); diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index b0a57ce6d..667ac7272 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_object.h" #include "lua_api/l_internal.h" #include "common/c_converter.h" -#include "common/c_content.h" #include "server.h" #include "particles.h" @@ -35,9 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc., // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" -// material_type_param = num -// animation = animation definition -// glow = indexed color or color string int ModApiParticles::l_add_particle(lua_State *L) { MAP_LOCK_REQUIRED; @@ -48,24 +44,13 @@ int ModApiParticles::l_add_particle(lua_State *L) float expirationtime, size; expirationtime = size = 1; - float frame_or_loop_length = -1; - - AnimationType animation_type = AT_NONE; - - u16 vertical_frame_num_or_aspect = 1; - u16 horizontal_frame_num_or_aspect = 1; - u16 first_frame = 0; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; - bool loop_animation = true; std::string texture = ""; std::string playername = ""; - u32 material_type_param = 0; - u8 glow = 0; - if (lua_gettop(L) > 1) // deprecated { log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition"); @@ -109,61 +94,8 @@ int ModApiParticles::l_add_particle(lua_State *L) acc = lua_istable(L, -1) ? check_v3f(L, -1) : acc; lua_pop(L, 1); - expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); + expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); size = getfloatfield_default(L, 1, "size", 1); - - lua_getfield(L, 1, "animation"); - if (lua_istable(L, -1)) { - animation_type = (AnimationType) - getenumfield(L, -1, "type", es_AnimationType, - AT_NONE); - } - switch (animation_type) { - case AT_NONE: - break; - case AT_2D_ANIMATION_SHEET: - frame_or_loop_length = - getfloatfield_default(L, -1, "frame_length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "vertical_frame_num", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "horizontal_frame_num", 1); - first_frame = - getintfield_default(L, -1, "first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - case AT_VERTICAL_FRAMES: - frame_or_loop_length = - getfloatfield_default(L, -1, "length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_w", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_h", 1); - first_frame = - getintfield_default(L, -1, "first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - default: - break; - } - lua_pop(L, 1); - - if (animation_type == AT_2D_ANIMATION_SHEET && - first_frame >= vertical_frame_num_or_aspect * - horizontal_frame_num_or_aspect) { - std::ostringstream error_text; - error_text << "first_frame should be lower, than " - << "vertical_frame_num * horizontal_frame_num. " - << "Got first_frame=" << first_frame - << ", vertical_frame_num=" - << vertical_frame_num_or_aspect - << " and horizontal_frame_num=" - << horizontal_frame_num_or_aspect << std::endl; - throw LuaError(error_text.str()); - } - collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -171,16 +103,9 @@ int ModApiParticles::l_add_particle(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); - material_type_param = check_material_type_param(L, 1, "material_type_param", 0); - glow = getintfield_default (L, 1, "glow", 0); } - getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, - size, collisiondetection, collision_removal, vertical, - texture, material_type_param, - animation_type, - vertical_frame_num_or_aspect, - horizontal_frame_num_or_aspect, - first_frame, frame_or_loop_length, loop_animation, glow); + getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, + collisiondetection, collision_removal, vertical, texture); return 1; } @@ -202,33 +127,21 @@ int ModApiParticles::l_add_particle(lua_State *L) // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" -// material_type_param = num -// animation = animation definition -// glow = indexed color or color string int ModApiParticles::l_add_particlespawner(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters u16 amount = 1; - u16 vertical_frame_num_or_aspect = 1; - u16 horizontal_frame_num_or_aspect = 1; - u16 min_first_frame = 0; - u16 max_first_frame = 0; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; - AnimationType animation_type = AT_NONE; - float frame_or_loop_length = -1; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; - bool loop_animation = true; ServerActiveObject *attached = NULL; std::string texture = ""; std::string playername = ""; - u32 material_type_param = 0; - u8 glow = 0; if (lua_gettop(L) > 1) //deprecated { @@ -283,65 +196,6 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); - - - lua_getfield(L, 1, "animation"); - if (lua_istable(L, -1)) { - animation_type = (AnimationType) - getenumfield(L, -1, "type", es_AnimationType, - AT_NONE); - } - switch (animation_type) { - case AT_NONE: - break; - case AT_2D_ANIMATION_SHEET: - frame_or_loop_length = - getfloatfield_default(L, -1, "frame_length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "vertical_frame_num", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "horizontal_frame_num", 1); - min_first_frame = - getintfield_default(L, -1, "min_first_frame", 0); - max_first_frame = - getintfield_default(L, -1, "max_first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - case AT_VERTICAL_FRAMES: - frame_or_loop_length = - getfloatfield_default(L, -1, "length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_w", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_h", 1); - min_first_frame = - getintfield_default(L, -1, "min_first_frame", 0); - max_first_frame = - getintfield_default(L, -1, "max_first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - default: - break; - } - lua_pop(L, 1); - - if (animation_type == AT_2D_ANIMATION_SHEET && - max_first_frame >= vertical_frame_num_or_aspect * - horizontal_frame_num_or_aspect) { - std::ostringstream error_text; - error_text << "max_first_frame should be lower, than " - << "vertical_frame_num * horizontal_frame_num. " - << "Got max_first_frame=" - << max_first_frame - << ", vertical_frame_num=" - << vertical_frame_num_or_aspect - << " and horizontal_frame_num=" - << horizontal_frame_num_or_aspect << std::endl; - throw LuaError(error_text.str()); - } - collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -357,8 +211,6 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); - material_type_param = check_material_type_param(L, 1, "material_type_param", 0); - glow = getintfield_default(L, 1, "glow", 0); } u32 id = getServer(L)->addParticleSpawner(amount, time, @@ -371,17 +223,9 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) collision_removal, attached, vertical, - texture, - playername, - material_type_param, - animation_type, - vertical_frame_num_or_aspect, - horizontal_frame_num_or_aspect, - min_first_frame, max_first_frame, - frame_or_loop_length, - loop_animation, - glow); + texture, playername); lua_pushnumber(L, id); + return 1; } diff --git a/src/server.cpp b/src/server.cpp index cef57be88..48331e4f8 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1658,11 +1658,7 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow) + bool vertical, const std::string &texture) { DSTACK(FUNCTION_NAME); @@ -1674,12 +1670,6 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat pkt << vertical; pkt << collision_removal; - pkt << material_type_param - << (u8)animation_type - << vertical_frame_num - << horizontal_frame_num << first_frame - << frame_length << loop_animation << glow; - if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -1692,10 +1682,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, - u16 attached_id, bool vertical, const std::string &texture, u32 id, - u32 material_type_param, AnimationType animation_type, u16 vertical_frame_num, u16 horizontal_frame_num, - u16 min_first_frame, u16 max_first_frame, float frame_length, - bool loop_animation, u8 glow) + u16 attached_id, bool vertical, const std::string &texture, u32 id) { DSTACK(FUNCTION_NAME); @@ -1711,12 +1698,6 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3 pkt << collision_removal; pkt << attached_id; - pkt << material_type_param - << (u8)animation_type - << vertical_frame_num << horizontal_frame_num - << min_first_frame << max_first_frame - << frame_length << loop_animation << glow; - if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -3166,11 +3147,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow) + bool vertical, const std::string &texture) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3186,11 +3163,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos, SendSpawnParticle(peer_id, pos, velocity, acceleration, expirationtime, size, collisiondetection, - collision_removal, vertical, texture, - material_type_param, animation_type, - vertical_frame_num, horizontal_frame_num, - first_frame, frame_length, loop_animation, - glow); + collision_removal, vertical, texture); } u32 Server::addParticleSpawner(u16 amount, float spawntime, @@ -3198,9 +3171,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername, u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 min_first_frame, u16 max_first_frame, - float frame_length, bool loop_animation, u8 glow) + const std::string &playername) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3226,10 +3197,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, collision_removal, attached_id, vertical, - texture, id, material_type_param, animation_type, - vertical_frame_num, horizontal_frame_num, - min_first_frame, max_first_frame, frame_length, loop_animation, - glow); + texture, id); return id; } diff --git a/src/server.h b/src/server.h index 9a8d22b2e..9e844e36c 100644 --- a/src/server.h +++ b/src/server.h @@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "gamedef.h" #include "serialization.h" // For SER_FMT_VER_INVALID -#include "nodedef.h" // AnimationType #include "mods.h" #include "inventorymanager.h" #include "subgame.h" @@ -255,11 +254,7 @@ public: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow); + bool vertical, const std::string &texture); u32 addParticleSpawner(u16 amount, float spawntime, v3f minpos, v3f maxpos, @@ -270,12 +265,7 @@ public: bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, - u16 min_first_frame, u16 max_first_frame, - float frame_length, bool loop_animation, - u8 glow); + const std::string &playername); void deleteParticleSpawner(const std::string &playername, u32 id); @@ -451,12 +441,7 @@ private: float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, - bool vertical, const std::string &texture, u32 id, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, - u16 min_first_frame, u16 max_first_frame, - float frame_length, bool loop_animation, - u8 glow); + bool vertical, const std::string &texture, u32 id); void SendDeleteParticleSpawner(u16 peer_id, u32 id); @@ -465,11 +450,7 @@ private: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow); + bool vertical, const std::string &texture); u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas); void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true); -- cgit v1.2.3 From 2fe3bf5a18eb9aa9f38654b3c0a0729c42408cd6 Mon Sep 17 00:00:00 2001 From: juhdanad Date: Mon, 28 Nov 2016 09:43:33 +0100 Subject: Limit light_source in the engine (#4814) Since light_source>15 causes crash, it must be limited. --- src/nodedef.cpp | 2 ++ src/script/common/c_content.cpp | 6 ++++++ src/voxelalgorithms.cpp | 1 + 3 files changed, 9 insertions(+) (limited to 'src/nodedef.cpp') diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 39ea1a60e..ccbb42c66 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -482,6 +482,7 @@ void ContentFeatures::deSerialize(std::istream &is) liquid_viscosity = readU8(is); liquid_renewable = readU8(is); light_source = readU8(is); + light_source = MYMIN(light_source, LIGHT_MAX); damage_per_second = readU32(is); node_box.deSerialize(is); selection_box.deSerialize(is); @@ -1442,6 +1443,7 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version) liquid_alternative_source = deSerializeString(is); liquid_viscosity = readU8(is); light_source = readU8(is); + light_source = MYMIN(light_source, LIGHT_MAX); damage_per_second = readU32(is); node_box.deSerialize(is); selection_box.deSerialize(is); diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index f20a65903..541744895 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -526,6 +526,12 @@ ContentFeatures read_content_features(lua_State *L, int index) // Amount of light the node emits f.light_source = getintfield_default(L, index, "light_source", f.light_source); + if (f.light_source > LIGHT_MAX) { + warningstream << "Node " << f.name.c_str() + << " had greater light_source than " << LIGHT_MAX + << ", it was reduced." << std::endl; + f.light_source = LIGHT_MAX; + } f.damage_per_second = getintfield_default(L, index, "damage_per_second", f.damage_per_second); diff --git a/src/voxelalgorithms.cpp b/src/voxelalgorithms.cpp index 55f0d1c98..93cc33acc 100644 --- a/src/voxelalgorithms.cpp +++ b/src/voxelalgorithms.cpp @@ -264,6 +264,7 @@ struct LightQueue { const mapblock_v3 &block_pos, MapBlock *block, direction source_dir) { + assert(light <= LIGHT_SUN); lights[light].push_back( ChangingLight(rel_pos, block_pos, block, source_dir)); } -- cgit v1.2.3