float bg5_temps[] = {5.0, 40.0};
int bg5_biomes[] = {BT_LAKE, BT_PLAINS, BT_DESERT};*/
+NoiseParams np_default = {0.0, 20.0, v3f(250., 250., 250.), 82341, 5, 0.6};
+
BiomeDefManager::BiomeDefManager(IGameDef *gamedef) {
this->m_gamedef = gamedef;
this->ndef = gamedef->ndef();
+ bgroups.push_back(new std::vector<Biome *>); //the initial biome group
//addDefaultBiomes(); //can't do this in the ctor, too early
}
}
-void BiomeDefManager::addBiome() {
+Biome *BiomeDefManager::createBiome(BiomeTerrainType btt) {
+ switch (btt) {
+ case BIOME_TERRAIN_NORMAL:
+ return new Biome;
+ case BIOME_TERRAIN_LIQUID:
+ return new BiomeLiquid;
+ case BIOME_TERRAIN_NETHER:
+ return new BiomeHell;
+ case BIOME_TERRAIN_AETHER:
+ return new BiomeAether;
+ case BIOME_TERRAIN_FLAT:
+ return new BiomeSuperflat;
+ }
+}
+
+
+void BiomeDefManager::addBiomeGroup(float freq) {
+ int size = bgroup_freqs.size();
+ float newfreq = freq;
+ if (size)
+ newfreq += bgroup_freqs[size - 1];
+ bgroup_freqs.push_back(newfreq);
+ bgroups.push_back(new std::vector<Biome *>);
+ printf("added biome with freq %f\n", newfreq);
}
-NoiseParams npmtdef = {0.0, 20.0, v3f(250., 250., 250.), 82341, 5, 0.6};
+void BiomeDefManager::addBiome(int groupid, Biome *b) {
+ std::vector<Biome *> *bgroup;
+
+ if (groupid >= bgroups.size()) {
+ printf("blahblahblah");
+ return;
+ }
+
+ bgroup = bgroups[groupid];
+ bgroup->push_back(b);
+}
+
void BiomeDefManager::addDefaultBiomes() {
std::vector<Biome *> *bgroup;
Biome *b;
- //bgroup = new std::vector<Biome *>;
-
b = new Biome;
b->name = "Default";
b->n_top = MapNode(ndef->getId("mapgen_stone"));
b->heat_max = FLT_MAX;
b->humidity_min = FLT_MIN;
b->humidity_max = FLT_MAX;
- b->np = &npmtdef;
+ b->np = &np_default;
biome_default = b;
-
- //bgroup->push_back(b);
- //bgroups.push_back(bgroup);
}
Biome *BiomeDefManager::getBiome(float bgfreq, float heat, float humidity) {
- std::vector<Biome *> bgroup;
+ std::vector<Biome *> *bgroup;
Biome *b;
int i;
int ngroups = bgroup_freqs.size();
if (!ngroups)
return biome_default;
- for (i = 0; (i != ngroups - 1) && (bgfreq > bgroup_freqs[i]); i++);
- bgroup = *(bgroups[i]);
+ for (i = 0; (i != ngroups) && (bgfreq > bgroup_freqs[i]); i++);
+ bgroup = bgroups[i];
- int nbiomes = bgroup.size();
- if (!nbiomes)
- return biome_default;
- for (i = 0; i != nbiomes - 1; i++) {
- b = bgroup[i];
+ int nbiomes = bgroup->size();
+ for (i = 0; i != nbiomes; i++) {
+ b = bgroup->operator[](i);///////////////////////////
if (heat >= b->heat_min && heat <= b->heat_max &&
humidity >= b->humidity_min && humidity <= b->humidity_max)
return b;
void Biome::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
- //printf("(%d, %d): %f\n", x, z, mg->map_terrain[z * mg->ystride + x]);
-
- //int surfaceh = 4;
- int surfaceh = np->offset + np->scale * mg->map_terrain[(z - mg->node_min.Z) * 80 /*THIS IS TEMPORARY mg->ystride*/ + (x - mg->node_min.X)];
- //printf("gen column %f\n", );
+ int i = (z - mg->node_min.Z) * mg->csize.Z + (x - mg->node_min.X);
+ int surfaceh = np->offset + np->scale * mg->map_terrain[i];
int y = y1;
- int i = mg->vmanip->m_area.index(x, y, z); //z * mg->zstride + x + (y - mg->vmanip->m_area.MinEdge.Y) * mg->ystride;
+
+ i = mg->vmanip->m_area.index(x, y, z);
for (; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
mg->vmanip->m_data[i] = n_filler;
for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
-void BiomeOcean::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
- int y, i = 0;
-
- int surfaceh = np->offset + np->scale * mg->map_terrain[z * mg->ystride + x];
+void BiomeLiquid::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
+ int i = (z - mg->node_min.Z) * mg->csize.Z + (x - mg->node_min.X);
+ int surfaceh = np->offset + np->scale * mg->map_terrain[i];
+ int y = y1;
- i = z * mg->zstride + x;
- for (y = y1; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
+ i = mg->vmanip->m_area.index(x, y, z);
+ for (; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
mg->vmanip->m_data[i] = n_filler;
for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
mg->vmanip->m_data[i] = n_top;
+ for (; y <= mg->water_level && y <= y2; y++, i += mg->ystride)
+ mg->vmanip->m_data[i] = mg->n_water;
for (; y <= y2; y++, i += mg->ystride)
mg->vmanip->m_data[i] = mg->n_air;
}
void BiomeHell::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
- int y, i = 0;
-
- int surfaceh = np->offset + np->scale * mg->map_terrain[z * mg->ystride + x];
- i = z * mg->zstride + x;
- for (y = y1; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
- mg->vmanip->m_data[i] = n_filler;
- for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
- mg->vmanip->m_data[i] = n_top;
- for (; y <= y2; y++, i += mg->ystride)
- mg->vmanip->m_data[i] = mg->n_air;
}
///////////////////////////// [ Aether biome ] ////////////////////////////////
+
+int BiomeAether::getSurfaceHeight(float noise_terrain) {
+ return np->offset + np->scale * noise_terrain;
+}
+
+
+void BiomeAether::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
+
+}
+
+
/////////////////////////// [ Superflat biome ] ///////////////////////////////
void BiomeSuperflat::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
- int y, i = 0;
-
- int surfaceh = ntopnodes;
- i = z * mg->zstride + x;
- for (y = y1; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
- mg->vmanip->m_data[i] = n_filler;
- for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
- mg->vmanip->m_data[i] = n_top;
- for (; y <= y2; y++, i += mg->ystride)
- mg->vmanip->m_data[i] = mg->n_air;
}
#include "content_sao.h" // For LuaEntitySAO and PlayerSAO
#include "itemdef.h"
#include "nodedef.h"
+#include "biome.h"
#include "craftdef.h"
#include "main.h" // For g_settings
#include "settings.h" // For accessing g_settings
{0, NULL},
};
+struct EnumString es_BiomeTerrainType[] =
+{
+ {BIOME_TERRAIN_NORMAL, "normal"},
+ {BIOME_TERRAIN_LIQUID, "liquid"},
+ {BIOME_TERRAIN_NETHER, "nether"},
+ {BIOME_TERRAIN_AETHER, "aether"},
+ {BIOME_TERRAIN_FLAT, "flat"},
+ {0, NULL},
+};
+
/*
C struct <-> Lua table converter functions
*/
if(lua_istable(L, -1))
prop->initial_sprite_basepos = read_v2s16(L, -1);
lua_pop(L, 1);
-
+
getboolfield(L, -1, "is_visible", prop->is_visible);
getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound);
getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate);
warn_if_field_exists(L, index, "tool_digging_properties",
"deprecated: use tool_capabilities");
-
+
lua_getfield(L, index, "tool_capabilities");
if(lua_istable(L, -1)){
def.tool_capabilities = new ToolCapabilities(
{
if(index < 0)
index = lua_gettop(L) + 1 + index;
-
+
TileDef tiledef;
// key at index -2 and value at index
index = lua_gettop(L) + 1 + index;
ContentFeatures f;
-
+
/* Cache existence of some callbacks */
lua_getfield(L, index, "on_construct");
if(!lua_isnil(L, -1)) f.has_on_construct = true;
f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
NDT_NORMAL);
getfloatfield(L, index, "visual_scale", f.visual_scale);
-
+
// tiles = {}
lua_getfield(L, index, "tiles");
// If nil, try the deprecated name "tile_images" instead
}
}
lua_pop(L, 1);
-
+
// special_tiles = {}
lua_getfield(L, index, "special_tiles");
// If nil, try the deprecated name "special_materials" instead
f.alpha = getintfield_default(L, index, "alpha", 255);
/* Other stuff */
-
+
lua_getfield(L, index, "post_effect_color");
if(!lua_isnil(L, -1))
f.post_effect_color = readARGB8(L, -1);
"deprecated: use 'drop' field");
warn_if_field_exists(L, index, "metadata_name",
"deprecated: use on_add and metadata callbacks");
-
+
// True for all ground-like things like stone and mud, false for eg. trees
getboolfield(L, index, "is_ground_content", f.is_ground_content);
f.light_propagates = (f.param_type == CPT_LIGHT);
"light_source", f.light_source);
f.damage_per_second = getintfield_default(L, index,
"damage_per_second", f.damage_per_second);
-
+
lua_getfield(L, index, "node_box");
if(lua_istable(L, -1))
f.node_box = read_nodebox(L, -1);
getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
// Set to true if wall_mounted used to be set to true
getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
-
+
// Sound table
lua_getfield(L, index, "sounds");
if(lua_istable(L, -1)){
static const luaL_reg methods[];
// Exported functions
-
+
// garbage collector
static int gc_object(lua_State *L)
{
{
return m_stack;
}
-
+
// LuaItemStack(itemstack or itemstring or table or nil)
// Creates an LuaItemStack and leaves it on top of stack
static int create_object(lua_State *L)
if(!ud) luaL_typerror(L, narg, className);
return *(InvRef**)ud; // unbox pointer
}
-
+
static Inventory* getinv(lua_State *L, InvRef *ref)
{
return get_server(L)->getInventory(ref->m_loc);
// Inform other things that the inventory has changed
get_server(L)->setInventoryModified(ref->m_loc);
}
-
+
// Exported functions
-
+
// garbage collector
static int gc_object(lua_State *L) {
InvRef *o = *(InvRef **)(lua_touserdata(L, 1));
if(!ud) luaL_typerror(L, narg, className);
return *(NodeMetaRef**)ud; // unbox pointer
}
-
+
static NodeMetadata* getmeta(NodeMetaRef *ref, bool auto_create)
{
NodeMetadata *meta = ref->m_env->getMap().getNodeMetadata(ref->m_p);
block->raiseModified(MOD_STATE_WRITE_NEEDED,
"NodeMetaRef::reportMetadataChange");
}
-
+
// Exported functions
-
+
// garbage collector
static int gc_object(lua_State *L) {
NodeMetaRef *o = *(NodeMetaRef **)(lua_touserdata(L, 1));
InvRef::createNodeMeta(L, ref->m_p);
return 1;
}
-
+
// to_table(self)
static int l_to_table(lua_State *L)
{
{
NodeMetaRef *ref = checkobject(L, 1);
int base = 2;
-
+
if(lua_isnil(L, base)){
// No metadata
ref->m_env->getMap().removeNodeMetadata(ref->m_p);
if(!ud) luaL_typerror(L, narg, className);
return *(ObjectRef**)ud; // unbox pointer
}
-
+
static ServerActiveObject* getobject(ObjectRef *ref)
{
ServerActiveObject *co = ref->m_object;
return NULL;
return (LuaEntitySAO*)obj;
}
-
+
static PlayerSAO* getplayersao(ObjectRef *ref)
{
ServerActiveObject *obj = getobject(ref);
return NULL;
return (PlayerSAO*)obj;
}
-
+
static Player* getplayer(ObjectRef *ref)
{
PlayerSAO *playersao = getplayersao(ref);
return NULL;
return playersao->getPlayer();
}
-
+
// Exported functions
-
+
// garbage collector
static int gc_object(lua_State *L) {
ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
co->m_removed = true;
return 0;
}
-
+
// getpos(self)
// returns: {x=num, y=num, z=num}
static int l_getpos(lua_State *L)
lua_setfield(L, -2, "z");
return 1;
}
-
+
// setpos(self, pos)
static int l_setpos(lua_State *L)
{
co->setPos(pos);
return 0;
}
-
+
// moveto(self, pos, continuous=false)
static int l_moveto(lua_State *L)
{
co->setVelocity(pos);
return 0;
}
-
+
// getvelocity(self)
static int l_getvelocity(lua_State *L)
{
pushFloatPos(L, v);
return 1;
}
-
+
// setacceleration(self, {x=num, y=num, z=num})
static int l_setacceleration(lua_State *L)
{
co->setAcceleration(pos);
return 0;
}
-
+
// getacceleration(self)
static int l_getacceleration(lua_State *L)
{
pushFloatPos(L, v);
return 1;
}
-
+
// setyaw(self, radians)
static int l_setyaw(lua_State *L)
{
co->setYaw(yaw);
return 0;
}
-
+
// getyaw(self)
static int l_getyaw(lua_State *L)
{
lua_pushnumber(L, yaw);
return 1;
}
-
+
// settexturemod(self, mod)
static int l_settexturemod(lua_State *L)
{
co->setTextureMod(mod);
return 0;
}
-
+
// setsprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
// select_horiz_by_yawpitch=false)
static int l_setsprite(lua_State *L)
lua_pushstring(L, name.c_str());
return 1;
}
-
+
// get_luaentity(self)
static int l_get_luaentity(lua_State *L)
{
luaentity_get(L, co->getId());
return 1;
}
-
+
/* Player-only */
// is_player(self)
lua_pushboolean(L, (player != NULL));
return 1;
}
-
+
// get_player_name(self)
static int l_get_player_name(lua_State *L)
{
lua_pushstring(L, player->getName());
return 1;
}
-
+
// get_look_dir(self)
static int l_get_look_dir(lua_State *L)
{
ObjectRef *o = checkobject(L, -1);
o->m_object = NULL;
}
-
+
static void Register(lua_State *L)
{
lua_newtable(L);
if(!ud) luaL_typerror(L, narg, className);
return *(NodeTimerRef**)ud; // unbox pointer
}
-
+
static int l_set(lua_State *L)
{
NodeTimerRef *o = checkobject(L, 1);
env->getMap().setNodeTimer(o->m_p,NodeTimer(t,e));
return 0;
}
-
+
static int l_start(lua_State *L)
{
NodeTimerRef *o = checkobject(L, 1);
env->getMap().setNodeTimer(o->m_p,NodeTimer(t,0));
return 0;
}
-
+
static int l_stop(lua_State *L)
{
NodeTimerRef *o = checkobject(L, 1);
env->getMap().removeNodeTimer(o->m_p);
return 0;
}
-
+
static int l_is_started(lua_State *L)
{
NodeTimerRef *o = checkobject(L, 1);
lua_pushboolean(L,(t.timeout != 0));
return 1;
}
-
+
static int l_get_timeout(lua_State *L)
{
NodeTimerRef *o = checkobject(L, 1);
lua_pushnumber(L,t.timeout);
return 1;
}
-
+
static int l_get_elapsed(lua_State *L)
{
NodeTimerRef *o = checkobject(L, 1);
NodeTimerRef *o = checkobject(L, -1);
o->m_env = NULL;
}
-
+
static void Register(lua_State *L)
{
lua_newtable(L);
if(!ud) luaL_typerror(L, narg, className);
return *(EnvRef**)ud; // unbox pointer
}
-
+
// Exported functions
// EnvRef:set_node(pos, node)
lua_getglobal(L, "table");
lua_getfield(L, -1, "insert");
int table_insert = lua_gettop(L);
-
+
lua_newtable(L);
int table = lua_gettop(L);
for(s16 x=minp.X; x<=maxp.X; x++)
EnvRef *o = checkobject(L, -1);
o->m_env = NULL;
}
-
+
static void Register(lua_State *L)
{
lua_newtable(L);
method(EnvRef, find_node_near),
method(EnvRef, find_nodes_in_area),
method(EnvRef, get_perlin),
+ //method{EnvRef, get_perlin_map_2d},
+ //method{EnvRef, get_perlin_map_3d},
method(EnvRef, clear_objects),
method(EnvRef, spawn_tree),
{0,0}
static const luaL_reg methods[];
// Exported functions
-
+
// garbage collector
static int gc_object(lua_State *L)
{
{
return m_pseudo;
}
-
+
// LuaPseudoRandom(seed)
// Creates an LuaPseudoRandom and leaves it on top of stack
static int create_object(lua_State *L)
u32 active_object_count, u32 active_object_count_wider)
{
lua_State *L = m_lua;
-
+
realitycheck(L);
assert(lua_checkstack(L, 20));
StackUnroller stack_unroller(L);
lua_gettable(L, registered_abms);
if(lua_isnil(L, -1))
assert(0);
-
+
// Call action
luaL_checktype(L, -1, LUA_TTABLE);
lua_getfield(L, -1, "action");
return 1;
}
+// register_biome_groups({frequencies})
+static int l_register_biome_groups(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+ int index = 1;
+ if (!lua_istable(L, index)) {
+
+ return 0;
+ }
+
+ BiomeDefManager *bmgr = get_server(L)->getEmergeManager()->biomedef;
+
+ lua_pushnil(L);
+ for (int i = 1; lua_next(L, index) != 0; i++) {
+ bmgr->addBiomeGroup(lua_tonumber(L, -1));
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+
+ return 0;
+}
+
+// register_biome({lots of stuff})
+static int l_register_biome(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TTABLE);
+ int index = 1, groupid;
+ std::string nodename;
+
+ IWritableNodeDefManager *ndef = get_server(L)->getWritableNodeDefManager();
+ BiomeDefManager *bmgr = get_server(L)->getEmergeManager()->biomedef;
+
+ groupid = getintfield_default(L, index, "group_id", 0);
+
+ enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
+ "terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
+ Biome *b = bmgr->createBiome(terrain);
+
+ b->name = getstringfield_default(L, index, "name", "");
+
+ if (getstringfield(L, index, "node_top", nodename))
+ b->n_top = MapNode(ndef->getId(nodename));
+ else
+ b->n_top = MapNode(CONTENT_IGNORE);
+
+ if (getstringfield(L, index, "node_filler", nodename))
+ b->n_filler = MapNode(ndef->getId(nodename));
+ else
+ b->n_filler = b->n_top;
+
+ b->ntopnodes = getintfield_default(L, index, "num_top_nodes", 0);
+
+ b->height_min = getintfield_default(L, index, "height_min", 0);
+ b->height_max = getintfield_default(L, index, "height_max", 0);
+ b->heat_min = getfloatfield_default(L, index, "heat_min", 0.);
+ b->heat_max = getfloatfield_default(L, index, "heat_max", 0.);
+ b->humidity_min = getfloatfield_default(L, index, "humidity_min", 0.);
+ b->humidity_max = getfloatfield_default(L, index, "humidity_max", 0.);
+
+//////hrm, what to do about the noiseparams...
+ b->np = new NoiseParams; /////just a hacky solution
+ getfloatfield(L, index, "scale", b->np->scale);
+ getfloatfield(L, index, "offset", b->np->offset);
+ //TODO: add configurable spread factor and octaves!?
+ //I'd have to create a Noise for every Biome...
+ bmgr->addBiome(groupid, b);
+ printf(" - added biome '%s' - %d %d\n", b->name.c_str(), b->n_top.param0, b->n_filler.param0);
+
+ return 0;
+}
+
// register_item_raw({lots of stuff})
static int l_register_item_raw(lua_State *L)
{
else
def.node_placement_prediction = "";
}
-
+
// Register item definition
idef->registerItem(def);
// Get the writable item definition manager from the server
IWritableItemDefManager *idef =
get_server(L)->getWritableItemDefManager();
-
+
idef->registerAlias(name, convert_to);
-
+
return 0; /* number of results */
}
// Get the writable craft definition manager from the server
IWritableCraftDefManager *craftdef =
get_server(L)->getWritableCraftDefManager();
-
+
std::string type = getstringfield_default(L, table, "type", "shaped");
/*
std::string name = checkstringfield(L, 1, "name");
loc.setDetached(name);
}
-
+
if(get_server(L)->getInventory(loc) != NULL)
InvRef::create(L, loc);
else
lua_getfield(L, input_i, "items");
std::vector<ItemStack> items = read_items(L, -1);
lua_pop(L, 1); // items
-
+
IGameDef *gdef = get_server(L);
ICraftDefManager *cdef = gdef->cdef();
CraftInput input(method, width, items);
char tmp[20];
int input_i = 1;
std::string o_item = luaL_checkstring(L,input_i);
-
+
IGameDef *gdef = get_server(L);
ICraftDefManager *cdef = gdef->cdef();
CraftInput input;
{"register_item_raw", l_register_item_raw},
{"register_alias_raw", l_register_alias_raw},
{"register_craft", l_register_craft},
+ {"register_biome", l_register_biome},
+ {"register_biome_groups", l_register_biome_groups},
{"setting_set", l_setting_set},
{"setting_get", l_setting_get},
{"setting_getbool", l_setting_getbool},
lua_newtable(L);
luaL_register(L, NULL, minetest_f);
lua_setglobal(L, "minetest");
-
+
// Get the main minetest table
lua_getglobal(L, "minetest");
<<"Only chararacters [a-z0-9_] are allowed."<<std::endl;
return false;
}
-
+
bool success = false;
try{
lua_getfield(L, -1, "registered_abms");
luaL_checktype(L, -1, LUA_TTABLE);
int registered_abms = lua_gettop(L);
-
+
if(lua_istable(L, registered_abms)){
int table = lua_gettop(L);
lua_pushnil(L);
LuaABM *abm = new LuaABM(L, id, trigger_contents,
required_neighbors, trigger_interval, trigger_chance);
-
+
env->addActiveBlockModifier(abm);
// removes value, keeps key for next iteration
lua_getfield(L, -1, "object_refs");
luaL_checktype(L, -1, LUA_TTABLE);
int objectstable = lua_gettop(L);
-
+
// object_refs[id] = object
lua_pushnumber(L, cobj->getId()); // Push id
lua_pushvalue(L, object); // Copy object to top of stack
lua_getfield(L, -1, "object_refs");
luaL_checktype(L, -1, LUA_TTABLE);
int objectstable = lua_gettop(L);
-
+
// Get object_refs[id]
lua_pushnumber(L, cobj->getId()); // Push id
lua_gettable(L, objectstable);
realitycheck(L);
assert(lua_checkstack(L, 20));
StackUnroller stack_unroller(L);
-
+
get_auth_handler(L);
lua_getfield(L, -1, "get_auth");
if(lua_type(L, -1) != LUA_TFUNCTION)
lua_pushstring(L, playername.c_str());
if(lua_pcall(L, 1, 1, 0))
script_error(L, "error: %s", lua_tostring(L, -1));
-
+
// nil = login not allowed
if(lua_isnil(L, -1))
return false;
luaL_checktype(L, -1, LUA_TTABLE);
-
+
std::string password;
bool found = getstringfield(L, -1, "password", password);
if(!found)
if(dst_privs)
read_privileges(L, -1, *dst_privs);
lua_pop(L, 1);
-
+
return true;
}
realitycheck(L);
assert(lua_checkstack(L, 20));
StackUnroller stack_unroller(L);
-
+
get_auth_handler(L);
lua_getfield(L, -1, "create_auth");
if(lua_type(L, -1) != LUA_TFUNCTION)
realitycheck(L);
assert(lua_checkstack(L, 20));
StackUnroller stack_unroller(L);
-
+
get_auth_handler(L);
lua_getfield(L, -1, "set_password");
if(lua_type(L, -1) != LUA_TFUNCTION)
player
*/
-void scriptapi_on_player_receive_fields(lua_State *L,
+void scriptapi_on_player_receive_fields(lua_State *L,
ServerActiveObject *player,
const std::string &formname,
const std::map<std::string, std::string> &fields)
script_error(L, "error: %s", lua_tostring(L, -1));
if((bool)lua_isboolean(L,-1) && (bool)lua_toboolean(L,-1) == true)
return true;
-
+
return false;
}
StackUnroller stack_unroller(L);
INodeDefManager *ndef = get_server(L)->ndef();
-
+
// If node doesn't exist, we don't know what callback to call
MapNode node = get_env(L)->getMap().getNodeNoEx(p);
if(node.getContent() == CONTENT_IGNORE)
verbosestream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
<<name<<"\""<<std::endl;
StackUnroller stack_unroller(L);
-
+
// Get minetest.registered_entities[name]
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_entities");
}
int prototype_table = lua_gettop(L);
//dump2(L, "prototype_table");
-
+
// Create entity object
lua_newtable(L);
int object = lua_gettop(L);
// Set object metatable
lua_pushvalue(L, prototype_table);
lua_setmetatable(L, -2);
-
+
// Add object reference
// This should be userdata with metatable ObjectRef
objectref_get(L, id);
lua_pushnumber(L, id); // Push id
lua_pushvalue(L, object); // Copy object to top of stack
lua_settable(L, -3);
-
+
return true;
}
assert(lua_checkstack(L, 20));
verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
StackUnroller stack_unroller(L);
-
+
// Get minetest.luaentities[id]
luaentity_get(L, id);
int object = lua_gettop(L);
-
+
// Get on_activate function
lua_pushvalue(L, object);
lua_getfield(L, -1, "on_activate");
lua_getfield(L, -1, "luaentities");
luaL_checktype(L, -1, LUA_TTABLE);
int objectstable = lua_gettop(L);
-
+
// Set luaentities[id] = nil
lua_pushnumber(L, id); // Push id
lua_pushnil(L);
lua_settable(L, objectstable);
-
+
lua_pop(L, 2); // pop luaentities, minetest
}
// Get minetest.luaentities[id]
luaentity_get(L, id);
int object = lua_gettop(L);
-
+
// Get get_staticdata function
lua_pushvalue(L, object);
lua_getfield(L, -1, "get_staticdata");
if(lua_isnil(L, -1))
return "";
-
+
luaL_checktype(L, -1, LUA_TFUNCTION);
lua_pushvalue(L, object); // self
// Call with 1 arguments, 1 results
if(lua_pcall(L, 1, 1, 0))
script_error(L, "error running function get_staticdata: %s\n",
lua_tostring(L, -1));
-
+
size_t len=0;
const char *s = lua_tolstring(L, -1, &len);
return std::string(s, len);
// Set default values that differ from ObjectProperties defaults
prop->hp_max = 10;
-
+
/* Read stuff */
-
+
prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
getboolfield(L, -1, "physical", prop->physical);
getstringfield(L, -1, "visual", prop->visual);
getstringfield(L, -1, "mesh", prop->mesh);
-
+
// Deprecated: read object properties directly
read_object_properties(L, -1, prop);
-
+
// Read initial_properties
lua_getfield(L, -1, "initial_properties");
read_object_properties(L, -1, prop);
delete q;
}
}
-
+
/*
peer_id=0 adds with nobody to send to
*/
void addBlock(u16 peer_id, v3s16 pos, u8 flags)
{
DSTACK(__FUNCTION_NAME);
-
+
JMutexAutoLock lock(m_mutex);
if(peer_id != 0)
}
}
}
-
+
/*
Add the block
*/
JMutexAutoLock lock(m_mutex);
return m_queue.size();
}
-
+
u32 peerItemCount(u16 peer_id)
{
JMutexAutoLock lock(m_mutex);
/*
Used for queueing and sorting block transfers in containers
-
+
Lower priority number means higher priority.
*/
struct PrioritySortedBlockTransfer
max_hear_distance(32*BS),
loop(false)
{}
-
+
v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
};
~RemoteClient()
{
}
-
+
/*
Finds block that should be sent next to the client.
Environment should be locked when this is called.
{
return m_blocks_sending.size();
}
-
+
// Increments timeouts and removes timed-out blocks from list
// NOTE: This doesn't fix the server-not-sending-block bug
// because it is related to emerging, not sending.
// Time from last placing or removing blocks
float m_time_from_building;
-
+
/*JMutex m_dig_mutex;
float m_dig_time_remaining;
// -1 = not digging
s16 m_dig_tool_item;
v3s16 m_dig_position;*/
-
+
/*
List of active objects that the client knows of.
Value is dummy.
- These don't have to be sent again.
- A block is cleared from here when client says it has
deleted it from it's memory
-
+
Key is position, value is dummy.
No MapBlock* is stored here because the blocks can get deleted.
*/
s16 m_nearest_unsent_d;
v3s16 m_last_center;
float m_nearest_unsent_reset_timer;
-
+
/*
Blocks that are currently on the line.
This is used for throttling the sending of blocks.
This is resetted by PrintInfo()
*/
u32 m_excess_gotblocks;
-
+
// CPU usage optimization
u32 m_nothing_to_send_counter;
float m_nothing_to_send_pause_timer;
/*
NOTE: Every public method should be thread-safe
*/
-
+
Server(
const std::string &path_world,
const std::string &path_config,
{
return m_shutdown_requested;
}
-
+
/*
Shall be called with the environment locked.
This is accessed by the map, which is inside the environment,
// Envlock + conlock
s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams ¶ms);
void stopSound(s32 handle);
-
+
// Envlock + conlock
std::set<std::string> getPlayerEffectivePrivs(const std::string &name);
bool checkPriv(const std::string &name, const std::string &priv);
{
return m_con.GetPeerAddress(peer_id);
}
-
+
// Envlock and conlock should be locked when calling this
void notifyPlayer(const char *name, const std::wstring msg);
void notifyPlayers(const std::wstring msg);
void queueBlockEmerge(v3s16 blockpos, bool allow_generate);
-
+
// Creates or resets inventory
Inventory* createDetachedInventory(const std::string &name);
-
+
// Envlock and conlock should be locked when using Lua
lua_State *getLua(){ return m_lua; }
// Envlock should be locked when using the rollback manager
IRollbackManager *getRollbackManager(){ return m_rollback; }
+
+ //TODO: determine what should be locked when accessing the emerge manager
+ EmergeManager *getEmergeManager(){ return m_emerge; }
+
// actions: time-reversed list
// Return value: success/failure
bool rollbackRevertActions(const std::list<RollbackAction> &actions,
std::list<std::string> *log);
-
+
// IGameDef interface
// Under envlock
virtual IItemDefManager* getItemDefManager();
virtual ISoundManager* getSoundManager();
virtual MtEventManager* getEventManager();
virtual IRollbackReportSink* getRollbackReportSink();
-
+
IWritableItemDefManager* getWritableItemDefManager();
IWritableNodeDefManager* getWritableNodeDefManager();
IWritableCraftDefManager* getWritableCraftDefManager();
const ModSpec* getModSpec(const std::string &modname);
void getModNames(core::list<std::string> &modlist);
std::string getBuiltinLuaPath();
-
+
std::string getWorldPath(){ return m_path_world; }
bool isSingleplayer(){ return m_simple_singleplayer_mode; }
// As of now, these create and remove clients and players.
void peerAdded(con::Peer *peer);
void deletingPeer(con::Peer *peer, bool timeout);
-
+
/*
Static send methods
*/
-
+
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
static void SendAccessDenied(con::Connection &con, u16 peer_id,
const std::wstring &reason);
IItemDefManager *itemdef);
static void SendNodeDef(con::Connection &con, u16 peer_id,
INodeDefManager *nodedef, u16 protocol_version);
-
+
/*
Non-static send methods.
Conlock should be always used.
void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
core::list<u16> *far_players=NULL, float far_d_nodes=100);
void setBlockNotSent(v3s16 p);
-
+
// Environment and Connection must be locked when called
void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
-
+
// Sends blocks to clients (locks env and con on its own)
void SendBlocks(float dtime);
-
+
void fillMediaCache();
void sendMediaAnnouncement(u16 peer_id);
void sendRequestedMedia(u16 peer_id,
const core::list<MediaRequest> &tosend);
-
+
void sendDetachedInventory(const std::string &name, u16 peer_id);
void sendDetachedInventoryToAll(const std::string &name);
void sendDetachedInventories(u16 peer_id);
/*
Something random
*/
-
+
void DiePlayer(u16 peer_id);
void RespawnPlayer(u16 peer_id);
-
+
void UpdateCrafting(u16 peer_id);
-
+
// When called, connection mutex should be locked
RemoteClient* getClient(u16 peer_id);
-
+
// When called, environment mutex should be locked
std::string getPlayerName(u16 peer_id)
{
Call with env and con locked.
*/
PlayerSAO *emergePlayer(const char *name, u16 peer_id);
-
+
// Locks environment and connection by its own
struct PeerChange;
void handlePeerChange(PeerChange &c);
/*
Variables
*/
-
+
// World directory
std::string m_path_world;
// Path to user's configuration file ("" = no configuration file)
// Thread can set; step() will throw as ServerError
MutexedVariable<std::string> m_async_fatal_error;
-
+
// Some timers
float m_liquid_transform_timer;
float m_print_info_timer;
float m_emergethread_trigger_timer;
float m_savemap_timer;
IntervalLimiter m_map_timer_and_unload_interval;
-
+
// NOTE: If connection and environment are both to be locked,
// environment shall be locked first.
// Environment
ServerEnvironment *m_env;
JMutex m_env_mutex;
-
+
// Connection
con::Connection m_con;
JMutex m_con_mutex;
// Item definition manager
IWritableItemDefManager *m_itemdef;
-
+
// Node definition manager
IWritableNodeDefManager *m_nodedef;
-
+
// Craft definition manager
IWritableCraftDefManager *m_craftdef;
-
+
// Event manager
EventManager *m_event;
-
+
// Mods
std::vector<ModSpec> m_mods;
-
+
/*
Threads
*/
-
+
// A buffer for time steps
// step() increments and AsyncRunStep() run by m_thread reads it.
float m_step_dtime;
EmergeThread m_emergethread;
// Queue of block coordinates to be processed by the emerge thread
BlockEmergeQueue m_emerge_queue;
-
+
/*
Time related stuff
*/
float m_time_of_day_send_timer;
// Uptime of server in seconds
MutexedVariable<double> m_uptime;
-
+
/*
Peer change queue.
Queues stuff from peerAdded() and deletingPeer() to
/*
Random stuff
*/
-
+
// Mod parent directory paths
core::list<std::string> m_modspaths;