improved mob spawning, pt1

This commit is contained in:
darkrose 2015-09-13 05:46:03 +10:00
parent 18953b1333
commit 70636b3b4a
8 changed files with 317 additions and 126 deletions

View File

@ -6331,7 +6331,6 @@ Frame Root {
123.529412;
0.000000; 0.000000; 0.000000;;
0.000000; 0.000000; 0.000000;;
TextureFilename {"mob_doe.png";}
}
} // End of Cube_002 material list
XSkinMeshHeader {

View File

@ -130,46 +130,12 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_coun
if ((c1 != CONTENT_AIR && c1 != CONTENT_WATERSOURCE) && c1 != c2)
return false;
u8 light = a1.getLightBlend(env->getDayNightRatio());
u8 level = mobLevelI(g_settings->get("max_mob_level"));
v3f pf = intToFloat(pos,BS);
Player *nearest = env->getNearestConnectedPlayer(pf);
f32 distance = 30000.0;
if (nearest)
distance = pf.getDistanceFrom(nearest->getPosition());
for (u16 i=0; i<CONTENT_MOB_COUNT; i++) {
MobFeatures m = g_content_mob_features[i];
if (m.spawn_in == CONTENT_IGNORE && m.spawn_on == CONTENT_IGNORE)
continue;
if (m.spawn_max_nearby_mobs < active_object_count)
continue;
if (m.spawn_min_height > pos.Y)
continue;
if (m.spawn_max_height < pos.Y)
continue;
if (m.spawn_in != CONTENT_IGNORE) {
if (m.spawn_in != c1)
continue;
if (m.spawn_in != c2)
continue;
}
if (m.spawn_on != CONTENT_IGNORE) {
if (m.spawn_on != c0)
continue;
}
if (m.spawn_min_light > light)
continue;
if (m.spawn_max_light < light)
continue;
if (m.level > level)
continue;
if (m.notices_player && m.spawn_nearest_player != m.spawn_farthest_player) {
if (m.spawn_nearest_player > distance)
continue;
if (m.spawn_farthest_player < distance)
continue;
}
if (m.spawn_chance > 1 && rand%m.spawn_chance != 0)
continue;
can.push_back(i);
@ -204,6 +170,196 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_coun
return true;
}
void mob_spawn(v3s16 pos, content_t mob, ServerEnvironment *env)
{
MobFeatures &m = content_mob_features(mob);
if (m.content == CONTENT_IGNORE)
return;
v3f p = intToFloat(pos+v3s16(0,1,0), BS);
actionstream<<"A mob of type "<<m.content<<" spawns at "<<PP(floatToInt(p,BS))<<std::endl;
ServerActiveObject *obj = new MobSAO(env, 0, p, m.content);
u16 id = env->addActiveObject(obj);
if (!id) {
actionstream<<"A mob of type "<<m.content<<" didn't spawn at "<<PP(floatToInt(p,BS))<<std::endl;
return;
}
if (id && m.sound_spawn != "")
env->addEnvEvent(ENV_EVENT_SOUND,p,m.sound_spawn);
}
void mob_spawn_passive(v3s16 pos, bool water, ServerEnvironment *env)
{
std::vector<content_t> can;
int rand = myrand();
for (u16 i=0; i<CONTENT_MOB_COUNT; i++) {
MobFeatures m = g_content_mob_features[i];
if (!m.spawn_naturally)
continue;
if (m.level > MOB_PASSIVE)
continue;
if (m.spawn_water != water)
continue;
if (m.spawn_min_height > pos.Y)
continue;
if (m.spawn_max_height < pos.Y)
continue;
if (m.spawn_chance > 1 && rand%m.spawn_chance != 0)
continue;
can.push_back(i);
}
if (can.size() == 0)
return;
MobFeatures m;
u32 index = 0;
if (can.size() > 1)
index = myrand_range(0,can.size()-1);
m = g_content_mob_features[can[index]];
if (m.content == CONTENT_IGNORE)
return;
v3s16 spots[9] = {
v3s16(0,0,0),
v3s16(-2,0,0),
v3s16(-2,0,2),
v3s16(-2,0,-2),
v3s16(2,0,0),
v3s16(2,0,-2),
v3s16(2,0,2),
v3s16(0,0,-2),
v3s16(0,0,2)
};
u16 cnt = 0;
for (u16 i=0; i<9 && cnt < m.spawn_group; i++) {
v3s16 p = pos+spots[i];
if (water) {
if (env->getMap().getNodeNoEx(p+v3s16(0,1,0)).getContent() != CONTENT_WATERSOURCE)
continue;
}else{
content_t c = env->getMap().getNodeNoEx(pos).getContent();
bool have_spot = false;
for (s16 x=-1; !have_spot && x<2; x++) {
for (s16 y=-1; !have_spot && y<2; y++) {
for (s16 z=-1; !have_spot && z<2; z++) {
v3s16 pp = p+v3s16(x,y,z);
if (env->getMap().getNodeNoEx(pp).getContent() != c)
continue;
pp.Y++;
if (env->getMap().getNodeNoEx(pp).getContent() != CONTENT_AIR)
continue;
pp.Y++;
if (env->getMap().getNodeNoEx(pp).getContent() != CONTENT_AIR)
continue;
p += v3s16(x,y,z);
have_spot = true;
break;
}
}
}
if (!have_spot)
continue;
}
mob_spawn(p,m.content,env);
cnt++;
}
}
void mob_spawn_hostile(v3s16 pos, bool water, ServerEnvironment *env)
{
std::vector<content_t> can;
int rand = myrand();
u8 level = mobLevelI(g_settings->get("max_mob_level"));
if (level < MOB_AGGRESSIVE)
return;
for (u16 i=0; i<CONTENT_MOB_COUNT; i++) {
MobFeatures m = g_content_mob_features[i];
if (!m.spawn_naturally)
continue;
if (m.level < MOB_AGGRESSIVE)
continue;
if (m.level > level)
continue;
if (m.spawn_water != water)
continue;
if (m.spawn_min_height > pos.Y)
continue;
if (m.spawn_max_height < pos.Y)
continue;
if (m.spawn_chance > 1 && rand%m.spawn_chance != 0)
continue;
can.push_back(i);
}
if (can.size() == 0)
return;
MobFeatures m;
u32 index = 0;
if (can.size() > 1)
index = myrand_range(0,can.size()-1);
m = g_content_mob_features[can[index]];
if (m.content == CONTENT_IGNORE)
return;
v3s16 spots[9] = {
v3s16(0,0,0),
v3s16(-2,0,0),
v3s16(-2,0,2),
v3s16(-2,0,-2),
v3s16(2,0,0),
v3s16(2,0,-2),
v3s16(2,0,2),
v3s16(0,0,-2),
v3s16(0,0,2)
};
u16 cnt = 0;
for (u16 i=0; i<9 && cnt < m.spawn_group; i++) {
v3s16 p = pos+spots[i];
if (water) {
if (env->getMap().getNodeNoEx(p+v3s16(0,1,0)).getContent() != CONTENT_WATERSOURCE)
continue;
}else{
content_t c = env->getMap().getNodeNoEx(pos).getContent();
bool have_spot = false;
for (s16 x=-1; !have_spot && x<2; x++) {
for (s16 y=-1; !have_spot && y<2; y++) {
for (s16 z=-1; !have_spot && z<2; z++) {
v3s16 pp = p+v3s16(x,y,z);
if (env->getMap().getNodeNoEx(pp).getContent() != c)
continue;
pp.Y++;
if (env->getMap().getNodeNoEx(pp).getContent() != CONTENT_AIR)
continue;
pp.Y++;
if (env->getMap().getNodeNoEx(pp).getContent() != CONTENT_AIR)
continue;
p += v3s16(x,y,z);
have_spot = true;
break;
}
}
}
if (!have_spot)
continue;
}
mob_spawn(p,m.content,env);
cnt++;
}
}
void content_mob_init()
{
content_t i;
@ -220,10 +376,9 @@ void content_mob_init()
f->dropped_item = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_RAT)+" 1";
f->motion = MM_WANDER;
f->moves_silently = true;
f->spawn_on = CONTENT_STONE;
f->spawn_in = CONTENT_AIR;
f->spawn_max_height = -10;
f->spawn_max_nearby_mobs = 4;
f->spawn_group = 3;
f->spawn_naturally = false;
f->lifetime = 900.0;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
@ -239,12 +394,9 @@ void content_mob_init()
f->motion_type = MMT_FLYLOW;
f->glow_light = LIGHT_MAX-1;
f->moves_silently = true;
f->spawn_on = CONTENT_JUNGLETREE;
f->spawn_in = CONTENT_AIR;
f->spawn_min_height = -5;
f->spawn_max_height = 50;
f->spawn_max_light = LIGHT_MAX/2;
f->spawn_max_nearby_mobs = 5;
f->spawn_naturally = false;
f->lifetime = 1200.0;
f->setCollisionBox(aabb3f(-BS/4.,-BS/6.,-BS/4., BS/4.,BS/6.,BS/4.));
@ -289,11 +441,7 @@ void content_mob_init()
f->dropped_item = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_OERKKI_DUST)+" 2";
f->motion = MM_SEEKER;
f->moves_silently = true;
f->spawn_on = CONTENT_STONE;
f->spawn_in = CONTENT_AIR;
f->spawn_max_height = 2;
f->spawn_max_light = LIGHT_MAX/4;
f->spawn_max_nearby_mobs = 2;
f->sound_spawn = "mob-oerkki-spawn";
f->notices_player = true;
f->attack_player_damage = 3;
@ -343,11 +491,6 @@ void content_mob_init()
f->punch_action = MPA_HARM;
f->dropped_item = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_GUNPOWDER)+" 4";
f->motion = MM_SENTRY;
f->spawn_on = CONTENT_MOSSYCOBBLE;
f->spawn_in = CONTENT_AIR;
f->spawn_max_light = LIGHT_MAX/3;
f->spawn_max_nearby_mobs = 1;
f->spawn_farthest_player = 20.0*BS;
f->notices_player = true;
f->attack_throw_object = CONTENT_MOB_FIREBALL;
f->attack_glow_light = LIGHT_MAX-1;
@ -369,6 +512,7 @@ void content_mob_init()
f->attack_player_damage = 3;
f->attack_player_range = v3f(2,2,2);
f->contact_explosion_diameter = 3;
f->spawn_naturally = false;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_DOE;
@ -389,12 +533,9 @@ void content_mob_init()
f->motion = MM_SEEKER;
f->motion_type = MMT_WALK;
f->sound_random = "mob-deer-env";
f->spawn_on = CONTENT_WILDGRASS_SHORT;
f->spawn_in = CONTENT_AIR;
f->spawn_min_height = -5;
f->spawn_max_height = 40;
f->spawn_min_light = LIGHT_MAX/2;
f->spawn_max_nearby_mobs = 3;
f->spawn_group = 3;
f->lifetime = 1200.0;
f->setCollisionBox(aabb3f(-0.6*BS, 0., -0.6*BS, 0.6*BS, 1.25*BS, 0.6*BS));
@ -418,12 +559,8 @@ void content_mob_init()
f->motion_type = MMT_WALK;
f->angry_motion = MM_SEEKER;
f->sound_random = "mob-deer-env";
f->spawn_on = CONTENT_WILDGRASS_SHORT;
f->spawn_in = CONTENT_AIR;
f->spawn_min_height = -5;
f->spawn_max_height = 40;
f->spawn_min_light = LIGHT_MAX/2;
f->spawn_max_nearby_mobs = 3;
f->spawn_chance = 2;
f->notices_player = true;
f->attack_player_damage = 3;
@ -451,6 +588,7 @@ void content_mob_init()
f->sound_random = "mob-deer-env";
f->notices_player = true;
f->lifetime = 1800.0;
f->spawn_naturally = false;
f->setCollisionBox(aabb3f(-0.7*BS, 0., -0.7*BS, 0.7*BS, 1.5*BS, 0.7*BS));
i = CONTENT_MOB_FISH;
@ -471,11 +609,9 @@ void content_mob_init()
f->motion = MM_WANDER;
f->motion_type = MMT_SWIM;
f->moves_silently = true;
f->spawn_on = CONTENT_SAND;
f->spawn_in = CONTENT_WATERSOURCE;
f->spawn_min_height = -30;
f->spawn_max_height = -2;
f->spawn_max_nearby_mobs = 5;
f->spawn_group = 3;
f->hp = 5;
f->lifetime = 1200.0;
f->setCollisionBox(aabb3f(-0.25*BS, 0.25*BS, -0.25*BS, 0.25*BS, 0.75*BS, 0.25*BS));
@ -498,11 +634,8 @@ void content_mob_init()
f->motion = MM_SEEKER;
f->motion_type = MMT_SWIM;
f->moves_silently = true;
f->spawn_on = CONTENT_SAND;
f->spawn_in = CONTENT_WATERSOURCE;
f->spawn_min_height = -30;
f->spawn_max_height = -2;
f->spawn_max_nearby_mobs = 3;
f->notices_player = true;
f->attack_player_damage = 3;
f->attack_player_range = v3f(1,1,1);
@ -527,12 +660,8 @@ void content_mob_init()
f->tamed_mob = CONTENT_MOB_TAMEWOLF;
f->motion = MM_SEEKER;
f->motion_type = MMT_WALK;
f->spawn_on = CONTENT_WILDGRASS_LONG;
f->spawn_in = CONTENT_AIR;
f->spawn_min_height = 0;
f->spawn_max_height = 40;
f->spawn_max_light = LIGHT_MAX/2;
f->spawn_max_nearby_mobs = 3;
f->sound_punch = "mob-wolf-hit";
f->sound_spawn = "mob-wolf-spawn";
f->notices_player = true;
@ -563,6 +692,7 @@ void content_mob_init()
f->attack_mob_damage = 5;
f->attack_mob_range = v3f(1,1,1);
f->lifetime = 1800.0;
f->spawn_naturally = false;
f->setCollisionBox(aabb3f(-0.5*BS, 0., -0.5*BS, 0.5*BS, 1.*BS, 0.5*BS));
i = CONTENT_MOB_SHEEP;
@ -588,12 +718,9 @@ void content_mob_init()
f->motion_type = MMT_WALK;
f->sound_random = "mob-sheep-env";
f->sound_random_extra = "mob-ducksheep-env";
f->spawn_on = CONTENT_WILDGRASS_SHORT;
f->spawn_in = CONTENT_AIR;
f->spawn_min_height = 2;
f->spawn_max_height = 50;
f->spawn_min_light = LIGHT_MAX/2;
f->spawn_max_nearby_mobs = 3;
f->spawn_group = 4;
f->lifetime = 1800.0;
f->setCollisionBox(aabb3f(-0.4*BS, 0., -0.4*BS, 0.4*BS, 1.*BS, 0.4*BS));
@ -613,6 +740,7 @@ void content_mob_init()
f->lifetime = 10.0;
f->contact_place_node = CONTENT_SNOW;
f->contact_drop_item = CONTENT_CRAFTITEM_SNOW_BALL;
f->spawn_naturally = false;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_ARROW;
@ -631,5 +759,6 @@ void content_mob_init()
f->attack_mob_range = v3f(1,1,1);
f->lifetime = 20.0;
f->contact_drop_item = CONTENT_CRAFTITEM_ARROW;
f->spawn_naturally = false;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
}

