From 70636b3b4a18a50a8a7750973511056be15a58e7 Mon Sep 17 00:00:00 2001 From: darkrose Date: Sun, 13 Sep 2015 05:46:03 +1000 Subject: [PATCH] improved mob spawning, pt1 --- data/models/stag.x | 1 - src/content_mob.cpp | 273 ++++++++++++++++++++++++++++++++------------ src/content_mob.h | 28 ++--- src/content_sao.cpp | 9 +- src/environment.cpp | 98 ++++++++++++---- src/light.h | 4 + src/mapblock.cpp | 24 ++-- src/mapblock.h | 6 + 8 files changed, 317 insertions(+), 126 deletions(-) diff --git a/data/models/stag.x b/data/models/stag.x index d2c0bc2..6191e3c 100644 --- a/data/models/stag.x +++ b/data/models/stag.x @@ -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 { diff --git a/src/content_mob.cpp b/src/content_mob.cpp index ec61bea..96928f0 100644 --- a/src/content_mob.cpp +++ b/src/content_mob.cpp @@ -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 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 "<addActiveObject(obj); + if (!id) { + actionstream<<"A mob of type "<addEnvEvent(ENV_EVENT_SOUND,p,m.sound_spawn); +} + +void mob_spawn_passive(v3s16 pos, bool water, ServerEnvironment *env) +{ + std::vector can; + int rand = myrand(); + for (u16 i=0; i 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 can; + int rand = myrand(); + u8 level = mobLevelI(g_settings->get("max_mob_level")); + if (level < MOB_AGGRESSIVE) + return; + for (u16 i=0; i 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.)); } diff --git a/src/content_mob.h b/src/content_mob.h index 834c879..85486c3 100644 --- a/src/content_mob.h +++ b/src/content_mob.h @@ -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(); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index d9776b8..2b8f787 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -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) { diff --git a/src/environment.cpp b/src/environment.cpp index b7446b7..a90fddd 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -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.XgetPosRelative(); 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; } } diff --git a/src/light.h b/src/light.h index 72264c8..eeea7d2 100644 --- a/src/light.h +++ b/src/light.h @@ -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) diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 99d14a4..8fa7b23 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -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; diff --git a/src/mapblock.h b/src/mapblock.h index 42ff6e2..b523f1e 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -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