some mob spawner optimisations

This commit is contained in:
darkrose 2015-01-25 03:08:42 +10:00
parent 171bc1e9b4
commit 3732082cc1
3 changed files with 75 additions and 54 deletions

View File

@ -29,17 +29,23 @@
#include "map.h"
#include "profiler.h"
std::map<content_t,struct MobFeatures> g_content_mob_features;
MobFeatures g_content_mob_features[CONTENT_MOB_COUNT];
MobFeatures & content_mob_features(content_t i)
MobFeatures & content_mob_features(content_t c)
{
if ((i&CONTENT_MOB_MASK) != CONTENT_MOB_MASK)
return g_content_mob_features[CONTENT_IGNORE];
static MobFeatures ignore = MobFeatures();
if ((c&CONTENT_MOB_MASK) != CONTENT_MOB_MASK)
return ignore;
std::map<content_t,struct MobFeatures>::iterator it = g_content_mob_features.find(i);
if (it == g_content_mob_features.end())
return g_content_mob_features[CONTENT_IGNORE];
return it->second;
u16 i = (c&~CONTENT_MOB_MASK);
if (i >= CONTENT_MOB_COUNT)
return ignore;
if (g_content_mob_features[i].content != c)
return ignore;
return g_content_mob_features[i];
}
#ifndef SERVER
@ -132,9 +138,8 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_coun
if (nearest)
distance = pf.getDistanceFrom(nearest->getPosition());
/* TODO: this loop is what's causing lag */
for (std::map<content_t,struct MobFeatures>::iterator i = g_content_mob_features.begin(); i != g_content_mob_features.end(); i++) {
MobFeatures m = i->second;
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)
@ -167,7 +172,7 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_coun
}
if (m.spawn_chance > 1 && rand%m.spawn_chance != 0)
continue;
can.push_back(i->first);
can.push_back(i);
}
if (can.size() == 0)
@ -197,13 +202,11 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_coun
void content_mob_init()
{
g_content_mob_features.clear();
content_t i;
MobFeatures *f = NULL;
i = CONTENT_MOB_RAT;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_PASSIVE;
f->model = "rat.x";
@ -216,11 +219,11 @@ void content_mob_init()
f->spawn_in = CONTENT_AIR;
f->spawn_max_height = -10;
f->spawn_max_nearby_mobs = 4;
f->lifetime = 1200.0;
f->lifetime = 900.0;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_FIREFLY;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_PASSIVE;
f->model_scale = v3f(0.5,0.5,0.5);
@ -240,7 +243,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-BS/4.,-BS/6.,-BS/4., BS/4.,BS/6.,BS/4.));
i = CONTENT_MOB_OERKKI;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_AGGRESSIVE;
if (g_settings->getBool("enable_supernatural")) {
@ -291,7 +294,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.));
i = CONTENT_MOB_DUNGEON_MASTER;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_DESTRUCTIVE;
if (g_settings->getBool("enable_supernatural")) {
@ -345,7 +348,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-0.75*BS, 0.*BS, -0.75*BS, 0.75*BS, 2.0*BS, 0.75*BS));
i = CONTENT_MOB_FIREBALL;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_DESTRUCTIVE;
f->setTexture("mob_fireball.png");
@ -360,7 +363,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_DOE;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_PASSIVE;
f->hp = 30;
@ -382,11 +385,11 @@ void content_mob_init()
f->spawn_max_height = 40;
f->spawn_min_light = LIGHT_MAX/2;
f->spawn_max_nearby_mobs = 3;
f->lifetime = 900.0;
f->lifetime = 1200.0;
f->setCollisionBox(aabb3f(-0.6*BS, 0., -0.6*BS, 0.6*BS, 1.25*BS, 0.6*BS));
i = CONTENT_MOB_STAG;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_AGGRESSIVE;
f->hp = 40;
@ -418,7 +421,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-0.7*BS, 0., -0.7*BS, 0.7*BS, 1.5*BS, 0.7*BS));
i = CONTENT_MOB_TAMESTAG;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_PASSIVE;
f->hp = 40;
@ -435,11 +438,11 @@ void content_mob_init()
f->motion = MM_SEEKER;
f->motion_type = MMT_WALK;
f->notices_player = true;
f->lifetime = 900.0;
f->lifetime = 1800.0;
f->setCollisionBox(aabb3f(-0.7*BS, 0., -0.7*BS, 0.7*BS, 1.5*BS, 0.7*BS));
i = CONTENT_MOB_FISH;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_PASSIVE;
f->model = "fish.b3d";
@ -465,7 +468,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-0.25*BS, 0.25*BS, -0.25*BS, 0.25*BS, 0.75*BS, 0.25*BS));
i = CONTENT_MOB_SHARK;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_AGGRESSIVE;
f->hp = 40;
@ -493,7 +496,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-0.75*BS, 0., -0.75*BS, 0.75*BS, 1.*BS, 0.75*BS));
i = CONTENT_MOB_WOLF;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_AGGRESSIVE;
f->hp = 40;
@ -522,7 +525,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-0.5*BS, 0., -0.5*BS, 0.5*BS, 1.*BS, 0.5*BS));
i = CONTENT_MOB_TAMEWOLF;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_PASSIVE;
f->hp = 40;
@ -541,11 +544,11 @@ void content_mob_init()
f->notices_player = true;
f->attack_mob_damage = 5;
f->attack_mob_range = v3f(1,1,1);
f->lifetime = 900.0;
f->lifetime = 1800.0;
f->setCollisionBox(aabb3f(-0.5*BS, 0., -0.5*BS, 0.5*BS, 1.*BS, 0.5*BS));
i = CONTENT_MOB_SHEEP;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_PASSIVE;
f->hp = 30;
@ -571,11 +574,11 @@ void content_mob_init()
f->spawn_max_height = 50;
f->spawn_min_light = LIGHT_MAX/2;
f->spawn_max_nearby_mobs = 3;
f->lifetime = 900.0;
f->lifetime = 1800.0;
f->setCollisionBox(aabb3f(-0.4*BS, 0., -0.4*BS, 0.4*BS, 1.*BS, 0.4*BS));
i = CONTENT_MOB_SNOWBALL;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_AGGRESSIVE;
f->setTexture("snow_ball.png");
@ -592,7 +595,7 @@ void content_mob_init()
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_ARROW;
f = &g_content_mob_features[i];
f = &g_content_mob_features[i&~CONTENT_MOB_MASK];
f->content = i;
f->level = MOB_AGGRESSIVE;
f->setTexture("mob_arrow.png");

