@@ -1417,8 +1417,8 @@ void ServerEnvironment::getAddedActiveObjects(v3s16 pos, s16 radius,
1417
1417
ServerActiveObject *object = i->second ;
1418
1418
if (object == NULL )
1419
1419
continue ;
1420
- // Discard if removed
1421
- if (object->m_removed )
1420
+ // Discard if removed or deactivating
1421
+ if (object->m_removed || object-> m_pending_deactivation )
1422
1422
continue ;
1423
1423
if (object->unlimitedTransferDistance () == false ){
1424
1424
// Discard if too far
@@ -1468,7 +1468,7 @@ void ServerEnvironment::getRemovedActiveObjects(v3s16 pos, s16 radius,
1468
1468
continue ;
1469
1469
}
1470
1470
1471
- if (object->m_removed )
1471
+ if (object->m_removed || object-> m_pending_deactivation )
1472
1472
{
1473
1473
removed_objects.insert (id);
1474
1474
continue ;
@@ -1556,21 +1556,19 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
1556
1556
StaticObject s_obj (object->getType (), objectpos, staticdata);
1557
1557
// Add to the block where the object is located in
1558
1558
v3s16 blockpos = getNodeBlockPos (floatToInt (objectpos, BS));
1559
- MapBlock *block = m_map->getBlockNoCreateNoEx (blockpos);
1560
- if (block)
1561
- {
1559
+ MapBlock *block = m_map->emergeBlock (blockpos);
1560
+ if (block){
1562
1561
block->m_static_objects .m_active [object->getId ()] = s_obj;
1563
1562
object->m_static_exists = true ;
1564
1563
object->m_static_block = blockpos;
1565
1564
1566
1565
if (set_changed)
1567
1566
block->raiseModified (MOD_STATE_WRITE_NEEDED,
1568
1567
" addActiveObjectRaw" );
1569
- }
1570
- else {
1568
+ } else {
1571
1569
v3s16 p = floatToInt (objectpos, BS);
1572
1570
errorstream<<" ServerEnvironment::addActiveObjectRaw(): "
1573
- <<" could not find block for storing id=" <<object->getId ()
1571
+ <<" could not emerge block for storing id=" <<object->getId ()
1574
1572
<<" statically (pos=" <<PP (p)<<" )" <<std::endl;
1575
1573
}
1576
1574
}
@@ -1616,18 +1614,39 @@ void ServerEnvironment::removeRemovedObjects()
1616
1614
if (block) {
1617
1615
block->m_static_objects .remove (id);
1618
1616
block->raiseModified (MOD_STATE_WRITE_NEEDED,
1619
- " removeRemovedObjects" );
1617
+ " removeRemovedObjects/remove " );
1620
1618
obj->m_static_exists = false ;
1621
1619
} else {
1622
- infostream << " failed to emerge block from which "
1623
- " an object to be removed was loaded from. id=" <<id<<std::endl;
1620
+ infostream<< " Failed to emerge block from which an object to "
1621
+ << " be removed was loaded from. id=" <<id<<std::endl;
1624
1622
}
1625
1623
}
1626
1624
1627
- // If m_known_by_count > 0, don't actually remove.
1625
+ // If m_known_by_count > 0, don't actually remove. On some future
1626
+ // invocation this will be 0, which is when removal will continue.
1628
1627
if (obj->m_known_by_count > 0 )
1629
1628
continue ;
1630
-
1629
+
1630
+ /*
1631
+ Move static data from active to stored if not marked as removed
1632
+ */
1633
+ if (obj->m_static_exists && !obj->m_removed ){
1634
+ MapBlock *block = m_map->emergeBlock (obj->m_static_block , false );
1635
+ if (block) {
1636
+ std::map<u16, StaticObject>::iterator i =
1637
+ block->m_static_objects .m_active .find (id);
1638
+ if (i != block->m_static_objects .m_active .end ()){
1639
+ block->m_static_objects .m_stored .push_back (i->second );
1640
+ block->m_static_objects .m_active .erase (id);
1641
+ block->raiseModified (MOD_STATE_WRITE_NEEDED,
1642
+ " removeRemovedObjects/deactivate" );
1643
+ }
1644
+ } else {
1645
+ infostream<<" Failed to emerge block from which an object to "
1646
+ <<" be deactivated was loaded from. id=" <<id<<std::endl;
1647
+ }
1648
+ }
1649
+
1631
1650
// Tell the object about removal
1632
1651
obj->removingFromEnvironment ();
1633
1652
// Deregister in scripting api
@@ -1708,10 +1727,9 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
1708
1727
" large amount of objects" );
1709
1728
return ;
1710
1729
}
1711
- // A list for objects that couldn't be converted to active for some
1712
- // reason. They will be stored back.
1730
+
1731
+ // Activate stored objects
1713
1732
std::list<StaticObject> new_stored;
1714
- // Loop through stored static objects
1715
1733
for (std::list<StaticObject>::iterator
1716
1734
i = block->m_static_objects .m_stored .begin ();
1717
1735
i != block->m_static_objects .m_stored .end (); ++i)
@@ -1750,6 +1768,19 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
1750
1768
StaticObject &s_obj = *i;
1751
1769
block->m_static_objects .m_stored .push_back (s_obj);
1752
1770
}
1771
+
1772
+ // Turn the active counterparts of activated objects not pending for
1773
+ // deactivation
1774
+ for (std::map<u16, StaticObject>::iterator
1775
+ i = block->m_static_objects .m_active .begin ();
1776
+ i != block->m_static_objects .m_active .end (); ++i)
1777
+ {
1778
+ u16 id = i->first ;
1779
+ ServerActiveObject *object = getActiveObject (id);
1780
+ assert (object);
1781
+ object->m_pending_deactivation = false ;
1782
+ }
1783
+
1753
1784
/*
1754
1785
Note: Block hasn't really been modified here.
1755
1786
The objects have just been activated and moved from the stored
@@ -1910,6 +1941,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
1910
1941
block = m_map->emergeBlock (blockpos);
1911
1942
} catch (InvalidPositionException &e){
1912
1943
// Handled via NULL pointer
1944
+ // NOTE: emergeBlock's failure is usually determined by it
1945
+ // actually returning NULL
1913
1946
}
1914
1947
1915
1948
if (block)
@@ -1923,17 +1956,21 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
1923
1956
<<" Forcing delete." <<std::endl;
1924
1957
force_delete = true ;
1925
1958
} else {
1926
- // If static counterpart already exists, remove it first.
1927
- // This shouldn't happen, but happens rarely for some
1928
- // unknown reason. Unsuccessful attempts have been made to
1929
- // find said reason.
1959
+ // If static counterpart already exists in target block,
1960
+ // remove it first.
1961
+ // This shouldn't happen because the object is removed from
1962
+ // the previous block before this according to
1963
+ // obj->m_static_block, but happens rarely for some unknown
1964
+ // reason. Unsuccessful attempts have been made to find
1965
+ // said reason.
1930
1966
if (id && block->m_static_objects .m_active .find (id) != block->m_static_objects .m_active .end ()){
1931
1967
infostream<<" ServerEnv: WARNING: Performing hack #83274"
1932
1968
<<std::endl;
1933
1969
block->m_static_objects .remove (id);
1934
1970
}
1935
- // store static data
1936
- block->m_static_objects .insert (0 , s_obj);
1971
+ // Store static data
1972
+ u16 store_id = pending_delete ? id : 0 ;
1973
+ block->m_static_objects .insert (store_id, s_obj);
1937
1974
1938
1975
// Only mark block as modified if data changed considerably
1939
1976
if (shall_be_written)
0 commit comments