X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fenvironment.cpp;h=3a294086c8ac78a6ee19b9bce7cff7a17868a76c;hb=6d4bc012f007a0aa63d7f917891d355d680b4a1b;hp=3a11b4acf469e81b082201ecc4d18564b8c45b34;hpb=fadf248892eae825b57d283032594ed924d8dbea;p=dragonfireclient.git diff --git a/src/environment.cpp b/src/environment.cpp index 3a11b4acf..3a294086c 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodemetadata.h" #include "main.h" // For g_settings, g_profiler #include "gamedef.h" +#include "serverremoteplayer.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -202,6 +203,22 @@ u32 Environment::getDayNightRatio() return time_to_daynight_ratio(m_time_of_day); } +/* + ABMWithState +*/ + +ABMWithState::ABMWithState(ActiveBlockModifier *abm_): + abm(abm_), + timer(0) +{ + // Initialize timer to random value to spread processing + float itv = abm->getTriggerInterval(); + itv = MYMAX(0.001, itv); // No less than 1ms + int minval = MYMAX(-0.51*itv, -60); // Clamp to + int maxval = MYMIN(0.51*itv, 60); // +-60 seconds + timer = myrand_range(minval, maxval); +} + /* ActiveBlockList */ @@ -472,6 +489,8 @@ void ServerEnvironment::deSerializePlayers(const std::string &savedir) newplayer = true; } + ServerRemotePlayer *srp = static_cast(player); + // Load player { infostream<<"Reading player "<deSerialize(is); + srp->deSerialize(is); + srp->m_last_good_position = srp->getBasePosition(); + srp->m_last_good_position_age = 0; } if(newplayer) + { addPlayer(player); + } } } @@ -558,6 +581,7 @@ struct ActiveABM { ActiveBlockModifier *abm; int chance; + std::set required_neighbors; }; class ABMHandler @@ -580,21 +604,35 @@ class ABMHandler float trigger_interval = abm->getTriggerInterval(); if(trigger_interval < 0.001) trigger_interval = 0.001; + float actual_interval = dtime_s; if(use_timers){ i->timer += dtime_s; if(i->timer < trigger_interval) continue; i->timer -= trigger_interval; + actual_interval = trigger_interval; } ActiveABM aabm; aabm.abm = abm; - float intervals = dtime_s / trigger_interval; + float intervals = actual_interval / trigger_interval; float chance = abm->getTriggerChance(); if(chance == 0) chance = 1; - aabm.chance = 1.0 / pow(1.0 / chance, intervals); + aabm.chance = 1.0 / pow((float)1.0/chance, (float)intervals); if(aabm.chance == 0) aabm.chance = 1; + // Trigger neighbors + std::set required_neighbors_s + = abm->getRequiredNeighbors(); + for(std::set::iterator + i = required_neighbors_s.begin(); + i != required_neighbors_s.end(); i++){ + content_t c = ndef->getId(*i); + if(c == CONTENT_IGNORE) + continue; + aabm.required_neighbors.insert(c); + } + // Trigger contents std::set contents_s = abm->getTriggerContents(); for(std::set::iterator i = contents_s.begin(); i != contents_s.end(); i++){ @@ -618,22 +656,6 @@ class ABMHandler return; ServerMap *map = &m_env->getServerMap(); - // 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 *block2 = map->getBlockNoCreateNoEx( - block->getPos() + v3s16(x,y,z)); - if(block2==NULL) - continue; - active_object_count_wider += - block2->m_static_objects.m_active.size() - + block2->m_static_objects.m_stored.size(); - } v3s16 p0; for(p0.X=0; p0.X::iterator - i = j->second.begin(); i != j->second.end(); i++){ + i = j->second.begin(); i != j->second.end(); i++) + { if(myrand() % i->chance != 0) continue; + + // Check neighbors + if(!i->required_neighbors.empty()) + { + v3s16 p1; + for(p1.X = p.X-1; p1.X <= p.X+1; p1.X++) + for(p1.Y = p.Y-1; p1.Y <= p.Y+1; p1.Y++) + for(p1.Z = p.Z-1; p1.Z <= p.Z+1; p1.Z++) + { + if(p1 == p) + continue; + MapNode n = map->getNodeNoEx(p1); + content_t c = n.getContent(); + std::set::const_iterator k; + k = i->required_neighbors.find(c); + if(k != i->required_neighbors.end()){ + goto neighbor_found; + } + } + // No required neighbor found + continue; + } +neighbor_found: + + // 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 *block2 = map->getBlockNoCreateNoEx( + block->getPos() + v3s16(x,y,z)); + if(block2==NULL) + continue; + active_object_count_wider += + block2->m_static_objects.m_active.size() + + block2->m_static_objects.m_stored.size(); + } + // Call all the trigger variations i->abm->trigger(m_env, p, n); i->abm->trigger(m_env, p, n, @@ -671,14 +735,14 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime) dtime_s = m_game_time - block->getTimestamp(); dtime_s += additional_dtime; - infostream<<"ServerEnvironment::activateBlock(): block timestamp: " - <setTimestampNoChangedFlag(m_game_time); - infostream<<"ServerEnvironment::activateBlock(): block is " - < ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius) +{ + std::set objects; + for(core::map::Iterator + i = m_active_objects.getIterator(); + i.atEnd()==false; i++) + { + ServerActiveObject* obj = i.getNode()->getValue(); + u16 id = i.getNode()->getKey(); + v3f objectpos = obj->getBasePosition(); + if(objectpos.getDistanceFrom(pos) > radius) + continue; + objects.insert(id); + } + return objects; +} + void ServerEnvironment::clearAllObjects() { infostream<<"ServerEnvironment::clearAllObjects(): " @@ -734,10 +815,15 @@ void ServerEnvironment::clearAllObjects() obj->m_removed = true; continue; } + + // Tell the object about removal + obj->removingFromEnvironment(); // Deregister in scripting api scriptapi_rm_object_reference(m_lua, obj); + // Delete active object - delete obj; + if(obj->environmentDeletes()) + delete obj; // Id to be removed from m_active_objects objects_to_remove.push_back(id); } @@ -1168,7 +1254,8 @@ bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj) succeeded = false; } - delete obj; + if(obj->environmentDeletes()) + delete obj; return succeeded; } @@ -1202,10 +1289,12 @@ void ServerEnvironment::getAddedActiveObjects(v3s16 pos, s16 radius, // Discard if removed if(object->m_removed) continue; - // Discard if too far - f32 distance_f = object->getBasePosition().getDistanceFrom(pos_f); - if(distance_f > radius_f) - continue; + if(object->unlimitedTransferDistance() == false){ + // Discard if too far + f32 distance_f = object->getBasePosition().getDistanceFrom(pos_f); + if(distance_f > radius_f) + continue; + } // Discard if already on current_objects core::map::Node *n; n = current_objects.find(id); @@ -1240,24 +1329,33 @@ void ServerEnvironment::getRemovedActiveObjects(v3s16 pos, s16 radius, { u16 id = i.getNode()->getKey(); ServerActiveObject *object = getActiveObject(id); - if(object == NULL) - { + + if(object == NULL){ infostream<<"ServerEnvironment::getRemovedActiveObjects():" <<" object in current_objects is NULL"<m_removed == false) + + if(object->m_removed) { - f32 distance_f = object->getBasePosition().getDistanceFrom(pos_f); - /*infostream<<"removed == false" - <<"distance_f = "<environmentDeletes()) + delete object; return 0; } object->setId(new_id); @@ -1296,7 +1395,8 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, { errorstream<<"ServerEnvironment::addActiveObjectRaw(): " <<"id is not free ("<getId()<<")"<environmentDeletes()) + delete object; return 0; } /*infostream<<"ServerEnvironment::addActiveObjectRaw(): " @@ -1309,34 +1409,38 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object, <getBasePosition(); - std::string staticdata = object->getStaticData(); - StaticObject s_obj(object->getType(), objectpos, staticdata); - // Add to the block where the object is located in - v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); - MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); - if(block) - { - block->m_static_objects.m_active.insert(object->getId(), s_obj); - object->m_static_exists = true; - object->m_static_block = blockpos; - - if(set_changed) - block->raiseModified(MOD_STATE_WRITE_NEEDED, - "addActiveObjectRaw"); - } - else{ - errorstream<<"ServerEnvironment::addActiveObjectRaw(): " - <<"could not find block for storing id="<getId() - <<" statically"<addedToEnvironment(); + + // Add static data to block + if(object->isStaticAllowed()) + { + // Add static object to active static list of the block + v3f objectpos = object->getBasePosition(); + std::string staticdata = object->getStaticData(); + StaticObject s_obj(object->getType(), objectpos, staticdata); + // Add to the block where the object is located in + v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); + MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); + if(block) + { + block->m_static_objects.m_active.insert(object->getId(), s_obj); + object->m_static_exists = true; + object->m_static_block = blockpos; + if(set_changed) + block->raiseModified(MOD_STATE_WRITE_NEEDED, + "addActiveObjectRaw"); + } + else{ + errorstream<<"ServerEnvironment::addActiveObjectRaw(): " + <<"could not find block for storing id="<getId() + <<" statically"<getId(); } @@ -1388,11 +1492,14 @@ void ServerEnvironment::removeRemovedObjects() if(obj->m_known_by_count > 0) continue; + // Tell the object about removal + obj->removingFromEnvironment(); // Deregister in scripting api scriptapi_rm_object_reference(m_lua, obj); // Delete - delete obj; + if(obj->environmentDeletes()) + delete obj; // Id to be removed from m_active_objects objects_to_remove.push_back(id); } @@ -1534,18 +1641,14 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) i.atEnd()==false; i++) { ServerActiveObject* obj = i.getNode()->getValue(); - - // This shouldn't happen but check it - if(obj == NULL) - { - errorstream<<"NULL object found in ServerEnvironment" - <isStaticAllowed()) continue; - } // If pending deactivation, let removeRemovedObjects() do it - if(obj->m_pending_deactivation) + if(!force_delete && obj->m_pending_deactivation) continue; u16 id = i.getNode()->getKey(); @@ -1555,7 +1658,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS)); // If block is active, don't remove - if(m_active_blocks.contains(blockpos_o)) + if(!force_delete && m_active_blocks.contains(blockpos_o)) continue; verbosestream<<"ServerEnvironment::deactivateFarObjects(): " @@ -1569,89 +1672,94 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) Update the static data */ - // Create new static object - std::string staticdata_new = obj->getStaticData(); - StaticObject s_obj(obj->getType(), objectpos, staticdata_new); - - bool stays_in_same_block = false; - bool data_changed = true; + if(obj->isStaticAllowed()) + { + // Create new static object + std::string staticdata_new = obj->getStaticData(); + StaticObject s_obj(obj->getType(), objectpos, staticdata_new); + + bool stays_in_same_block = false; + bool data_changed = true; - if(obj->m_static_exists){ - if(obj->m_static_block == blockpos_o) - stays_in_same_block = true; + if(obj->m_static_exists){ + if(obj->m_static_block == blockpos_o) + stays_in_same_block = true; - MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); - - core::map::Node *n = - block->m_static_objects.m_active.find(id); - if(n){ - StaticObject static_old = n->getValue(); - - float save_movem = obj->getMinimumSavedMovement(); - - if(static_old.data == staticdata_new && - (static_old.pos - objectpos).getLength() < save_movem) - data_changed = false; - } else { - errorstream<<"ServerEnvironment::deactivateFarObjects(): " - <<"id="<m_static_block)<emergeBlock(obj->m_static_block, false); + + core::map::Node *n = + block->m_static_objects.m_active.find(id); + if(n){ + StaticObject static_old = n->getValue(); + + float save_movem = obj->getMinimumSavedMovement(); + + if(static_old.data == staticdata_new && + (static_old.pos - objectpos).getLength() < save_movem) + data_changed = false; + } else { + errorstream<<"ServerEnvironment::deactivateFarObjects(): " + <<"id="<m_static_block)<m_static_exists) - { - MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); - if(block) + bool shall_be_written = (!stays_in_same_block || data_changed); + + // Delete old static object + if(obj->m_static_exists) { - block->m_static_objects.remove(id); - obj->m_static_exists = false; - // Only mark block as modified if data changed considerably - if(shall_be_written) - block->raiseModified(MOD_STATE_WRITE_NEEDED, - "deactivateFarObjects: Static data " - "changed considerably"); + MapBlock *block = m_map->emergeBlock(obj->m_static_block, false); + if(block) + { + block->m_static_objects.remove(id); + obj->m_static_exists = false; + // Only mark block as modified if data changed considerably + if(shall_be_written) + block->raiseModified(MOD_STATE_WRITE_NEEDED, + "deactivateFarObjects: Static data " + "changed considerably"); + } } - } - // Add to the block where the object is located in - v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); - // Get or generate the block - MapBlock *block = m_map->emergeBlock(blockpos); + // Add to the block where the object is located in + v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); + // Get or generate the block + MapBlock *block = m_map->emergeBlock(blockpos); - if(block) - { - if(block->m_static_objects.m_stored.size() >= 49){ - errorstream<<"ServerEnv: Trying to store id="<getId() - <<" statically but block "<m_static_objects.m_stored.size() - <<" (over 49) objects." - <<" Forcing delete."<m_static_objects.insert(new_id, s_obj); - - // Only mark block as modified if data changed considerably - if(shall_be_written) - block->raiseModified(MOD_STATE_WRITE_NEEDED, - "deactivateFarObjects: Static data " - "changed considerably"); - - obj->m_static_exists = true; - obj->m_static_block = block->getPos(); + if(block) + { + if(block->m_static_objects.m_stored.size() >= 49){ + errorstream<<"ServerEnv: Trying to store id="<getId() + <<" statically but block "<m_static_objects.m_stored.size() + <<" (over 49) objects." + <<" Forcing delete."<m_static_objects.insert(new_id, s_obj); + + // Only mark block as modified if data changed considerably + if(shall_be_written) + block->raiseModified(MOD_STATE_WRITE_NEEDED, + "deactivateFarObjects: Static data " + "changed considerably"); + + obj->m_static_exists = true; + obj->m_static_block = block->getPos(); + } + } + else{ + if(!force_delete){ + errorstream<<"ServerEnv: Could not find or generate " + <<"a block for storing id="<getId() + <<" statically"<removingFromEnvironment(); // Deregister in scripting api scriptapi_rm_object_reference(m_lua, obj); // Delete active object - delete obj; + if(obj->environmentDeletes()) + delete obj; // Id to be removed from m_active_objects objects_to_remove.push_back(id); } @@ -1698,14 +1809,14 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete) */ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, - ITextureSource *texturesource, IGameDef *gamedef): + ITextureSource *texturesource, IGameDef *gamedef, + IrrlichtDevice *irr): m_map(map), m_smgr(smgr), m_texturesource(texturesource), - m_gamedef(gamedef) + m_gamedef(gamedef), + m_irr(irr) { - assert(m_map); - assert(m_smgr); } ClientEnvironment::~ClientEnvironment() @@ -1880,6 +1991,7 @@ void ClientEnvironment::step(float dtime) ClientEnvEvent event; event.type = CEE_PLAYER_DAMAGE; event.player_damage.amount = damage; + event.player_damage.send_to_server = true; m_client_event_queue.push_back(event); } } @@ -1913,6 +2025,7 @@ void ClientEnvironment::step(float dtime) ClientEnvEvent event; event.type = CEE_PLAYER_DAMAGE; event.player_damage.amount = damage_per_second; + event.player_damage.send_to_server = true; m_client_event_queue.push_back(event); } } @@ -2081,7 +2194,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) infostream<<"ClientEnvironment::addActiveObject(): " <<"added (id="<getId()<<")"<getId(), object); - object->addToScene(m_smgr, m_texturesource); + object->addToScene(m_smgr, m_texturesource, m_irr); { // Update lighting immediately u8 light = 0; try{ @@ -2099,7 +2212,8 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) void ClientEnvironment::addActiveObject(u16 id, u8 type, const std::string &init_data) { - ClientActiveObject* obj = ClientActiveObject::create(type, m_gamedef); + ClientActiveObject* obj = + ClientActiveObject::create(type, m_gamedef, this); if(obj == NULL) { infostream<<"ClientEnvironment::addActiveObject(): " @@ -2149,19 +2263,22 @@ void ClientEnvironment::processActiveObjectMessage(u16 id, Callbacks for activeobjects */ -void ClientEnvironment::damageLocalPlayer(u8 damage) +void ClientEnvironment::damageLocalPlayer(u8 damage, bool handle_hp) { LocalPlayer *lplayer = getLocalPlayer(); assert(lplayer); - - if(lplayer->hp > damage) - lplayer->hp -= damage; - else - lplayer->hp = 0; + + if(handle_hp){ + if(lplayer->hp > damage) + lplayer->hp -= damage; + else + lplayer->hp = 0; + } ClientEnvEvent event; event.type = CEE_PLAYER_DAMAGE; event.player_damage.amount = damage; + event.player_damage.send_to_server = handle_hp; m_client_event_queue.push_back(event); }