View File

@ -319,4 +319,7 @@ void content_mob_init();
#define CONTENT_MOB_SNOWBALL (CONTENT_MOB_MASK | 0x0E)
#define CONTENT_MOB_ARROW (CONTENT_MOB_MASK | 0x0F)
// increment me if you add a mob!
#define CONTENT_MOB_COUNT 16
#endif

View File

@ -959,35 +959,48 @@ void ServerEnvironment::step(float dtime)
if (wblock == NULL)
continue;
active_object_count_wider += wblock->m_static_objects.m_stored.size();
}
for (std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
ServerActiveObject* obj = i->second;
if (obj->m_removed)
continue;
v3s16 obp = getNodeBlockPos(floatToInt(obj->getBasePosition(), BS));
if (obp.X > bp.X+1 || obp.X < bp.X-1)
continue;
if (obp.Y > bp.Y+1 || obp.Y < bp.Y-1)
continue;
if (obp.Z > bp.Z+1 || obp.Z < bp.Z-1)
continue;
active_object_count_wider++;
active_object_count_wider += wblock->m_static_objects.m_active.size();
}
if (active_object_count_wider < 10) {
v3s16 p = v3s16(myrand_range(0,MAP_BLOCKSIZE),myrand_range(0,MAP_BLOCKSIZE),myrand_range(0,MAP_BLOCKSIZE));
p += block->getPosRelative();
if (content_mob_spawn(this,p,active_object_count_wider))
active_object_count_wider++;
}
//if (active_object_count_wider < 10) {
//v3s16 p = v3s16(myrand_range(0,MAP_BLOCKSIZE),myrand_range(0,MAP_BLOCKSIZE),myrand_range(0,MAP_BLOCKSIZE));
//p += block->getPosRelative();
//printf("spawn at: %d %d %d\n",p.X,p.Y,p.Z);
//if (content_mob_spawn(this,p,active_object_count_wider))
//active_object_count_wider++;
//}
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 < 10) {
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++;
}
}
switch(n.getContent()) {
case CONTENT_GRASS_FOOTSTEPS:
@ -3523,7 +3536,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
core::map<u16, StaticObject>::Node *n = block->m_static_objects.m_active.find(id);
if (n != NULL) {
StaticObject static_old = n->getValue();
if (static_old.data == staticdata_new)
if (static_old.data == staticdata_new && obj->m_static_block == blockpos)
will_write = false;
}
block->m_static_objects.remove(id);
@ -3545,6 +3558,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
if (block) {
if (block->m_static_objects.m_stored.size() < 50) {
if (id && block->m_static_objects.m_active.find(id) != NULL)
block->m_static_objects.remove(id);
// Store static data
block->m_static_objects.insert(0, s_obj);