View File

@ -110,8 +110,6 @@ struct MobFeatures {
MobMotionType motion_type;
MobMotion angry_motion;
f32 static_thrown_speed;
content_t hunted_node;
content_t fleed_node;
bool notices_player;
content_t tamed_mob;
content_t attack_throw_object;
@ -141,16 +139,13 @@ struct MobFeatures {
std::string sound_random;
std::string sound_random_extra;
content_t spawn_on;
content_t spawn_in;
u8 spawn_min_light;
u8 spawn_max_light;
s16 spawn_min_height;
s16 spawn_max_height;
u8 spawn_max_nearby_mobs;
s16 spawn_chance;
s16 spawn_nearest_player;
s16 spawn_farthest_player;
s16 spawn_group;
bool spawn_water;
bool spawn_naturally;
MobFeatures()
{
@ -241,8 +236,6 @@ struct MobFeatures {
motion_type = MMT_WALK;
angry_motion = MM_STATIC;
static_thrown_speed = 20.0;
hunted_node = CONTENT_IGNORE;
fleed_node = CONTENT_IGNORE;
notices_player = false;
tamed_mob = CONTENT_IGNORE;
attack_throw_object = CONTENT_IGNORE;
@ -270,16 +263,12 @@ struct MobFeatures {
sound_punch = "mob-dig";
sound_random = "";
sound_random_extra = "";
spawn_on = CONTENT_IGNORE;
spawn_in = CONTENT_IGNORE;
spawn_min_light = 0;
spawn_max_light = LIGHT_MAX;
spawn_min_height = -20000;
spawn_max_height = 100;
spawn_max_nearby_mobs = 3;
spawn_chance = 1;
spawn_nearest_player = 0;
spawn_farthest_player = 0;
spawn_group = 1;
spawn_water = false;
spawn_naturally = true;
}
};
@ -307,6 +296,9 @@ inline std::string mobLevelS(u8 level)
class ServerEnvironment;
bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_count);
void mob_spawn(v3s16 pos, content_t mob, ServerEnvironment *env);
void mob_spawn_passive(v3s16 pos, bool water, ServerEnvironment *env);
void mob_spawn_hostile(v3s16 pos, bool water, ServerEnvironment *env);
MobFeatures & content_mob_features(content_t i);
void content_mob_init();

View File

@ -517,7 +517,6 @@ void MobSAO::step(float dtime, bool send_recommended)
bool dont_move = false;
m_age += dtime;
m_last_sound += dtime;
/* die, but not in the middle of attacking someone */
if (m.lifetime > 0.0 && m_age >= m.lifetime && (!m.notices_player || m_disturbing_player == "")) {
@ -567,6 +566,8 @@ void MobSAO::step(float dtime, bool send_recommended)
}
}
m_last_sound += dtime;
if (m_last_sound > 30.0) {
m_last_sound -= 5.0;
if (m.sound_random != "" && myrand_range(0,10) == 0) {
@ -729,10 +730,10 @@ void MobSAO::step(float dtime, bool send_recommended)
}else{
m_walk_around = !m_walk_around;
if (m_walk_around) {
if (!disturbing_player || mot != MM_SEEKER)
m_walk_around_timer = 0.1*myrand_range(5,15);
if ((!m.notices_player && !disturbing_player) || mot != MM_SEEKER)
m_walk_around_timer = myrand_range(10,20);
}else{
m_walk_around_timer = 0.1*myrand_range(20,40);
m_walk_around_timer = myrand_range(10,20);
}
}
}else if (m_walk_around_timer > 10.0) {

View File

@ -988,35 +988,91 @@ void ServerEnvironment::step(float dtime)
active_object_count_wider += wblock->m_active_objects.size();
}
if (
active_object_count_wider < 2
&& block->has_spawn_area
&& (
block->last_spawn < m_time_of_day-6000
|| block->last_spawn > m_time_of_day+6000
)
) {
MapNode n = block->getNodeNoEx(block->spawn_area);
MapNode n1 = block->getNodeNoEx(block->spawn_area+v3s16(0,1,0));
MapNode n2 = block->getNodeNoEx(block->spawn_area+v3s16(0,2,0));
u8 light = n1.getLightBlend(getDayNightRatio());
if (block->water_spawn) {
if (n1.getContent() != CONTENT_WATERSOURCE || n2.getContent() != CONTENT_WATERSOURCE)
block->has_spawn_area = false;
}else{
if (
!content_features(n1.getContent()).air_equivalent
|| !content_features(n2.getContent()).air_equivalent
)
block->has_spawn_area = false;
}
if (block->has_spawn_area) {
// dawn, passive mobs spawn
if (m_time_of_day > 7000 && m_time_of_day < 8000) {
if (
(
n.getContent() == CONTENT_GRASS
|| n.getContent() == CONTENT_GRASS_AUTUMN
|| n.getContent() == CONTENT_GRASS_FOOTSTEPS
|| n.getContent() == CONTENT_GRASS_FOOTSTEPS_AUTUMN
|| n.getContent() == CONTENT_MUDSNOW
|| (
block->water_spawn
&& n.getContent() == CONTENT_SAND
)
) && (
light >= LIGHT_SPAWN_BRIGHT
)
) {
mob_spawn_passive(block->spawn_area+block->getPosRelative(),block->water_spawn,this);
}else if (n.getContent() == CONTENT_STONE && light <= LIGHT_SPAWN_DARK && block->getPosRelative().Y < -16) {
mob_spawn(block->spawn_area+block->getPosRelative(),CONTENT_MOB_RAT,this);
}
block->last_spawn = m_time_of_day;
// dusk, hostile mobs spawn, or fireflies
}else if (m_time_of_day > 19000 && m_time_of_day < 20000) {
if (light <= LIGHT_SPAWN_DARK) {
if (n.getContent() == CONTENT_STONE || n.getContent() == CONTENT_SAND) {
mob_spawn_hostile(block->spawn_area+block->getPosRelative(),block->water_spawn,this);
}else if (n1.getContent() == CONTENT_JUNGLEGRASS) {
mob_spawn(block->spawn_area+block->getPosRelative(),CONTENT_MOB_FIREFLY,this);
}
}
block->last_spawn = m_time_of_day;
}
}
}
v3s16 p0;
bool spawned = false;
for (p0.X=0; p0.X<MAP_BLOCKSIZE; p0.X++)
for (p0.Y=0; p0.Y<MAP_BLOCKSIZE; p0.Y++)
for (p0.Z=0; p0.Z<MAP_BLOCKSIZE; p0.Z++) {
v3s16 p = p0 + block->getPosRelative();
block->incNodeTicks(p0);
MapNode n = block->getNodeNoEx(p0);
if (!spawned && active_object_count_wider < 5) {
if (!block->has_spawn_area && content_features(n.getContent()).draw_type == CDT_CUBELIKE) {
MapNode n1 = block->getNodeNoEx(p0+v3s16(0,1,0));
bool spawnable = false;
switch (n.getContent()) {
case CONTENT_SAND:
if (n1.getContent() == CONTENT_WATERSOURCE)
spawnable = true;
break;
case CONTENT_STONE:
case CONTENT_MOSSYCOBBLE:
case CONTENT_WILDGRASS_SHORT:
case CONTENT_WILDGRASS_LONG:
case CONTENT_JUNGLETREE:
if (n1.getContent() == CONTENT_AIR)
spawnable = true;
break;
default:;
}
if (spawnable && content_mob_spawn(this,p,active_object_count_wider)) {
spawned = true;
active_object_count_wider++;
MapNode n2 = block->getNodeNoEx(p0+v3s16(0,2,0));
if (
content_features(n1.getContent()).air_equivalent
&& content_features(n2.getContent()).air_equivalent
) {
block->spawn_area = p0;
block->has_spawn_area = true;
block->water_spawn = false;
}else if (
n.getContent() == CONTENT_SAND
&& n1.getContent() == CONTENT_WATERSOURCE
&& n2.getContent() == CONTENT_WATERSOURCE
) {
block->spawn_area = p0;
block->has_spawn_area = true;
block->water_spawn = true;
}
}

View File

@ -50,6 +50,10 @@ extern u32 daynight_cache_ratios[DAYNIGHT_CACHE_COUNT];*/
// This brightness is reserved for sunlight
#define LIGHT_SUN 15
// these are used in mob spawning
#define LIGHT_SPAWN_BRIGHT 10
#define LIGHT_SPAWN_DARK 4
inline u8 diminish_light(u8 light)
{
if(light == 0)

View File

@ -38,18 +38,22 @@
*/
MapBlock::MapBlock(Map *parent, v3s16 pos, bool dummy):
m_parent(parent),
m_pos(pos),
m_modified(MOD_STATE_WRITE_NEEDED),
is_underground(false),
m_lighting_expired(true),
m_day_night_differs(false),
m_generated(false),
m_timestamp(BLOCK_TIMESTAMP_UNDEFINED),
m_usage_timer(0)
has_spawn_area(false),
spawn_area(0,0,0),
water_spawn(false),
last_spawn(0),
m_parent(parent),
m_pos(pos),
m_modified(MOD_STATE_WRITE_NEEDED),
is_underground(false),
m_lighting_expired(true),
m_day_night_differs(false),
m_generated(false),
m_timestamp(BLOCK_TIMESTAMP_UNDEFINED),
m_usage_timer(0)
{
data = NULL;
if(dummy == false)
if (dummy == false)
reallocate();
//m_spawn_timer = -10000;

View File

@ -539,6 +539,12 @@ public:
void serializeDiskExtra(std::ostream &os, u8 version);
void deSerializeDiskExtra(std::istream &is, u8 version);
// Used by the server env for mob spawning
bool has_spawn_area;
v3s16 spawn_area;
bool water_spawn;
u32 last_spawn;
private:
/*
Private methods