- /*
- Do stuff!
-
- Note that map modifications should be done using the event-
- making map methods so that the server gets information
- about them.
-
- Reading can be done quickly directly from the block.
-
- Everything should bind to inside this single content
- searching loop to keep things fast.
- */
- // TODO: Implement usage of ActiveBlockModifier
-
- // Find out how many objects the block contains
- //u32 active_object_count = block->m_static_objects.m_active.size();
- // Find out how many objects this and all the neighbors contain
- u32 active_object_count_wider = 0;
- for(s16 x=-1; x<=1; x++)
- for(s16 y=-1; y<=1; y++)
- for(s16 z=-1; z<=1; z++)
- {
- MapBlock *block = m_map->getBlockNoCreateNoEx(p+v3s16(x,y,z));
- if(block==NULL)
- continue;
- active_object_count_wider +=
- block->m_static_objects.m_active.size()
- + block->m_static_objects.m_stored.size();
-
- /*if(block->m_static_objects.m_stored.size() != 0){
- errorstream<<"ServerEnvironment::step(): "
- <<PP(block->getPos())<<" contains "
- <<block->m_static_objects.m_stored.size()
- <<" stored objects; "
- <<"when spawning objects, when counting active "
- <<"objects in wide area. relative position: "
- <<"("<<x<<","<<y<<","<<z<<")"<<std::endl;
- }*/
- }
-
- v3s16 p0;
- 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();
- MapNode n = block->getNodeNoEx(p0);
-
- /*
- Test something:
- Convert dirt under proper lighting to grass
- */
- if(n.getContent() == c_dirt)
- {
- if(myrand()%20 == 0)
- {
- MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
- if(m_gamedef->ndef()->get(n_top).light_propagates &&
- !m_gamedef->ndef()->get(n_top).isLiquid() &&
- n_top.getLightBlend(getDayNightRatio(),
- m_gamedef->ndef()) >= 13)
- {
- n.setContent(c_grass);
- m_map->addNodeWithEvent(p, n);
- }
- }
- }
- /*
- Convert grass into dirt if under something else than air
- */
- if(n.getContent() == c_grass)
- {
- //if(myrand()%20 == 0)
- {
- MapNode n_top = m_map->getNodeNoEx(p+v3s16(0,1,0));
- if(!m_gamedef->ndef()->get(n_top).light_propagates ||
- m_gamedef->ndef()->get(n_top).isLiquid())
- {
- n.setContent(c_dirt);
- m_map->addNodeWithEvent(p, n);
- }
- }
- }
- /*
- Rats spawn around regular trees
- */
- if(n.getContent() == c_tree ||
- n.getContent() == c_jungletree)
- {
- if(myrand()%200 == 0 && active_object_count_wider == 0)
- {
- v3s16 p1 = p + v3s16(myrand_range(-2, 2),
- 0, myrand_range(-2, 2));
- MapNode n1 = m_map->getNodeNoEx(p1);
- MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,-1,0));
- if(n1b.getContent() == c_grass &&
- n1.getContent() == CONTENT_AIR)
- {
- v3f pos = intToFloat(p1, BS);
- ServerActiveObject *obj = new RatSAO(this, pos);
- addActiveObject(obj);
- }
- }
- }
- /*
- Fun things spawn in caves and dungeons
- */
- if(n.getContent() == c_stone ||
- n.getContent() == c_mossycobble)
- {
- if(myrand()%200 == 0 && active_object_count_wider == 0)
- {
- v3s16 p1 = p + v3s16(0,1,0);
- MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,0));
- if(n1a.getLightBlend(getDayNightRatio(),
- m_gamedef->ndef()) <= 3){
- MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
- if(n1a.getContent() == CONTENT_AIR &&
- n1b.getContent() == CONTENT_AIR)
- {
- v3f pos = intToFloat(p1, BS);
- int i = myrand()%5;
- if(i == 0 || i == 1){
- actionstream<<"A dungeon master spawns at "
- <<PP(p1)<<std::endl;
- Settings properties;
- getMob_dungeon_master(properties);
- ServerActiveObject *obj = new MobV2SAO(
- this, pos, &properties);
- addActiveObject(obj);
- } else if(i == 2 || i == 3){
- actionstream<<"Rats spawn at "
- <<PP(p1)<<std::endl;
- for(int j=0; j<3; j++){
- ServerActiveObject *obj = new RatSAO(
- this, pos);
- addActiveObject(obj);
- }
- } else {
- actionstream<<"An oerkki spawns at "
- <<PP(p1)<<std::endl;
- ServerActiveObject *obj = new Oerkki1SAO(
- this, pos);
- addActiveObject(obj);
- }
- }
- }
- }
- }
- /*
- Make trees from saplings!
- */
- if(n.getContent() == c_sapling)
- {
- if(myrand()%50 == 0)
- {
- actionstream<<"A sapling grows into a tree at "
- <<PP(p)<<std::endl;
-
- core::map<v3s16, MapBlock*> modified_blocks;
- v3s16 tree_p = p;
- ManualMapVoxelManipulator vmanip(m_map);
- v3s16 tree_blockp = getNodeBlockPos(tree_p);
- vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
- bool is_apple_tree = myrand()%4 == 0;
- mapgen::make_tree(vmanip, tree_p, is_apple_tree,
- m_gamedef->ndef());
- 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());
- }
- m_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);
- }
- m_map->dispatchEvent(&event);
- }
- }
- }