mirror of https://github.com/minetest/minetest.git
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
77d5926700
|
@ -192,11 +192,15 @@ function minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||||
-- Add node and update
|
-- Add node and update
|
||||||
minetest.env:add_node(place_to, newnode)
|
minetest.env:add_node(place_to, newnode)
|
||||||
|
|
||||||
|
local take_item = true
|
||||||
|
|
||||||
-- Run callback
|
-- Run callback
|
||||||
if def.after_place_node then
|
if def.after_place_node then
|
||||||
-- Copy place_to because callback can modify it
|
-- Copy place_to because callback can modify it
|
||||||
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
|
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
|
||||||
def.after_place_node(place_to_copy, placer)
|
if def.after_place_node(place_to_copy, placer, itemstack) then
|
||||||
|
take_item = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run script hook
|
-- Run script hook
|
||||||
|
@ -206,10 +210,14 @@ function minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||||
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
|
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
|
||||||
local newnode_copy = {name=newnode.name, param1=newnode.param1, param2=newnode.param2}
|
local newnode_copy = {name=newnode.name, param1=newnode.param1, param2=newnode.param2}
|
||||||
local oldnode_copy = {name=oldnode.name, param1=oldnode.param1, param2=oldnode.param2}
|
local oldnode_copy = {name=oldnode.name, param1=oldnode.param1, param2=oldnode.param2}
|
||||||
callback(place_to_copy, newnode_copy, placer, oldnode_copy)
|
if callback(place_to_copy, newnode_copy, placer, oldnode_copy, itemstack) then
|
||||||
|
take_item = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if take_item then
|
||||||
itemstack:take_item()
|
itemstack:take_item()
|
||||||
|
end
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,38 @@
|
||||||
# CURL_LIBRARY - List of libraries when using curl.
|
# CURL_LIBRARY - List of libraries when using curl.
|
||||||
# CURL_FOUND - True if curl found.
|
# CURL_FOUND - True if curl found.
|
||||||
|
|
||||||
# Look for the header file.
|
if( UNIX )
|
||||||
FIND_PATH(CURL_INCLUDE_DIR NAMES curl/curl.h)
|
FIND_PATH(CURL_INCLUDE_DIR NAMES curl.h
|
||||||
|
PATHS
|
||||||
|
/usr/local/include/curl
|
||||||
|
/usr/include/curl
|
||||||
|
)
|
||||||
|
|
||||||
# Look for the library.
|
FIND_LIBRARY(CURL_LIBRARY NAMES curl
|
||||||
FIND_LIBRARY(CURL_LIBRARY NAMES curl)
|
PATHS
|
||||||
|
/usr/local/lib
|
||||||
|
/usr/lib
|
||||||
|
)
|
||||||
|
else( UNIX )
|
||||||
|
FIND_PATH(CURL_INCLUDE_DIR NAMES curl/curl.h) # Look for the header file.
|
||||||
|
FIND_LIBRARY(CURL_LIBRARY NAMES curl) # Look for the library.
|
||||||
|
INCLUDE(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if
|
||||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL DEFAULT_MSG CURL_LIBRARY CURL_INCLUDE_DIR) # all listed variables are TRUE
|
||||||
|
endif( UNIX )
|
||||||
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if
|
if( WIN32 )
|
||||||
# all listed variables are TRUE
|
if( CURL_LIBRARY AND CURL_INCLUDE_DIR AND CURL_DLL ) # libcurl.dll is required on Windows
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
SET(CURL_FOUND TRUE)
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL DEFAULT_MSG CURL_LIBRARY CURL_INCLUDE_DIR)
|
else( CURL_LIBRARY AND CURL_INCLUDE_DIR AND CURL_DLL )
|
||||||
|
SET(CURL_FOUND FALSE)
|
||||||
|
endif( CURL_LIBRARY AND CURL_INCLUDE_DIR AND CURL_DLL )
|
||||||
|
else ( WIN32 )
|
||||||
|
if( CURL_LIBRARY AND CURL_INCLUDE_DIR )
|
||||||
|
SET(CURL_FOUND TRUE)
|
||||||
|
else( CURL_LIBRARY AND CURL_INCLUDE_DIR )
|
||||||
|
SET(CURL_FOUND FALSE)
|
||||||
|
endif( CURL_LIBRARY AND CURL_INCLUDE_DIR )
|
||||||
|
endif ( WIN32 )
|
||||||
|
|
||||||
|
MESSAGE(STATUS "CURL_INCLUDE_DIR = ${CURL_INCLUDE_DIR}")
|
||||||
|
MESSAGE(STATUS "CURL_LIBRARY = ${CURL_LIBRARY}")
|
||||||
|
|
|
@ -810,8 +810,9 @@ minetest.register_on_shutdown(func())
|
||||||
^ WARNING: If the server terminates abnormally (i.e. crashes), the registered
|
^ WARNING: If the server terminates abnormally (i.e. crashes), the registered
|
||||||
callbacks WILL LIKELY NOT BE RUN. Data should be saved at
|
callbacks WILL LIKELY NOT BE RUN. Data should be saved at
|
||||||
semi-frequent intervals as well as on server shutdown.
|
semi-frequent intervals as well as on server shutdown.
|
||||||
minetest.register_on_placenode(func(pos, newnode, placer, oldnode))
|
minetest.register_on_placenode(func(pos, newnode, placer, oldnode, itemstack))
|
||||||
^ Called when a node has been placed
|
^ Called when a node has been placed
|
||||||
|
^ If return true no item is taken from itemstack
|
||||||
^ Deprecated: Use on_construct or after_place_node in node definition instead
|
^ Deprecated: Use on_construct or after_place_node in node definition instead
|
||||||
minetest.register_on_dignode(func(pos, oldnode, digger))
|
minetest.register_on_dignode(func(pos, oldnode, digger))
|
||||||
^ Called when a node has been dug.
|
^ Called when a node has been dug.
|
||||||
|
@ -1062,6 +1063,60 @@ methods:
|
||||||
^ Return world-specific perlin noise (int(worldseed)+seeddiff)
|
^ Return world-specific perlin noise (int(worldseed)+seeddiff)
|
||||||
- clear_objects()
|
- clear_objects()
|
||||||
^ clear all objects in the environments
|
^ clear all objects in the environments
|
||||||
|
- spawn_tree (pos, {treedef})
|
||||||
|
^ spawns L-System tree at given pos with definition in treedef table
|
||||||
|
treedef={
|
||||||
|
axiom, - string initial tree axiom
|
||||||
|
rules_a, - string rules set A
|
||||||
|
rules_b, - string rules set B
|
||||||
|
rules_c, - string rules set C
|
||||||
|
rules_d, - string rules set D
|
||||||
|
trunk, - string trunk node name
|
||||||
|
leaves, - string leaves node name
|
||||||
|
angle, - num angle in deg
|
||||||
|
iterations, - num max # of iterations, usually 2 -5
|
||||||
|
random_level, - num factor to lower nr of iterations, usually 0 - 3
|
||||||
|
thin_trunks, - boolean true -> use thin trunks
|
||||||
|
fruit_tree, - boolean true -> is a fruit tree
|
||||||
|
fruit - string fruit node name
|
||||||
|
}
|
||||||
|
|
||||||
|
Key for Special L-System Symbols used in Axioms
|
||||||
|
G - move forward one unit with the pin down
|
||||||
|
F - move forward one unit with the pin up
|
||||||
|
A - replace with rules set A
|
||||||
|
B - replace with rules set B
|
||||||
|
C - replace with rules set C
|
||||||
|
D - replace with rules set D
|
||||||
|
a - replace with rules set A, chance 90%
|
||||||
|
b - replace with rules set B, chance 80%
|
||||||
|
c - replace with rules set C, chance 70%
|
||||||
|
d - replace with rules set D, chance 60%
|
||||||
|
+ - yaw the turtle right by angle parameter
|
||||||
|
- - yaw the turtle left by angle parameter
|
||||||
|
& - pitch the turtle down by angle parameter
|
||||||
|
^ - pitch the turtle up by angle parameter
|
||||||
|
/ - roll the turtle to the right by angle parameter
|
||||||
|
* - roll the turtle to the left by angle parameter
|
||||||
|
[ - save in stack current state info
|
||||||
|
] - recover from stack state info
|
||||||
|
|
||||||
|
Example usage: spawn small apple tree
|
||||||
|
apple_tree={
|
||||||
|
axiom="FFFFFAFFBF",
|
||||||
|
rules_a="[&&&FFFFF&&FFFF][&&&++++FFFFF&&FFFF][&&&----FFFFF&&FFFF]",
|
||||||
|
rules_b="[&&&++FFFFF&&FFFF][&&&--FFFFF&&FFFF][&&&------FFFFF&&FFFF]",
|
||||||
|
trunk="default:tree",
|
||||||
|
leaves="default:leaves",
|
||||||
|
angle=30,
|
||||||
|
iterations=2,
|
||||||
|
random_level=0,
|
||||||
|
thin_trunks=true,
|
||||||
|
fruit_tree=true,
|
||||||
|
fruit="default:apple"
|
||||||
|
}
|
||||||
|
minetest.env:spawn_tree(pos,apple_tree)
|
||||||
|
|
||||||
Deprecated:
|
Deprecated:
|
||||||
- add_rat(pos): Add C++ rat object (no-op)
|
- add_rat(pos): Add C++ rat object (no-op)
|
||||||
- add_firefly(pos): Add C++ firefly object (no-op)
|
- add_firefly(pos): Add C++ firefly object (no-op)
|
||||||
|
@ -1405,9 +1460,10 @@ Node definition (register_node)
|
||||||
^ Node destructor; always called after removing node
|
^ Node destructor; always called after removing node
|
||||||
^ default: nil
|
^ default: nil
|
||||||
|
|
||||||
after_place_node = func(pos, placer),
|
after_place_node = func(pos, placer, itemstack),
|
||||||
^ Called after constructing node when node was placed using
|
^ Called after constructing node when node was placed using
|
||||||
minetest.item_place_node / minetest.env:place_node
|
minetest.item_place_node / minetest.env:place_node
|
||||||
|
^ If return true no item is taken from itemstack
|
||||||
^ default: nil
|
^ default: nil
|
||||||
after_dig_node = func(pos, oldnode, oldmetadata, digger),
|
after_dig_node = func(pos, oldnode, oldmetadata, digger),
|
||||||
^ oldmetadata is in table format
|
^ oldmetadata is in table format
|
||||||
|
|
|
@ -124,6 +124,12 @@
|
||||||
#console_color = (0,0,0)
|
#console_color = (0,0,0)
|
||||||
# In-game chat console background alpha (opaqueness, between 0 and 255)
|
# In-game chat console background alpha (opaqueness, between 0 and 255)
|
||||||
#console_alpha = 200
|
#console_alpha = 200
|
||||||
|
# Selection box border color (R,G,B)
|
||||||
|
#selectionbox_color = (0,0,0)
|
||||||
|
# Crosshair color (R,G,B)
|
||||||
|
#crosshair_color = (255,255,255)
|
||||||
|
# Cross alpha (opaqueness, between 0 and 255)
|
||||||
|
#crosshair_alpha = 255
|
||||||
# Sound settings
|
# Sound settings
|
||||||
#enable_sound = true
|
#enable_sound = true
|
||||||
#sound_volume = 0.7
|
#sound_volume = 0.7
|
||||||
|
|
|
@ -12,7 +12,9 @@ if (NOT ENABLE_CURL)
|
||||||
mark_as_advanced(CLEAR CURL_LIBRARY CURL_INCLUDE_DIR)
|
mark_as_advanced(CLEAR CURL_LIBRARY CURL_INCLUDE_DIR)
|
||||||
endif(NOT ENABLE_CURL)
|
endif(NOT ENABLE_CURL)
|
||||||
|
|
||||||
|
if( ENABLE_CURL )
|
||||||
find_package(CURL)
|
find_package(CURL)
|
||||||
|
endif( ENABLE_CURL )
|
||||||
set(USE_CURL 0)
|
set(USE_CURL 0)
|
||||||
if (CURL_FOUND AND ENABLE_CURL)
|
if (CURL_FOUND AND ENABLE_CURL)
|
||||||
message(STATUS "cURL support enabled")
|
message(STATUS "cURL support enabled")
|
||||||
|
@ -186,6 +188,7 @@ set(common_SRCS
|
||||||
log.cpp
|
log.cpp
|
||||||
content_sao.cpp
|
content_sao.cpp
|
||||||
mapgen.cpp
|
mapgen.cpp
|
||||||
|
treegen.cpp
|
||||||
content_nodemeta.cpp
|
content_nodemeta.cpp
|
||||||
content_mapnode.cpp
|
content_mapnode.cpp
|
||||||
collision.cpp
|
collision.cpp
|
||||||
|
@ -436,6 +439,9 @@ if(WIN32)
|
||||||
if(VORBISFILE_DLL)
|
if(VORBISFILE_DLL)
|
||||||
install(FILES ${VORBISFILE_DLL} DESTINATION ${BINDIR})
|
install(FILES ${VORBISFILE_DLL} DESTINATION ${BINDIR})
|
||||||
endif()
|
endif()
|
||||||
|
if(CURL_DLL)
|
||||||
|
install(FILES ${CURL_DLL} DESTINATION ${BINDIR})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -236,6 +236,7 @@ void * MediaFetchThread::Thread()
|
||||||
i != m_file_requests.end(); i++) {
|
i != m_file_requests.end(); i++) {
|
||||||
curl = curl_easy_init();
|
curl = curl_easy_init();
|
||||||
assert(curl);
|
assert(curl);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, (m_remote_url + i->name).c_str());
|
curl_easy_setopt(curl, CURLOPT_URL, (m_remote_url + i->name).c_str());
|
||||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
|
curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
|
||||||
std::ostringstream stream;
|
std::ostringstream stream;
|
||||||
|
|
|
@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "content_sao.h"
|
#include "content_sao.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "mapblock.h" // For getNodeBlockPos
|
#include "mapblock.h" // For getNodeBlockPos
|
||||||
#include "mapgen.h" // For mapgen::make_tree
|
#include "treegen.h" // For treegen::make_tree
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
|
||||||
|
@ -118,7 +118,7 @@ public:
|
||||||
v3s16 tree_blockp = getNodeBlockPos(tree_p);
|
v3s16 tree_blockp = getNodeBlockPos(tree_p);
|
||||||
vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
|
vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
|
||||||
bool is_apple_tree = myrand()%4 == 0;
|
bool is_apple_tree = myrand()%4 == 0;
|
||||||
mapgen::make_tree(vmanip, tree_p, is_apple_tree, ndef);
|
treegen::make_tree(vmanip, tree_p, is_apple_tree, ndef);
|
||||||
vmanip.blitBackAll(&modified_blocks);
|
vmanip.blitBackAll(&modified_blocks);
|
||||||
|
|
||||||
// update lighting
|
// update lighting
|
||||||
|
|
|
@ -356,8 +356,11 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
|
||||||
m_last_sent_position_timer(0),
|
m_last_sent_position_timer(0),
|
||||||
m_last_sent_move_precision(0),
|
m_last_sent_move_precision(0),
|
||||||
m_armor_groups_sent(false),
|
m_armor_groups_sent(false),
|
||||||
|
m_animation_speed(0),
|
||||||
|
m_animation_blend(0),
|
||||||
m_animation_sent(false),
|
m_animation_sent(false),
|
||||||
m_bone_position_sent(false),
|
m_bone_position_sent(false),
|
||||||
|
m_attachment_parent_id(0),
|
||||||
m_attachment_sent(false)
|
m_attachment_sent(false)
|
||||||
{
|
{
|
||||||
// Only register type if no environment supplied
|
// Only register type if no environment supplied
|
||||||
|
|
|
@ -108,6 +108,9 @@ void set_default_settings(Settings *settings)
|
||||||
settings->setDefault("opaque_water", "false");
|
settings->setDefault("opaque_water", "false");
|
||||||
settings->setDefault("console_color", "(0,0,0)");
|
settings->setDefault("console_color", "(0,0,0)");
|
||||||
settings->setDefault("console_alpha", "200");
|
settings->setDefault("console_alpha", "200");
|
||||||
|
settings->setDefault("selectionbox_color", "(0,0,0)");
|
||||||
|
settings->setDefault("crosshair_color", "(255,255,255)");
|
||||||
|
settings->setDefault("crosshair_alpha", "255");
|
||||||
settings->setDefault("enable_sound", "true");
|
settings->setDefault("enable_sound", "true");
|
||||||
settings->setDefault("sound_volume", "0.8");
|
settings->setDefault("sound_volume", "0.8");
|
||||||
settings->setDefault("desynchronize_mapblock_texture_animation", "true");
|
settings->setDefault("desynchronize_mapblock_texture_animation", "true");
|
||||||
|
|
17
src/game.cpp
17
src/game.cpp
|
@ -2920,6 +2920,11 @@ void the_game(
|
||||||
|
|
||||||
if(show_hud)
|
if(show_hud)
|
||||||
{
|
{
|
||||||
|
v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
|
||||||
|
u32 selectionbox_color_r = rangelim(myround(selectionbox_color.X), 0, 255);
|
||||||
|
u32 selectionbox_color_g = rangelim(myround(selectionbox_color.Y), 0, 255);
|
||||||
|
u32 selectionbox_color_b = rangelim(myround(selectionbox_color.Z), 0, 255);
|
||||||
|
|
||||||
for(std::vector<aabb3f>::const_iterator
|
for(std::vector<aabb3f>::const_iterator
|
||||||
i = hilightboxes.begin();
|
i = hilightboxes.begin();
|
||||||
i != hilightboxes.end(); i++)
|
i != hilightboxes.end(); i++)
|
||||||
|
@ -2929,7 +2934,7 @@ void the_game(
|
||||||
<<" max="
|
<<" max="
|
||||||
<<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
|
<<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
driver->draw3DBox(*i, video::SColor(255,0,0,0));
|
driver->draw3DBox(*i, video::SColor(255,selectionbox_color_r,selectionbox_color_g,selectionbox_color_b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2962,12 +2967,18 @@ void the_game(
|
||||||
*/
|
*/
|
||||||
if(show_hud)
|
if(show_hud)
|
||||||
{
|
{
|
||||||
|
v3f crosshair_color = g_settings->getV3F("crosshair_color");
|
||||||
|
u32 crosshair_color_r = rangelim(myround(crosshair_color.X), 0, 255);
|
||||||
|
u32 crosshair_color_g = rangelim(myround(crosshair_color.Y), 0, 255);
|
||||||
|
u32 crosshair_color_b = rangelim(myround(crosshair_color.Z), 0, 255);
|
||||||
|
u32 crosshair_alpha = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
|
||||||
|
|
||||||
driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
|
driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
|
||||||
displaycenter + core::vector2d<s32>(10,0),
|
displaycenter + core::vector2d<s32>(10,0),
|
||||||
video::SColor(255,255,255,255));
|
video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
|
||||||
driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),
|
driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),
|
||||||
displaycenter + core::vector2d<s32>(0,10),
|
displaycenter + core::vector2d<s32>(0,10),
|
||||||
video::SColor(255,255,255,255));
|
video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // timer
|
} // timer
|
||||||
|
|
|
@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
using namespace irr;
|
using namespace irr;
|
||||||
|
|
||||||
|
// Irrlicht 1.8+ defines 64bit unsigned symbol in irrTypes.h
|
||||||
|
#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// Windows
|
// Windows
|
||||||
typedef unsigned long long u64;
|
typedef unsigned long long u64;
|
||||||
|
@ -33,6 +35,7 @@ using namespace irr;
|
||||||
typedef uint64_t u64;
|
typedef uint64_t u64;
|
||||||
//typedef unsigned long long u64;
|
//typedef unsigned long long u64;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -260,7 +260,7 @@ KeyPress::KeyPress(const char *name)
|
||||||
try {
|
try {
|
||||||
Key = keyname_to_keycode(name);
|
Key = keyname_to_keycode(name);
|
||||||
m_name = name;
|
m_name = name;
|
||||||
if (strlen(name) > 8) {
|
if (strlen(name) > 8 && strncmp(name, "KEY_KEY_", 8) == 0) {
|
||||||
int chars_read = mbtowc(&Char, name + 8, 1);
|
int chars_read = mbtowc(&Char, name + 8, 1);
|
||||||
assert (chars_read == 1 && "unexpected multibyte character");
|
assert (chars_read == 1 && "unexpected multibyte character");
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -399,13 +399,13 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
// Whether superspeed mode is used or not
|
// Whether superspeed mode is used or not
|
||||||
bool superspeed = false;
|
bool superspeed = false;
|
||||||
|
|
||||||
|
// Old descend control
|
||||||
|
if(g_settings->getBool("aux1_descends"))
|
||||||
|
{
|
||||||
// If free movement and fast movement, always move fast
|
// If free movement and fast movement, always move fast
|
||||||
if(free_move && fast_move)
|
if(free_move && fast_move)
|
||||||
superspeed = true;
|
superspeed = true;
|
||||||
|
|
||||||
// Old descend control
|
|
||||||
if(g_settings->getBool("aux1_descends"))
|
|
||||||
{
|
|
||||||
// Auxiliary button 1 (E)
|
// Auxiliary button 1 (E)
|
||||||
if(control.aux1)
|
if(control.aux1)
|
||||||
{
|
{
|
||||||
|
@ -440,10 +440,9 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
// Auxiliary button 1 (E)
|
// Auxiliary button 1 (E)
|
||||||
if(control.aux1)
|
if(control.aux1)
|
||||||
{
|
{
|
||||||
if(!free_move && !is_climbing)
|
if(!is_climbing)
|
||||||
{
|
{
|
||||||
// If not free movement but fast is allowed, aux1 is
|
// aux1 is "Turbo button"
|
||||||
// "Turbo button"
|
|
||||||
if(fast_move)
|
if(fast_move)
|
||||||
superspeed = true;
|
superspeed = true;
|
||||||
}
|
}
|
||||||
|
@ -455,7 +454,7 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
{
|
{
|
||||||
// In free movement mode, sneak descends
|
// In free movement mode, sneak descends
|
||||||
v3f speed = getSpeed();
|
v3f speed = getSpeed();
|
||||||
if(fast_move)
|
if(fast_move && control.aux1)
|
||||||
speed.Y = -20*BS;
|
speed.Y = -20*BS;
|
||||||
else
|
else
|
||||||
speed.Y = -walkspeed_max;
|
speed.Y = -walkspeed_max;
|
||||||
|
@ -497,10 +496,20 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
if(free_move)
|
if(free_move)
|
||||||
{
|
{
|
||||||
v3f speed = getSpeed();
|
v3f speed = getSpeed();
|
||||||
|
|
||||||
|
if(g_settings->getBool("aux1_descends"))
|
||||||
|
{
|
||||||
if(fast_move)
|
if(fast_move)
|
||||||
speed.Y = 20*BS;
|
speed.Y = 20*BS;
|
||||||
else
|
else
|
||||||
speed.Y = walkspeed_max;
|
speed.Y = walkspeed_max;
|
||||||
|
} else {
|
||||||
|
if(fast_move && control.aux1)
|
||||||
|
speed.Y = 20*BS;
|
||||||
|
else
|
||||||
|
speed.Y = walkspeed_max;
|
||||||
|
}
|
||||||
|
|
||||||
setSpeed(speed);
|
setSpeed(speed);
|
||||||
}
|
}
|
||||||
else if(m_can_jump)
|
else if(m_can_jump)
|
||||||
|
@ -548,7 +557,7 @@ void LocalPlayer::applyControl(float dtime)
|
||||||
f32 inc = walk_acceleration * BS * dtime;
|
f32 inc = walk_acceleration * BS * dtime;
|
||||||
|
|
||||||
// Faster acceleration if fast and free movement
|
// Faster acceleration if fast and free movement
|
||||||
if(free_move && fast_move)
|
if(free_move && fast_move && superspeed)
|
||||||
inc = walk_acceleration * BS * dtime * 10;
|
inc = walk_acceleration * BS * dtime * 10;
|
||||||
|
|
||||||
// Accelerate to target speed with maximum increment
|
// Accelerate to target speed with maximum increment
|
||||||
|
|
170
src/mapgen.cpp
170
src/mapgen.cpp
|
@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "voxelalgorithms.h"
|
#include "voxelalgorithms.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
#include "main.h" // For g_profiler
|
#include "main.h" // For g_profiler
|
||||||
|
#include "treegen.h"
|
||||||
|
|
||||||
namespace mapgen
|
namespace mapgen
|
||||||
{
|
{
|
||||||
|
@ -120,174 +121,7 @@ static s16 find_stone_level(VoxelManipulator &vmanip, v2s16 p2d,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
|
|
||||||
bool is_apple_tree, INodeDefManager *ndef)
|
|
||||||
{
|
|
||||||
MapNode treenode(ndef->getId("mapgen_tree"));
|
|
||||||
MapNode leavesnode(ndef->getId("mapgen_leaves"));
|
|
||||||
MapNode applenode(ndef->getId("mapgen_apple"));
|
|
||||||
|
|
||||||
s16 trunk_h = myrand_range(4, 5);
|
|
||||||
v3s16 p1 = p0;
|
|
||||||
for(s16 ii=0; ii<trunk_h; ii++)
|
|
||||||
{
|
|
||||||
if(vmanip.m_area.contains(p1))
|
|
||||||
if(ii == 0 || vmanip.getNodeNoExNoEmerge(p1).getContent() == CONTENT_AIR)
|
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
|
|
||||||
p1.Y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// p1 is now the last piece of the trunk
|
|
||||||
p1.Y -= 1;
|
|
||||||
|
|
||||||
VoxelArea leaves_a(v3s16(-2,-1,-2), v3s16(2,2,2));
|
|
||||||
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
|
||||||
Buffer<u8> leaves_d(leaves_a.getVolume());
|
|
||||||
for(s32 i=0; i<leaves_a.getVolume(); i++)
|
|
||||||
leaves_d[i] = 0;
|
|
||||||
|
|
||||||
// Force leaves at near the end of the trunk
|
|
||||||
{
|
|
||||||
s16 d = 1;
|
|
||||||
for(s16 z=-d; z<=d; z++)
|
|
||||||
for(s16 y=-d; y<=d; y++)
|
|
||||||
for(s16 x=-d; x<=d; x++)
|
|
||||||
{
|
|
||||||
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add leaves randomly
|
|
||||||
for(u32 iii=0; iii<7; iii++)
|
|
||||||
{
|
|
||||||
s16 d = 1;
|
|
||||||
|
|
||||||
v3s16 p(
|
|
||||||
myrand_range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
|
|
||||||
myrand_range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
|
|
||||||
myrand_range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
|
|
||||||
);
|
|
||||||
|
|
||||||
for(s16 z=0; z<=d; z++)
|
|
||||||
for(s16 y=0; y<=d; y++)
|
|
||||||
for(s16 x=0; x<=d; x++)
|
|
||||||
{
|
|
||||||
leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blit leaves to vmanip
|
|
||||||
for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
|
|
||||||
for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
|
|
||||||
for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
|
|
||||||
{
|
|
||||||
v3s16 p(x,y,z);
|
|
||||||
p += p1;
|
|
||||||
if(vmanip.m_area.contains(p) == false)
|
|
||||||
continue;
|
|
||||||
u32 vi = vmanip.m_area.index(p);
|
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
|
||||||
continue;
|
|
||||||
u32 i = leaves_a.index(x,y,z);
|
|
||||||
if(leaves_d[i] == 1) {
|
|
||||||
bool is_apple = myrand_range(0,99) < 10;
|
|
||||||
if(is_apple_tree && is_apple) {
|
|
||||||
vmanip.m_data[vi] = applenode;
|
|
||||||
} else {
|
|
||||||
vmanip.m_data[vi] = leavesnode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
|
|
||||||
INodeDefManager *ndef)
|
|
||||||
{
|
|
||||||
MapNode treenode(ndef->getId("mapgen_jungletree"));
|
|
||||||
MapNode leavesnode(ndef->getId("mapgen_leaves"));
|
|
||||||
|
|
||||||
for(s16 x=-1; x<=1; x++)
|
|
||||||
for(s16 z=-1; z<=1; z++)
|
|
||||||
{
|
|
||||||
if(myrand_range(0, 2) == 0)
|
|
||||||
continue;
|
|
||||||
v3s16 p1 = p0 + v3s16(x,0,z);
|
|
||||||
v3s16 p2 = p0 + v3s16(x,-1,z);
|
|
||||||
if(vmanip.m_area.contains(p2)
|
|
||||||
&& vmanip.m_data[vmanip.m_area.index(p2)] == CONTENT_AIR)
|
|
||||||
vmanip.m_data[vmanip.m_area.index(p2)] = treenode;
|
|
||||||
else if(vmanip.m_area.contains(p1))
|
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
|
|
||||||
}
|
|
||||||
|
|
||||||
s16 trunk_h = myrand_range(8, 12);
|
|
||||||
v3s16 p1 = p0;
|
|
||||||
for(s16 ii=0; ii<trunk_h; ii++)
|
|
||||||
{
|
|
||||||
if(vmanip.m_area.contains(p1))
|
|
||||||
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
|
|
||||||
p1.Y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// p1 is now the last piece of the trunk
|
|
||||||
p1.Y -= 1;
|
|
||||||
|
|
||||||
VoxelArea leaves_a(v3s16(-3,-2,-3), v3s16(3,2,3));
|
|
||||||
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
|
||||||
Buffer<u8> leaves_d(leaves_a.getVolume());
|
|
||||||
for(s32 i=0; i<leaves_a.getVolume(); i++)
|
|
||||||
leaves_d[i] = 0;
|
|
||||||
|
|
||||||
// Force leaves at near the end of the trunk
|
|
||||||
{
|
|
||||||
s16 d = 1;
|
|
||||||
for(s16 z=-d; z<=d; z++)
|
|
||||||
for(s16 y=-d; y<=d; y++)
|
|
||||||
for(s16 x=-d; x<=d; x++)
|
|
||||||
{
|
|
||||||
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add leaves randomly
|
|
||||||
for(u32 iii=0; iii<30; iii++)
|
|
||||||
{
|
|
||||||
s16 d = 1;
|
|
||||||
|
|
||||||
v3s16 p(
|
|
||||||
myrand_range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
|
|
||||||
myrand_range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
|
|
||||||
myrand_range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
|
|
||||||
);
|
|
||||||
|
|
||||||
for(s16 z=0; z<=d; z++)
|
|
||||||
for(s16 y=0; y<=d; y++)
|
|
||||||
for(s16 x=0; x<=d; x++)
|
|
||||||
{
|
|
||||||
leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blit leaves to vmanip
|
|
||||||
for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
|
|
||||||
for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
|
|
||||||
for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
|
|
||||||
{
|
|
||||||
v3s16 p(x,y,z);
|
|
||||||
p += p1;
|
|
||||||
if(vmanip.m_area.contains(p) == false)
|
|
||||||
continue;
|
|
||||||
u32 vi = vmanip.m_area.index(p);
|
|
||||||
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
|
||||||
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
|
||||||
continue;
|
|
||||||
u32 i = leaves_a.index(x,y,z);
|
|
||||||
if(leaves_d[i] == 1)
|
|
||||||
vmanip.m_data[vi] = leavesnode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void make_papyrus(VoxelManipulator &vmanip, v3s16 p0,
|
static void make_papyrus(VoxelManipulator &vmanip, v3s16 p0,
|
||||||
INodeDefManager *ndef)
|
INodeDefManager *ndef)
|
||||||
|
@ -2239,7 +2073,7 @@ void make_block(BlockMakeData *data)
|
||||||
}
|
}
|
||||||
p.Y++;
|
p.Y++;
|
||||||
// Make a tree
|
// Make a tree
|
||||||
make_tree(vmanip, p, false, ndef);
|
treegen::make_tree(vmanip, p, false, ndef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,6 @@ namespace mapgen
|
||||||
// Main map generation routine
|
// Main map generation routine
|
||||||
void make_block(BlockMakeData *data);
|
void make_block(BlockMakeData *data);
|
||||||
|
|
||||||
// Add a tree
|
|
||||||
void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
|
|
||||||
bool is_apple_tree, INodeDefManager *ndef);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These are used by FarMesh
|
These are used by FarMesh
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,6 +48,7 @@ extern "C" {
|
||||||
#include "noise.h" // PseudoRandom for LuaPseudoRandom
|
#include "noise.h" // PseudoRandom for LuaPseudoRandom
|
||||||
#include "util/pointedthing.h"
|
#include "util/pointedthing.h"
|
||||||
#include "rollback.h"
|
#include "rollback.h"
|
||||||
|
#include "treegen.h"
|
||||||
|
|
||||||
static void stackDump(lua_State *L, std::ostream &o)
|
static void stackDump(lua_State *L, std::ostream &o)
|
||||||
{
|
{
|
||||||
|
@ -4004,6 +4005,45 @@ private:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_spawn_tree(lua_State *L)
|
||||||
|
{
|
||||||
|
EnvRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
v3s16 p0 = read_v3s16(L, 2);
|
||||||
|
|
||||||
|
treegen::TreeDef tree_def;
|
||||||
|
std::string trunk,leaves,fruit;
|
||||||
|
INodeDefManager *ndef = env->getGameDef()->ndef();
|
||||||
|
|
||||||
|
if(lua_istable(L, 3))
|
||||||
|
{
|
||||||
|
getstringfield(L, 3, "axiom", tree_def.initial_axiom);
|
||||||
|
getstringfield(L, 3, "rules_a", tree_def.rules_a);
|
||||||
|
getstringfield(L, 3, "rules_b", tree_def.rules_b);
|
||||||
|
getstringfield(L, 3, "rules_c", tree_def.rules_a);
|
||||||
|
getstringfield(L, 3, "rules_d", tree_def.rules_b);
|
||||||
|
getstringfield(L, 3, "trunk", trunk);
|
||||||
|
tree_def.trunknode=ndef->getId(trunk);
|
||||||
|
getstringfield(L, 3, "leaves", leaves);
|
||||||
|
tree_def.leavesnode=ndef->getId(leaves);
|
||||||
|
getintfield(L, 3, "angle", tree_def.angle);
|
||||||
|
getintfield(L, 3, "iterations", tree_def.iterations);
|
||||||
|
getintfield(L, 3, "random_level", tree_def.iterations_random_level);
|
||||||
|
getboolfield(L, 3, "thin_trunks", tree_def.thin_trunks);
|
||||||
|
getboolfield(L, 3, "fruit_tree", tree_def.fruit_tree);
|
||||||
|
if (tree_def.fruit_tree)
|
||||||
|
{
|
||||||
|
getstringfield(L, 3, "fruit", fruit);
|
||||||
|
tree_def.fruitnode=ndef->getId(fruit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
treegen::spawn_ltree (env, p0, ndef, tree_def);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EnvRef(ServerEnvironment *env):
|
EnvRef(ServerEnvironment *env):
|
||||||
m_env(env)
|
m_env(env)
|
||||||
|
@ -4086,6 +4126,7 @@ const luaL_reg EnvRef::methods[] = {
|
||||||
method(EnvRef, find_nodes_in_area),
|
method(EnvRef, find_nodes_in_area),
|
||||||
method(EnvRef, get_perlin),
|
method(EnvRef, get_perlin),
|
||||||
method(EnvRef, clear_objects),
|
method(EnvRef, clear_objects),
|
||||||
|
method(EnvRef, spawn_tree),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,520 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>,
|
||||||
|
2012 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl>
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "irr_v3d.h"
|
||||||
|
#include <stack>
|
||||||
|
#include "util/numeric.h"
|
||||||
|
#include "util/mathconstants.h"
|
||||||
|
#include "noise.h"
|
||||||
|
#include "map.h"
|
||||||
|
#include "environment.h"
|
||||||
|
#include "nodedef.h"
|
||||||
|
#include "treegen.h"
|
||||||
|
|
||||||
|
namespace treegen
|
||||||
|
{
|
||||||
|
|
||||||
|
void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
|
||||||
|
bool is_apple_tree, INodeDefManager *ndef)
|
||||||
|
{
|
||||||
|
MapNode treenode(ndef->getId("mapgen_tree"));
|
||||||
|
MapNode leavesnode(ndef->getId("mapgen_leaves"));
|
||||||
|
MapNode applenode(ndef->getId("mapgen_apple"));
|
||||||
|
|
||||||
|
s16 trunk_h = myrand_range(4, 5);
|
||||||
|
v3s16 p1 = p0;
|
||||||
|
for(s16 ii=0; ii<trunk_h; ii++)
|
||||||
|
{
|
||||||
|
if(vmanip.m_area.contains(p1))
|
||||||
|
if(ii == 0 || vmanip.getNodeNoExNoEmerge(p1).getContent() == CONTENT_AIR)
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
|
||||||
|
p1.Y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// p1 is now the last piece of the trunk
|
||||||
|
p1.Y -= 1;
|
||||||
|
|
||||||
|
VoxelArea leaves_a(v3s16(-2,-1,-2), v3s16(2,2,2));
|
||||||
|
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
||||||
|
Buffer<u8> leaves_d(leaves_a.getVolume());
|
||||||
|
for(s32 i=0; i<leaves_a.getVolume(); i++)
|
||||||
|
leaves_d[i] = 0;
|
||||||
|
|
||||||
|
// Force leaves at near the end of the trunk
|
||||||
|
{
|
||||||
|
s16 d = 1;
|
||||||
|
for(s16 z=-d; z<=d; z++)
|
||||||
|
for(s16 y=-d; y<=d; y++)
|
||||||
|
for(s16 x=-d; x<=d; x++)
|
||||||
|
{
|
||||||
|
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add leaves randomly
|
||||||
|
for(u32 iii=0; iii<7; iii++)
|
||||||
|
{
|
||||||
|
s16 d = 1;
|
||||||
|
|
||||||
|
v3s16 p(
|
||||||
|
myrand_range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
|
||||||
|
myrand_range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
|
||||||
|
myrand_range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
|
||||||
|
);
|
||||||
|
|
||||||
|
for(s16 z=0; z<=d; z++)
|
||||||
|
for(s16 y=0; y<=d; y++)
|
||||||
|
for(s16 x=0; x<=d; x++)
|
||||||
|
{
|
||||||
|
leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blit leaves to vmanip
|
||||||
|
for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
|
||||||
|
for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
|
||||||
|
for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
|
||||||
|
{
|
||||||
|
v3s16 p(x,y,z);
|
||||||
|
p += p1;
|
||||||
|
if(vmanip.m_area.contains(p) == false)
|
||||||
|
continue;
|
||||||
|
u32 vi = vmanip.m_area.index(p);
|
||||||
|
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
|
continue;
|
||||||
|
u32 i = leaves_a.index(x,y,z);
|
||||||
|
if(leaves_d[i] == 1) {
|
||||||
|
bool is_apple = myrand_range(0,99) < 10;
|
||||||
|
if(is_apple_tree && is_apple) {
|
||||||
|
vmanip.m_data[vi] = applenode;
|
||||||
|
} else {
|
||||||
|
vmanip.m_data[vi] = leavesnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// L-System tree LUA spawner
|
||||||
|
void spawn_ltree (ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition)
|
||||||
|
{
|
||||||
|
ServerMap *map = &env->getServerMap();
|
||||||
|
core::map<v3s16, MapBlock*> modified_blocks;
|
||||||
|
ManualMapVoxelManipulator vmanip(map);
|
||||||
|
v3s16 tree_blockp = getNodeBlockPos(p0);
|
||||||
|
vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
|
||||||
|
make_ltree (vmanip, p0, ndef, tree_definition);
|
||||||
|
vmanip.blitBackAll(&modified_blocks);
|
||||||
|
|
||||||
|
// update lighting
|
||||||
|
core::map<v3s16, MapBlock*> lighting_modified_blocks;
|
||||||
|
for(core::map<v3s16, MapBlock*>::Iterator
|
||||||
|
i = modified_blocks.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue());
|
||||||
|
}
|
||||||
|
map->updateLighting(lighting_modified_blocks, modified_blocks);
|
||||||
|
// Send a MEET_OTHER event
|
||||||
|
MapEditEvent event;
|
||||||
|
event.type = MEET_OTHER;
|
||||||
|
for(core::map<v3s16, MapBlock*>::Iterator
|
||||||
|
i = modified_blocks.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
v3s16 p = i.getNode()->getKey();
|
||||||
|
event.modified_blocks.insert(p, true);
|
||||||
|
}
|
||||||
|
map->dispatchEvent(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//L-System tree generator
|
||||||
|
void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *ndef,
|
||||||
|
TreeDef tree_definition)
|
||||||
|
{
|
||||||
|
MapNode dirtnode(ndef->getId("mapgen_dirt"));
|
||||||
|
|
||||||
|
// chance of inserting abcd rules
|
||||||
|
double prop_a = 9;
|
||||||
|
double prop_b = 8;
|
||||||
|
double prop_c = 7;
|
||||||
|
double prop_d = 6;
|
||||||
|
|
||||||
|
//randomize tree growth level, minimum=2
|
||||||
|
s16 iterations = tree_definition.iterations;
|
||||||
|
if (tree_definition.iterations_random_level>0)
|
||||||
|
iterations -= myrand_range(0,tree_definition.iterations_random_level);
|
||||||
|
if (iterations<2)
|
||||||
|
iterations=2;
|
||||||
|
|
||||||
|
s16 MAX_ANGLE_OFFSET = 5;
|
||||||
|
double angle_in_radians = (double)tree_definition.angle*M_PI/180;
|
||||||
|
double angleOffset_in_radians = (s16)(myrand_range(0,1)%MAX_ANGLE_OFFSET)*M_PI/180;
|
||||||
|
|
||||||
|
//initialize rotation matrix, position and stacks for branches
|
||||||
|
core::matrix4 rotation;
|
||||||
|
rotation=setRotationAxisRadians(rotation, M_PI/2,v3f(0,0,1));
|
||||||
|
v3f position = v3f(0,0,0);
|
||||||
|
std::stack <core::matrix4> stack_orientation;
|
||||||
|
std::stack <v3f> stack_position;
|
||||||
|
|
||||||
|
//generate axiom
|
||||||
|
std::string axiom = tree_definition.initial_axiom;
|
||||||
|
for(s16 i=0; i<iterations; i++)
|
||||||
|
{
|
||||||
|
std::string temp = "";
|
||||||
|
for(s16 j=0; j<(s16)axiom.size(); j++)
|
||||||
|
{
|
||||||
|
char axiom_char = axiom.at(j);
|
||||||
|
switch (axiom_char)
|
||||||
|
{
|
||||||
|
case 'A':
|
||||||
|
temp+=tree_definition.rules_a;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
temp+=tree_definition.rules_b;
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
temp+=tree_definition.rules_c;
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
temp+=tree_definition.rules_d;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
if (prop_a >= myrand_range(1,10))
|
||||||
|
temp+=tree_definition.rules_a;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
if (prop_b >= myrand_range(1,10))
|
||||||
|
temp+=tree_definition.rules_b;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
if (prop_c >= myrand_range(1,10))
|
||||||
|
temp+=tree_definition.rules_c;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
if (prop_d >= myrand_range(1,10))
|
||||||
|
temp+=tree_definition.rules_d;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
temp+=axiom_char;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axiom=temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//make sure tree is not floating in the air
|
||||||
|
if (tree_definition.thin_trunks == false)
|
||||||
|
{
|
||||||
|
make_tree_node_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode);
|
||||||
|
make_tree_node_placement(vmanip,v3f(p0.X+position.X-1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode);
|
||||||
|
make_tree_node_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y-1,p0.Z+position.Z+1),dirtnode);
|
||||||
|
make_tree_node_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y-1,p0.Z+position.Z-1),dirtnode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build tree out of generated axiom
|
||||||
|
|
||||||
|
Key for Special L-System Symbols used in Axioms
|
||||||
|
|
||||||
|
G - move forward one unit with the pin down
|
||||||
|
F - move forward one unit with the pin up
|
||||||
|
A - replace with rules set A
|
||||||
|
B - replace with rules set B
|
||||||
|
C - replace with rules set C
|
||||||
|
D - replace with rules set D
|
||||||
|
a - replace with rules set A, chance 90%
|
||||||
|
b - replace with rules set B, chance 80%
|
||||||
|
c - replace with rules set C, chance 70%
|
||||||
|
d - replace with rules set D, chance 60%
|
||||||
|
+ - yaw the turtle right by angle degrees
|
||||||
|
- - yaw the turtle left by angle degrees
|
||||||
|
& - pitch the turtle down by angle degrees
|
||||||
|
^ - pitch the turtle up by angle degrees
|
||||||
|
/ - roll the turtle to the right by angle degrees
|
||||||
|
* - roll the turtle to the left by angle degrees
|
||||||
|
[ - save in stack current state info
|
||||||
|
] - recover from stack state info
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
s16 x,y,z;
|
||||||
|
for(s16 i=0; i<(s16)axiom.size(); i++)
|
||||||
|
{
|
||||||
|
char axiom_char = axiom.at(i);
|
||||||
|
core::matrix4 temp_rotation;
|
||||||
|
temp_rotation.makeIdentity();
|
||||||
|
v3f dir;
|
||||||
|
switch (axiom_char)
|
||||||
|
{
|
||||||
|
case 'G':
|
||||||
|
dir = v3f(-1,0,0);
|
||||||
|
dir = transposeMatrix(rotation,dir);
|
||||||
|
position+=dir;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
|
||||||
|
if (tree_definition.thin_trunks == false)
|
||||||
|
{
|
||||||
|
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
|
||||||
|
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X-1,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
|
||||||
|
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z+1),tree_definition);
|
||||||
|
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z-1),tree_definition);
|
||||||
|
}
|
||||||
|
if (stack_orientation.empty() == false)
|
||||||
|
{
|
||||||
|
s16 size = 1;
|
||||||
|
for(x=-size; x<size+1; x++)
|
||||||
|
for(y=-size; y<size+1; y++)
|
||||||
|
for(z=-size; z<size+1; z++)
|
||||||
|
if (abs(x) == size && abs(y) == size && abs(z) == size)
|
||||||
|
{
|
||||||
|
make_tree_leaves_placement(vmanip,v3f(p0.X+position.X+x+1,p0.Y+position.Y+y,p0.Z+position.Z+z),tree_definition);
|
||||||
|
make_tree_leaves_placement(vmanip,v3f(p0.X+position.X+x-1,p0.Y+position.Y+y,p0.Z+position.Z+z),tree_definition);
|
||||||
|
make_tree_leaves_placement(vmanip,v3f(p0.X+position.X+x,p0.Y+position.Y+y,p0.Z+position.Z+z+1),tree_definition);
|
||||||
|
make_tree_leaves_placement(vmanip,v3f(p0.X+position.X+x,p0.Y+position.Y+y,p0.Z+position.Z+z-1),tree_definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir = v3f(1,0,0);
|
||||||
|
dir = transposeMatrix(rotation,dir);
|
||||||
|
position+=dir;
|
||||||
|
break;
|
||||||
|
// turtle commands
|
||||||
|
case '[':
|
||||||
|
stack_orientation.push(rotation);
|
||||||
|
stack_position.push(position);
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
rotation=stack_orientation.top();
|
||||||
|
stack_orientation.pop();
|
||||||
|
position=stack_position.top();
|
||||||
|
stack_position.pop();
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
temp_rotation.makeIdentity();
|
||||||
|
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,0,1));
|
||||||
|
rotation*=temp_rotation;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
temp_rotation.makeIdentity();
|
||||||
|
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,0,-1));
|
||||||
|
rotation*=temp_rotation;
|
||||||
|
break;
|
||||||
|
case '&':
|
||||||
|
temp_rotation.makeIdentity();
|
||||||
|
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,1,0));
|
||||||
|
rotation*=temp_rotation;
|
||||||
|
break;
|
||||||
|
case '^':
|
||||||
|
temp_rotation.makeIdentity();
|
||||||
|
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians+angleOffset_in_radians,v3f(0,-1,0));
|
||||||
|
rotation*=temp_rotation;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
temp_rotation.makeIdentity();
|
||||||
|
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians,v3f(1,0,0));
|
||||||
|
rotation*=temp_rotation;
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
temp_rotation.makeIdentity();
|
||||||
|
temp_rotation=setRotationAxisRadians(temp_rotation, angle_in_radians,v3f(-1,0,0));
|
||||||
|
rotation*=temp_rotation;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void make_tree_node_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
|
||||||
|
MapNode node)
|
||||||
|
{
|
||||||
|
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
||||||
|
if(vmanip.m_area.contains(p1) == false)
|
||||||
|
return;
|
||||||
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
|
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
|
return;
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void make_tree_trunk_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
|
||||||
|
TreeDef &tree_definition)
|
||||||
|
{
|
||||||
|
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
||||||
|
if(vmanip.m_area.contains(p1) == false)
|
||||||
|
return;
|
||||||
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
|
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
|
return;
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.trunknode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void make_tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
|
||||||
|
TreeDef &tree_definition)
|
||||||
|
{
|
||||||
|
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
|
||||||
|
if(vmanip.m_area.contains(p1) == false)
|
||||||
|
return;
|
||||||
|
u32 vi = vmanip.m_area.index(p1);
|
||||||
|
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
|
return;
|
||||||
|
if (tree_definition.fruit_tree)
|
||||||
|
{
|
||||||
|
if (myrand_range(1,100) > 90+tree_definition.iterations)
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode;
|
||||||
|
else
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.leavesnode;
|
||||||
|
}
|
||||||
|
else if (myrand_range(1,100) > 20)
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.leavesnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis)
|
||||||
|
{
|
||||||
|
double c = cos(angle);
|
||||||
|
double s = sin(angle);
|
||||||
|
double t = 1.0 - c;
|
||||||
|
|
||||||
|
double tx = t * axis.X;
|
||||||
|
double ty = t * axis.Y;
|
||||||
|
double tz = t * axis.Z;
|
||||||
|
double sx = s * axis.X;
|
||||||
|
double sy = s * axis.Y;
|
||||||
|
double sz = s * axis.Z;
|
||||||
|
|
||||||
|
M[0] = tx * axis.X + c;
|
||||||
|
M[1] = tx * axis.Y + sz;
|
||||||
|
M[2] = tx * axis.Z - sy;
|
||||||
|
|
||||||
|
M[4] = ty * axis.X - sz;
|
||||||
|
M[5] = ty * axis.Y + c;
|
||||||
|
M[6] = ty * axis.Z + sx;
|
||||||
|
|
||||||
|
M[8] = tz * axis.X + sy;
|
||||||
|
M[9] = tz * axis.Y - sx;
|
||||||
|
M[10] = tz * axis.Z + c;
|
||||||
|
return M;
|
||||||
|
}
|
||||||
|
|
||||||
|
v3f transposeMatrix(irr::core::matrix4 M, v3f v)
|
||||||
|
{
|
||||||
|
v3f translated;
|
||||||
|
double x = M[0] * v.X + M[4] * v.Y + M[8] * v.Z +M[12];
|
||||||
|
double y = M[1] * v.X + M[5] * v.Y + M[9] * v.Z +M[13];
|
||||||
|
double z = M[2] * v.X + M[6] * v.Y + M[10] * v.Z +M[14];
|
||||||
|
translated.X=x;
|
||||||
|
translated.Y=y;
|
||||||
|
translated.Z=z;
|
||||||
|
return translated;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
|
||||||
|
INodeDefManager *ndef)
|
||||||
|
{
|
||||||
|
MapNode treenode(ndef->getId("mapgen_jungletree"));
|
||||||
|
MapNode leavesnode(ndef->getId("mapgen_leaves"));
|
||||||
|
|
||||||
|
for(s16 x=-1; x<=1; x++)
|
||||||
|
for(s16 z=-1; z<=1; z++)
|
||||||
|
{
|
||||||
|
if(myrand_range(0, 2) == 0)
|
||||||
|
continue;
|
||||||
|
v3s16 p1 = p0 + v3s16(x,0,z);
|
||||||
|
v3s16 p2 = p0 + v3s16(x,-1,z);
|
||||||
|
if(vmanip.m_area.contains(p2)
|
||||||
|
&& vmanip.m_data[vmanip.m_area.index(p2)] == CONTENT_AIR)
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p2)] = treenode;
|
||||||
|
else if(vmanip.m_area.contains(p1))
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 trunk_h = myrand_range(8, 12);
|
||||||
|
v3s16 p1 = p0;
|
||||||
|
for(s16 ii=0; ii<trunk_h; ii++)
|
||||||
|
{
|
||||||
|
if(vmanip.m_area.contains(p1))
|
||||||
|
vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
|
||||||
|
p1.Y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// p1 is now the last piece of the trunk
|
||||||
|
p1.Y -= 1;
|
||||||
|
|
||||||
|
VoxelArea leaves_a(v3s16(-3,-2,-3), v3s16(3,2,3));
|
||||||
|
//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
|
||||||
|
Buffer<u8> leaves_d(leaves_a.getVolume());
|
||||||
|
for(s32 i=0; i<leaves_a.getVolume(); i++)
|
||||||
|
leaves_d[i] = 0;
|
||||||
|
|
||||||
|
// Force leaves at near the end of the trunk
|
||||||
|
{
|
||||||
|
s16 d = 1;
|
||||||
|
for(s16 z=-d; z<=d; z++)
|
||||||
|
for(s16 y=-d; y<=d; y++)
|
||||||
|
for(s16 x=-d; x<=d; x++)
|
||||||
|
{
|
||||||
|
leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add leaves randomly
|
||||||
|
for(u32 iii=0; iii<30; iii++)
|
||||||
|
{
|
||||||
|
s16 d = 1;
|
||||||
|
|
||||||
|
v3s16 p(
|
||||||
|
myrand_range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
|
||||||
|
myrand_range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
|
||||||
|
myrand_range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
|
||||||
|
);
|
||||||
|
|
||||||
|
for(s16 z=0; z<=d; z++)
|
||||||
|
for(s16 y=0; y<=d; y++)
|
||||||
|
for(s16 x=0; x<=d; x++)
|
||||||
|
{
|
||||||
|
leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blit leaves to vmanip
|
||||||
|
for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
|
||||||
|
for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
|
||||||
|
for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
|
||||||
|
{
|
||||||
|
v3s16 p(x,y,z);
|
||||||
|
p += p1;
|
||||||
|
if(vmanip.m_area.contains(p) == false)
|
||||||
|
continue;
|
||||||
|
u32 vi = vmanip.m_area.index(p);
|
||||||
|
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
|
||||||
|
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
|
||||||
|
continue;
|
||||||
|
u32 i = leaves_a.index(x,y,z);
|
||||||
|
if(leaves_d[i] == 1)
|
||||||
|
vmanip.m_data[vi] = leavesnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}; // namespace treegen
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
Minetest-c55
|
||||||
|
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>,
|
||||||
|
2012 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl>
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TREEGEN_HEADER
|
||||||
|
#define TREEGEN_HEADER
|
||||||
|
|
||||||
|
#include <matrix4.h>
|
||||||
|
|
||||||
|
class ManualMapVoxelManipulator;
|
||||||
|
class INodeDefManager;
|
||||||
|
|
||||||
|
|
||||||
|
namespace treegen
|
||||||
|
{
|
||||||
|
|
||||||
|
struct TreeDef
|
||||||
|
{
|
||||||
|
std::string initial_axiom;
|
||||||
|
std::string rules_a;
|
||||||
|
std::string rules_b;
|
||||||
|
std::string rules_c;
|
||||||
|
std::string rules_d;
|
||||||
|
MapNode trunknode;
|
||||||
|
MapNode leavesnode;
|
||||||
|
int angle;
|
||||||
|
int iterations;
|
||||||
|
int iterations_random_level;
|
||||||
|
bool thin_trunks;
|
||||||
|
bool fruit_tree;
|
||||||
|
MapNode fruitnode;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Add default tree
|
||||||
|
void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
|
||||||
|
bool is_apple_tree, INodeDefManager *ndef);
|
||||||
|
|
||||||
|
// Add L-Systems tree (used by engine)
|
||||||
|
void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *ndef,
|
||||||
|
TreeDef tree_definition);
|
||||||
|
// Spawn L-systems tree from LUA
|
||||||
|
void spawn_ltree (ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeDef tree_definition);
|
||||||
|
|
||||||
|
// L-System tree gen helper functions
|
||||||
|
void make_tree_node_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
|
||||||
|
MapNode node);
|
||||||
|
void make_tree_trunk_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
|
||||||
|
TreeDef &tree_definition);
|
||||||
|
void make_tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
|
||||||
|
TreeDef &tree_definition);
|
||||||
|
irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle,v3f axis);
|
||||||
|
|
||||||
|
v3f transposeMatrix(irr::core::matrix4 M ,v3f v);
|
||||||
|
|
||||||
|
}; // namespace treegen
|
||||||
|
#endif
|
|
@ -117,7 +117,7 @@ end
|
||||||
|
|
||||||
do
|
do
|
||||||
local f_count = ProtoField.uint8("minetest.client.gotblocks_count", "Count", base.DEC)
|
local f_count = ProtoField.uint8("minetest.client.gotblocks_count", "Count", base.DEC)
|
||||||
local f_block = ProtoField.bytes("minetset.client.gotblocks_block", "Block", base.DEC)
|
local f_block = ProtoField.bytes("minetest.client.gotblocks_block", "Block", base.DEC)
|
||||||
local f_x = ProtoField.int16("minetest.client.gotblocks_x", "Block position X", base.DEC)
|
local f_x = ProtoField.int16("minetest.client.gotblocks_x", "Block position X", base.DEC)
|
||||||
local f_y = ProtoField.int16("minetest.client.gotblocks_y", "Block position Y", base.DEC)
|
local f_y = ProtoField.int16("minetest.client.gotblocks_y", "Block position Y", base.DEC)
|
||||||
local f_z = ProtoField.int16("minetest.client.gotblocks_z", "Block position Z", base.DEC)
|
local f_z = ProtoField.int16("minetest.client.gotblocks_z", "Block position Z", base.DEC)
|
||||||
|
@ -151,7 +151,7 @@ end
|
||||||
|
|
||||||
do
|
do
|
||||||
local f_count = ProtoField.uint8("minetest.client.deletedblocks_count", "Count", base.DEC)
|
local f_count = ProtoField.uint8("minetest.client.deletedblocks_count", "Count", base.DEC)
|
||||||
local f_block = ProtoField.bytes("minetset.client.deletedblocks_block", "Block", base.DEC)
|
local f_block = ProtoField.bytes("minetest.client.deletedblocks_block", "Block", base.DEC)
|
||||||
local f_x = ProtoField.int16("minetest.client.deletedblocks_x", "Block position X", base.DEC)
|
local f_x = ProtoField.int16("minetest.client.deletedblocks_x", "Block position X", base.DEC)
|
||||||
local f_y = ProtoField.int16("minetest.client.deletedblocks_y", "Block position Y", base.DEC)
|
local f_y = ProtoField.int16("minetest.client.deletedblocks_y", "Block position Y", base.DEC)
|
||||||
local f_z = ProtoField.int16("minetest.client.deletedblocks_z", "Block position Z", base.DEC)
|
local f_z = ProtoField.int16("minetest.client.deletedblocks_z", "Block position Z", base.DEC)
|
||||||
|
|
Loading…
Reference in New Issue