+void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
+{
+ // Get time difference
+ u32 dtime_s = 0;
+ u32 stamp = block->getTimestamp();
+ if(m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED)
+ dtime_s = m_game_time - block->getTimestamp();
+ dtime_s += additional_dtime;
+
+ // Set current time as timestamp (and let it set ChangedFlag)
+ block->setTimestamp(m_game_time);
+
+ //infostream<<"Block is "<<dtime_s<<" seconds old."<<std::endl;
+
+ // Activate stored objects
+ activateObjects(block);
+
+ // Run node metadata
+ bool changed = block->m_node_metadata->step((float)dtime_s);
+ if(changed)
+ {
+ MapEditEvent event;
+ event.type = MEET_BLOCK_NODE_METADATA_CHANGED;
+ event.p = block->getPos();
+ m_map->dispatchEvent(&event);
+
+ block->setChangedFlag();
+ }
+
+ // TODO: Do something
+ // TODO: Implement usage of ActiveBlockModifier
+
+ // Here's a quick demonstration
+ 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);
+#if 1
+ // Test something:
+ // Convert all mud under proper day lighting to grass
+ if(n.getContent() == CONTENT_MUD)
+ {
+ if(dtime_s > 300)
+ {
+ MapNode n_top = block->getNodeNoEx(p0+v3s16(0,1,0));
+ if(content_features(n_top).air_equivalent &&
+ n_top.getLight(LIGHTBANK_DAY) >= 13)
+ {
+ n.setContent(CONTENT_GRASS);
+ m_map->addNodeWithEvent(p, n);
+ }
+ }
+ }
+#endif
+ }
+}
+
+void ServerEnvironment::clearAllObjects()
+{
+ infostream<<"ServerEnvironment::clearAllObjects(): "
+ <<"Removing all active objects"<<std::endl;
+ core::list<u16> objects_to_remove;
+ for(core::map<u16, ServerActiveObject*>::Iterator
+ i = m_active_objects.getIterator();
+ i.atEnd()==false; i++)
+ {
+ ServerActiveObject* obj = i.getNode()->getValue();
+ u16 id = i.getNode()->getKey();
+ v3f objectpos = obj->getBasePosition();
+ // Delete static object if block is loaded
+ if(obj->m_static_exists){
+ MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block);
+ if(block){
+ block->m_static_objects.remove(id);
+ block->raiseModified(MOD_STATE_WRITE_NEEDED);
+ obj->m_static_exists = false;
+ }
+ }
+ // If known by some client, don't delete immediately
+ if(obj->m_known_by_count > 0){
+ obj->m_pending_deactivation = true;
+ obj->m_removed = true;
+ continue;
+ }
+ // Deregister in scripting api
+ scriptapi_rm_object_reference(m_lua, obj);
+ // Delete active object
+ delete obj;
+ // Id to be removed from m_active_objects
+ objects_to_remove.push_back(id);
+ }
+ // Remove references from m_active_objects
+ for(core::list<u16>::Iterator i = objects_to_remove.begin();
+ i != objects_to_remove.end(); i++)
+ {
+ m_active_objects.remove(*i);
+ }
+
+ core::list<v3s16> loadable_blocks;
+ infostream<<"ServerEnvironment::clearAllObjects(): "
+ <<"Listing all loadable blocks"<<std::endl;
+ m_map->listAllLoadableBlocks(loadable_blocks);
+ infostream<<"ServerEnvironment::clearAllObjects(): "
+ <<"Done listing all loadable blocks: "
+ <<loadable_blocks.size()
+ <<", now clearing"<<std::endl;
+ u32 report_interval = loadable_blocks.size() / 10;
+ u32 num_blocks_checked = 0;
+ u32 num_blocks_cleared = 0;
+ u32 num_objs_cleared = 0;
+ for(core::list<v3s16>::Iterator i = loadable_blocks.begin();
+ i != loadable_blocks.end(); i++)
+ {
+ v3s16 p = *i;
+ MapBlock *block = m_map->emergeBlock(p, false);
+ if(!block){
+ errorstream<<"ServerEnvironment::clearAllObjects(): "
+ <<"Failed to emerge block "<<PP(p)<<std::endl;
+ continue;
+ }
+ u32 num_stored = block->m_static_objects.m_stored.size();
+ u32 num_active = block->m_static_objects.m_active.size();
+ if(num_stored != 0 || num_active != 0){
+ block->m_static_objects.m_stored.clear();
+ block->m_static_objects.m_active.clear();
+ block->raiseModified(MOD_STATE_WRITE_NEEDED);
+ num_objs_cleared += num_stored + num_active;
+ num_blocks_cleared++;
+ }
+ num_blocks_checked++;
+
+ if(num_blocks_checked % report_interval == 0){
+ float percent = 100.0 * (float)num_blocks_checked /
+ loadable_blocks.size();
+ infostream<<"ServerEnvironment::clearAllObjects(): "
+ <<"Cleared "<<num_objs_cleared<<" objects"
+ <<" in "<<num_blocks_cleared<<" blocks ("
+ <<percent<<"%)"<<std::endl;
+ }
+ }
+ infostream<<"ServerEnvironment::clearAllObjects(): "
+ <<"Finished: Cleared "<<num_objs_cleared<<" objects"
+ <<" in "<<num_blocks_cleared<<" blocks"<<std::endl;
+}
+
+static void getMob_dungeon_master(Settings &properties)
+{
+ properties.set("looks", "dungeon_master");
+ properties.setFloat("yaw", 1.57);
+ properties.setFloat("hp", 30);
+ properties.setBool("bright_shooting", true);
+ properties.set("shoot_type", "fireball");
+ properties.set("shoot_y", "0.7");
+ properties.set("player_hit_damage", "1");
+ properties.set("player_hit_distance", "1.0");
+ properties.set("player_hit_interval", "0.5");
+ properties.setBool("mindless_rage", myrand_range(0,100)==0);
+}
+