diff options
Diffstat (limited to 'src')
34 files changed, 348 insertions, 445 deletions
diff --git a/src/BlockEntities/MobSpawnerEntity.cpp b/src/BlockEntities/MobSpawnerEntity.cpp index 7f1b88c9b..cbf94de57 100644 --- a/src/BlockEntities/MobSpawnerEntity.cpp +++ b/src/BlockEntities/MobSpawnerEntity.cpp @@ -163,7 +163,7 @@ void cMobSpawnerEntity::SpawnEntity(void) double PosX = Chunk->GetPosX() * cChunkDef::Width + RelX; double PosZ = Chunk->GetPosZ() * cChunkDef::Width + RelZ; - cMonster * Monster = cMonster::NewMonsterFromType(m_MobType); + auto Monster = cMonster::NewMonsterFromType(m_MobType); if (Monster == nullptr) { continue; @@ -171,7 +171,7 @@ void cMobSpawnerEntity::SpawnEntity(void) Monster->SetPosition(PosX, RelY, PosZ); Monster->SetYaw(Random.NextFloat() * 360.0f); - if (Chunk->GetWorld()->SpawnMobFinalize(Monster) != cEntity::INVALID_ID) + if (Chunk->GetWorld()->SpawnMobFinalize(std::move(Monster)) != cEntity::INVALID_ID) { EntitiesSpawned = true; Chunk->BroadcastSoundParticleEffect( diff --git a/src/Chunk.cpp b/src/Chunk.cpp index b5c2339b7..8068b2119 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -131,17 +131,18 @@ cChunk::~cChunk() } m_BlockEntities.clear(); - // Remove and destroy all entities that are not players: - cEntityList Entities; - std::swap(Entities, m_Entities); // Need another list because cEntity destructors check if they've been removed from chunk - for (cEntityList::const_iterator itr = Entities.begin(); itr != Entities.end(); ++itr) + // Remove and destroy all entities: + for (auto & Entity : m_Entities) { - if (!(*itr)->IsPlayer()) + if (Entity->IsDestroyed()) { - // Scheduling a normal destruction is neither possible (Since this chunk will be gone till the schedule occurs) nor necessary. - (*itr)->DestroyNoScheduling(false); // No point in broadcasting in an unloading chunk. Chunks unload when no one is nearby. - delete *itr; + // Workaround to mitigate crashing in cPlayer::SaveToDisk which may try to access destroyed member variables on server stop + // All entities will have been destroyed in cWorld::Stop in this circumstance + continue; } + + // Scheduling a normal destruction is neither possible (Since this chunk will be gone till the schedule occurs) nor necessary. + Entity->DestroyNoScheduling(false); // No point in broadcasting in an unloading chunk. Chunks unload when no one is nearby. } if (m_NeighborXM != nullptr) @@ -284,9 +285,9 @@ void cChunk::GetAllData(cChunkDataCallback & a_Callback) a_Callback.ChunkData(m_ChunkData); - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + for (const auto & Entity : m_Entities) { - a_Callback.Entity(*itr); + a_Callback.Entity(Entity.get()); } for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) @@ -483,7 +484,7 @@ void cChunk::CollectMobCensus(cMobCensus & toFill) } Vector3d currentPosition; - for (auto entity : m_Entities) + for (auto & entity : m_Entities) { // LOGD("Counting entity #%i (%s)", (*itr)->GetUniqueID(), (*itr)->GetClass()); if (entity->IsMob()) @@ -581,7 +582,7 @@ void cChunk::SpawnMobs(cMobSpawner & a_MobSpawner) continue; } - cEntity * newMob = a_MobSpawner.TryToSpawnHere(this, TryX, TryY, TryZ, Biome, MaxNbOfSuccess); + auto newMob = a_MobSpawner.TryToSpawnHere(this, TryX, TryY, TryZ, Biome, MaxNbOfSuccess); if (newMob == nullptr) { continue; @@ -605,7 +606,7 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt) // If we are not valid, tick players and bailout if (!IsValid()) { - for (auto Entity : m_Entities) + for (const auto & Entity : m_Entities) { if (Entity->IsPlayer()) { @@ -630,7 +631,7 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt) m_IsDirty = (*itr)->Tick(a_Dt, *this) | m_IsDirty; } - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();) + for (auto itr = m_Entities.begin(); itr != m_Entities.end();) { // Do not tick mobs that are detached from the world. They're either scheduled for teleportation or for removal. if (!(*itr)->IsTicking()) @@ -655,20 +656,22 @@ void cChunk::Tick(std::chrono::milliseconds a_Dt) continue; } - if ((((*itr)->GetChunkX() != m_PosX) || - ((*itr)->GetChunkZ() != m_PosZ)) + if ( + ((*itr)->GetChunkX() != m_PosX) || + ((*itr)->GetChunkZ() != m_PosZ) ) { - // This block is very similar to RemoveEntity, except it uses an iterator to avoid scanning the whole m_Entities - // The entity moved out of the chunk, move it to the neighbor - (*itr)->SetParentChunk(nullptr); - MoveEntityToNewChunk(*itr); + // Mark as dirty if it was a server-generated entity: if (!(*itr)->IsPlayer()) { MarkDirty(); } + + // The entity moved out of the chunk, move it to the neighbor + MoveEntityToNewChunk(std::move(*itr)); + itr = m_Entities.erase(itr); } else @@ -697,7 +700,7 @@ void cChunk::TickBlock(int a_RelX, int a_RelY, int a_RelZ) -void cChunk::MoveEntityToNewChunk(cEntity * a_Entity) +void cChunk::MoveEntityToNewChunk(std::unique_ptr<cEntity> a_Entity) { cChunk * Neighbor = GetNeighborChunk(a_Entity->GetChunkX() * cChunkDef::Width, a_Entity->GetChunkZ() * cChunkDef::Width); if (Neighbor == nullptr) @@ -711,28 +714,29 @@ void cChunk::MoveEntityToNewChunk(cEntity * a_Entity) } ASSERT(Neighbor != this); // Moving into the same chunk? wtf? - Neighbor->AddEntity(a_Entity); + auto & EntityPtr = *a_Entity; + Neighbor->AddEntity(std::move(a_Entity)); class cMover : public cClientDiffCallback { virtual void Removed(cClientHandle * a_Client) override { - a_Client->SendDestroyEntity(*m_Entity); + a_Client->SendDestroyEntity(m_Entity); } virtual void Added(cClientHandle * a_Client) override { - m_Entity->SpawnOn(*a_Client); + m_Entity.SpawnOn(*a_Client); } - cEntity * m_Entity; + cEntity & m_Entity; public: - cMover(cEntity * a_CallbackEntity) : + cMover(cEntity & a_CallbackEntity) : m_Entity(a_CallbackEntity) {} - } Mover(a_Entity); + } Mover(EntityPtr); m_ChunkMap->CompareChunkClients(this, Neighbor, Mover); } @@ -1810,15 +1814,15 @@ void cChunk::CollectPickupsByPlayer(cPlayer & a_Player) double PosY = a_Player.GetPosY(); double PosZ = a_Player.GetPosZ(); - for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) + for (auto & Entity : m_Entities) { - if ((!(*itr)->IsPickup()) && (!(*itr)->IsProjectile())) + if ((!Entity->IsPickup()) && (!Entity->IsProjectile())) { continue; // Only pickups and projectiles can be picked up } - float DiffX = static_cast<float>((*itr)->GetPosX() - PosX); - float DiffY = static_cast<float>((*itr)->GetPosY() - PosY); - float DiffZ = static_cast<float>((*itr)->GetPosZ() - PosZ); + float DiffX = static_cast<float>(Entity->GetPosX() - PosX); + float DiffY = static_cast<float>(Entity->GetPosY() - PosY); + float DiffZ = static_cast<float>(Entity->GetPosZ() - PosZ); float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; if (SqrDist < 1.5f * 1.5f) // 1.5 block { @@ -1828,13 +1832,13 @@ void cChunk::CollectPickupsByPlayer(cPlayer & a_Player) ); */ MarkDirty(); - if ((*itr)->IsPickup()) + if (Entity->IsPickup()) { - (reinterpret_cast<cPickup *>(*itr))->CollectedBy(a_Player); + reinterpret_cast<cPickup *>(Entity.get())->CollectedBy(a_Player); } else { - (reinterpret_cast<cProjectileEntity *>(*itr))->CollectedBy(a_Player); + reinterpret_cast<cProjectileEntity *>(Entity.get())->CollectedBy(a_Player); } } else if (SqrDist < 5 * 5) @@ -1970,34 +1974,49 @@ bool cChunk::HasAnyClients(void) const -void cChunk::AddEntity(cEntity * a_Entity) +void cChunk::AddEntity(std::unique_ptr<cEntity> a_Entity) { if (!a_Entity->IsPlayer()) { MarkDirty(); } + auto EntityPtr = a_Entity.get(); + ASSERT(std::find(m_Entities.begin(), m_Entities.end(), a_Entity) == m_Entities.end()); // Not there already + m_Entities.emplace_back(std::move(a_Entity)); - m_Entities.push_back(a_Entity); - ASSERT(a_Entity->GetParentChunk() == nullptr); - a_Entity->SetParentChunk(this); + ASSERT(EntityPtr->GetParentChunk() == nullptr); + EntityPtr->SetParentChunk(this); + EntityPtr->SetIsTicking(true); } -void cChunk::RemoveEntity(cEntity * a_Entity) +void cChunk::RemoveEntity(cEntity & a_Entity) { - ASSERT(a_Entity->GetParentChunk() == this); - a_Entity->SetParentChunk(nullptr); - m_Entities.remove(a_Entity); - // Mark as dirty if it was a server-generated entity: - if (!a_Entity->IsPlayer()) + ASSERT(a_Entity.GetParentChunk() == this); + ASSERT(!a_Entity.IsTicking()); + a_Entity.SetParentChunk(nullptr); + + if (!a_Entity.IsPlayer()) { MarkDirty(); } + + m_Entities.erase( + std::remove_if( + m_Entities.begin(), + m_Entities.end(), + [&a_Entity](const decltype(m_Entities)::value_type & a_Value) + { + return (a_Value.get() == &a_Entity); + } + ), + m_Entities.end() + ); } @@ -2006,13 +2025,13 @@ void cChunk::RemoveEntity(cEntity * a_Entity) bool cChunk::HasEntity(UInt32 a_EntityID) { - for (cEntityList::const_iterator itr = m_Entities.begin(), end = m_Entities.end(); itr != end; ++itr) + for (const auto & Entity : m_Entities) { - if ((*itr)->GetUniqueID() == a_EntityID) + if (Entity->GetUniqueID() == a_EntityID) { return true; } - } // for itr - m_Entities[] + } return false; } @@ -2023,14 +2042,14 @@ bool cChunk::HasEntity(UInt32 a_EntityID) bool cChunk::ForEachEntity(cEntityCallback & a_Callback) { // The entity list is locked by the parent chunkmap's CS - for (cEntityList::iterator itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2) + for (auto itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2) { ++itr2; if (!(*itr)->IsTicking()) { continue; } - if (a_Callback.Item(*itr)) + if (a_Callback.Item((*itr).get())) { return false; } @@ -2045,7 +2064,7 @@ bool cChunk::ForEachEntity(cEntityCallback & a_Callback) bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_Callback) { // The entity list is locked by the parent chunkmap's CS - for (cEntityList::iterator itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2) + for (auto itr = m_Entities.begin(), itr2 = itr; itr != m_Entities.end(); itr = itr2) { ++itr2; if (!(*itr)->IsTicking()) @@ -2058,7 +2077,7 @@ bool cChunk::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & a_ // The entity is not in the specified box continue; } - if (a_Callback.Item(*itr)) + if (a_Callback.Item((*itr).get())) { return false; } @@ -2093,7 +2112,7 @@ bool cChunk::ForEachBlockEntity(cBlockEntityCallback & a_Callback) for (cBlockEntityList::iterator itr = m_BlockEntities.begin(), itr2 = itr; itr != m_BlockEntities.end(); itr = itr2) { ++itr2; - if (a_Callback.Item((*itr).get())) + if (a_Callback.Item(*itr)) { return false; } diff --git a/src/Chunk.h b/src/Chunk.h index ecb594191..a75054d30 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -485,6 +485,36 @@ public: return m_LoadedByClient; } + std::unique_ptr<cEntity> AcquireAssociatedEntityPtr(const cEntity & a_Entity) + { + auto Iterator = std::find_if( + m_Entities.begin(), + m_Entities.end(), + [&a_Entity](const decltype(m_Entities)::value_type & a_Value) + { + return (a_Value.get() == &a_Entity); + } + ); + + if (Iterator == m_Entities.cend()) + { + return nullptr; + } + else + { + auto Entity = std::move(*Iterator); + Entity->SetParentChunk(nullptr); + + if (!Entity->IsPlayer()) + { + MarkDirty(); + } + + m_Entities.erase(Iterator); + return Entity; + } + } + private: friend class cChunkMap; @@ -519,8 +549,8 @@ private: std::vector<Vector3i> m_ToTickBlocks; sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients - cEntityList m_Entities; std::vector<std::weak_ptr<cClientHandle>> m_LoadedByClient; + std::vector<std::unique_ptr<cEntity>> m_Entities; cBlockEntityList m_BlockEntities; /** Number of times the chunk has been requested to stay (by various cChunkStay objects); if zero, the chunk can be unloaded */ @@ -594,7 +624,7 @@ private: bool GrowMelonPumpkin(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, MTRand & a_Random); /** Called by Tick() when an entity moves out of this chunk into a neighbor; moves the entity and sends spawn / despawn packet to clients */ - void MoveEntityToNewChunk(cEntity * a_Entity); + void MoveEntityToNewChunk(std::unique_ptr<cEntity> a_Entity); }; typedef cChunk * cChunkPtr; diff --git a/src/ChunkDef.h b/src/ChunkDef.h index d146fe9ac..f99cc761b 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -31,7 +31,7 @@ class cEntity; class cClientHandle; class cBlockEntity; -typedef std::list<cEntity *> cEntityList; +typedef std::vector<std::unique_ptr<cEntity>> cEntityList; typedef std::list<cBlockEntity *> cBlockEntityList; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 2e6153f0e..abd4eb8bf 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1582,51 +1582,19 @@ void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, const std::shared_ +void cChunkMap::AddEntity(std::unique_ptr<cEntity> a_Entity) { - for (const auto & Chunk : m_Chunks) - { - Chunk.second->RemoveClient(a_Client); - } -} - - - - - -void cChunkMap::AddEntity(cEntity * a_Entity) -{ - cCSLock Lock(m_CSChunks); - cChunkPtr Chunk = GetChunk(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); - if (Chunk == nullptr) // This will assert inside GetChunk in Debug builds - { - LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.", - static_cast<void *>(a_Entity), a_Entity->GetClass(), a_Entity->GetUniqueID() - ); - return; - } - Chunk->AddEntity(a_Entity); -} - - - - ASSERT(GetWorld()->IsInTickThread()); -void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) -{ - cCSLock Lock(m_CSChunks); cChunkPtr Chunk = GetChunk(a_Entity->GetChunkX(), a_Entity->GetChunkZ()); if (Chunk == nullptr) // This will assert inside GetChunk in Debug builds { LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.", - static_cast<void *>(a_Entity), a_Entity->GetClass(), a_Entity->GetUniqueID() + static_cast<void *>(a_Entity.get()), a_Entity->GetClass(), a_Entity->GetUniqueID() ); return; } - if (!Chunk->HasEntity(a_Entity->GetUniqueID())) - { - Chunk->AddEntity(a_Entity); - } + Chunk->AddEntity(std::move(a_Entity)); } @@ -2574,10 +2542,10 @@ void cChunkMap::GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) bool cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand) { + ASSERT(GetWorld()->IsInTickThread()); int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - ASSERT(GetWorld()->IsInTickThread()); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) { diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 7ca62a41d..cad1cddc2 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -211,18 +211,11 @@ public: void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, const std::shared_ptr<cClientHandle> & a_Client); /** Adds the entity to its appropriate chunk, takes ownership of the entity pointer */ - void AddEntity(cEntity * a_Entity); - - /** Adds the entity to its appropriate chunk, if the entity is not already added. - Takes ownership of the entity pointer */ - void AddEntityIfNotPresent(cEntity * a_Entity); + void AddEntity(std::unique_ptr<cEntity> a_Entity); /** Returns true if the entity with specified ID is present in the chunks */ bool HasEntity(UInt32 a_EntityID); - /** Removes the entity from its appropriate chunk */ - void RemoveEntity(cEntity * a_Entity); - /** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 489b55cf8..5693bc42b 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -130,7 +130,7 @@ const char * cEntity::GetParentClass(void) const -bool cEntity::Initialize(cWorld & a_World) +bool cEntity::Initialize(std::unique_ptr<cEntity> a_Entity, cWorld & a_EntityWorld) { ASSERT(a_EntityWorld.IsInTickThread()); diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 25f6e76bf..a8074406c 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -153,7 +153,7 @@ public: /** Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed). Adds the entity to the world. */ - virtual bool Initialize(cWorld & a_World); + virtual bool Initialize(std::unique_ptr<cEntity>a_Entity, cWorld & a_EntityWorld); // tolua_begin diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index c83e7f3cb..809c51731 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -28,9 +28,8 @@ cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height) : cPawn::~cPawn() -bool cPawn::OnPreWorldTravel(cWorld & a_NewWorld) { - ASSERT(m_TargetingMe.size() == 0); + UnsetAllTargeters(); return super::OnPreWorldTravel(a_NewWorld); } @@ -40,7 +39,7 @@ bool cPawn::OnPreWorldTravel(cWorld & a_NewWorld) void cPawn::Destroyed() { - StopEveryoneFromTargetingMe(); + UnsetAllTargeters(); super::Destroyed(); } @@ -221,32 +220,37 @@ void cPawn::ClearEntityEffects() -void cPawn::NoLongerTargetingMe(cMonster * a_Monster) +void cPawn::UnsetAllTargeters() { - ASSERT(IsTicking()); // Our destroy override is supposed to clear all targets before we're destroyed. - for (auto i = m_TargetingMe.begin(); i != m_TargetingMe.end(); ++i) + class Callback : public cEntityCallback { - cMonster * Monster = *i; - if (Monster == a_Monster) + public: + Callback(cPawn & a_Pawn) : + m_Pawn(a_Pawn) { - ASSERT(Monster->GetTarget() != this); // The monster is notifying us it is no longer targeting us, assert if that's a lie - m_TargetingMe.erase(i); - return; } - } - ASSERT(false); // If this happens, something is wrong. Perhaps the monster never called TargetingMe() or called NoLongerTargetingMe() twice. -} + virtual bool Item(cEntity * a_Entity) override + { + if (!a_Entity->IsMob()) + { + return false; + } + auto Monster = static_cast<cMonster *>(a_Entity); + if (Monster->GetTarget() == &m_Pawn) + { + Monster->SetTarget(nullptr); + } + return false; + } + private: + cPawn & m_Pawn; + } Callback(*this); -void cPawn::TargetingMe(cMonster * a_Monster) -{ - ASSERT(IsTicking()); - ASSERT(m_TargetingMe.size() < 10000); - ASSERT(a_Monster->GetTarget() == this); - m_TargetingMe.push_back(a_Monster); + GetWorld()->ForEachEntity(Callback); } @@ -418,20 +422,3 @@ void cPawn::HandleFalling(void) because of the client skipping an update about the lava block. This can only be resolved by somehow integrating these above checks into the tracer in HandlePhysics. */ } - - - - - -void cPawn::StopEveryoneFromTargetingMe() -{ - std::vector<cMonster*>::iterator i = m_TargetingMe.begin(); - while (i != m_TargetingMe.end()) - { - cMonster * Monster = *i; - ASSERT(Monster->GetTarget() == this); - Monster->UnsafeUnsetTarget(); - i = m_TargetingMe.erase(i); - } - ASSERT(m_TargetingMe.size() == 0); -} diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h index 74bccc4a3..f613196e1 100644 --- a/src/Entities/Pawn.h +++ b/src/Entities/Pawn.h @@ -24,7 +24,6 @@ public: cPawn(eEntityType a_EntityType, double a_Width, double a_Height); ~cPawn(); - virtual bool OnPreWorldTravel(cWorld & a_NewWorld) override; virtual void Destroyed() override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; @@ -34,11 +33,6 @@ public: virtual void HandleAir(void) override; virtual void HandleFalling(void); - /** Tells all pawns which are targeting us to stop targeting us. */ - void StopEveryoneFromTargetingMe(); - - - // tolua_begin /** Applies an entity effect. @@ -59,23 +53,17 @@ public: // tolua_end - /** Remove the monster from the list of monsters targeting this pawn. */ - void NoLongerTargetingMe(cMonster * a_Monster); - - /** Add the monster to the list of monsters targeting this pawn. (Does not check if already in list!) */ - void TargetingMe(cMonster * a_Monster); - protected: + /** Resets the targeted entity of all who currently are targeting us in the current world. + Fulfils invariant set out in cMonster::m_Target. */ + void UnsetAllTargeters(); + typedef std::map<cEntityEffect::eType, cEntityEffect *> tEffectMap; tEffectMap m_EntityEffects; double m_LastGroundHeight; bool m_bTouchGround; -private: - - /** A list of all monsters that are targeting this pawn. */ - std::vector<cMonster*> m_TargetingMe; } ; // tolua_export diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index c4f705668..ebfaba366 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -252,7 +252,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve -cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed) +std::unique_ptr<cProjectileEntity> cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed) { Vector3d Speed; if (a_Speed != nullptr) @@ -262,15 +262,15 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, switch (a_Kind) { - case pkArrow: return new cArrowEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkEgg: return new cThrownEggEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkEnderPearl: return new cThrownEnderPearlEntity(a_Creator, a_X, a_Y, a_Z, Speed); - case pkSnowball: return new cThrownSnowballEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkGhastFireball: return new cGhastFireballEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkFireCharge: return new cFireChargeEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkExpBottle: return new cExpBottleEntity (a_Creator, a_X, a_Y, a_Z, Speed); - case pkSplashPotion: return new cSplashPotionEntity (a_Creator, a_X, a_Y, a_Z, Speed, *a_Item); - case pkWitherSkull: return new cWitherSkullEntity (a_Creator, a_X, a_Y, a_Z, Speed); + case pkArrow: return cpp14::make_unique<cArrowEntity>(a_Creator, a_X, a_Y, a_Z, Speed); + case pkEgg: return cpp14::make_unique<cThrownEggEntity>(a_Creator, a_X, a_Y, a_Z, Speed); + case pkEnderPearl: return cpp14::make_unique<cThrownEnderPearlEntity>(a_Creator, a_X, a_Y, a_Z, Speed); + case pkSnowball: return cpp14::make_unique<cThrownSnowballEntity>(a_Creator, a_X, a_Y, a_Z, Speed); + case pkGhastFireball: return cpp14::make_unique<cGhastFireballEntity>(a_Creator, a_X, a_Y, a_Z, Speed); + case pkFireCharge: return cpp14::make_unique<cFireChargeEntity>(a_Creator, a_X, a_Y, a_Z, Speed); + case pkExpBottle: return cpp14::make_unique<cExpBottleEntity>(a_Creator, a_X, a_Y, a_Z, Speed); + case pkSplashPotion: return cpp14::make_unique<cSplashPotionEntity>(a_Creator, a_X, a_Y, a_Z, Speed, *a_Item); + case pkWitherSkull: return cpp14::make_unique<cWitherSkullEntity>(a_Creator, a_X, a_Y, a_Z, Speed); case pkFirework: { ASSERT(a_Item != nullptr); @@ -279,7 +279,7 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, return nullptr; } - return new cFireworkEntity(a_Creator, a_X, a_Y, a_Z, *a_Item); + return cpp14::make_unique<cFireworkEntity>(a_Creator, a_X, a_Y, a_Z, *a_Item); } case pkFishingFloat: break; } diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h index b354c7cfc..da8c650f5 100644 --- a/src/Entities/ProjectileEntity.h +++ b/src/Entities/ProjectileEntity.h @@ -46,7 +46,7 @@ public: cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height); cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height); - static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed = nullptr); + static std::unique_ptr<cProjectileEntity> Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed = nullptr); /** Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given */ virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace); diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp index 4b2e2f9ff..68022d74e 100644 --- a/src/Entities/ThrownEnderPearlEntity.cpp +++ b/src/Entities/ThrownEnderPearlEntity.cpp @@ -86,7 +86,7 @@ void cThrownEnderPearlEntity::TeleportCreator(const Vector3d & a_HitPos) virtual bool Item(cPlayer * a_Entity) override { // Teleport the creator here, make them take 5 damage: - a_Entity->TeleportToCoords(m_HitPos.x, m_HitPos.y + 0.2, m_HitPos.z); + a_Entity->TeleportToCoords(m_HitPos + Vector3d(0, 0.2, 0)); a_Entity->TakeDamage(dtEnderPearl, m_Attacker, 5, 0); return true; } diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index 3f6a1dc7a..f9e43d9fd 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -1483,11 +1483,11 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX double AnimalY = a_RelY; double AnimalZ = static_cast<double>(a_ChunkDesc.GetChunkZ() * cChunkDef::Width + a_RelZ + 0.5); - cMonster * NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); + auto NewMob = cMonster::NewMonsterFromType(AnimalToSpawn); NewMob->SetHealth(NewMob->GetMaxHealth()); NewMob->SetPosition(AnimalX, AnimalY, AnimalZ); - a_ChunkDesc.GetEntities().push_back(NewMob); LOGD("Spawning %s #%i at {%.02f, %.02f, %.02f}", NewMob->GetClass(), NewMob->GetUniqueID(), AnimalX, AnimalY, AnimalZ); + a_ChunkDesc.GetEntities().emplace_back(std::move(NewMob)); return true; } diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h index de16c70dc..ad6934916 100644 --- a/src/Items/ItemBoat.h +++ b/src/Items/ItemBoat.h @@ -92,8 +92,7 @@ public: } // Spawn block at water level - cBoat * Boat = new cBoat(x + 0.5, y + 0.5, z + 0.5); - Boat->Initialize(*a_World); + a_World->SpawnBoat(x + 0.5, y + 0.5, z + 0.5); return true; } diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index fc0ee8434..0d4bdd46e 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -69,17 +69,12 @@ public: } // Create the arrow entity: - cArrowEntity * Arrow = new cArrowEntity(*a_Player, Force * 2); - if (Arrow == nullptr) + auto ArrowPtr = cpp14::make_unique<cArrowEntity>(*a_Player, Force * 2); + auto Arrow = ArrowPtr.get(); + if (!Arrow->Initialize(std::move(ArrowPtr), *a_Player->GetWorld())) { return; } - if (!Arrow->Initialize(*a_Player->GetWorld())) - { - delete Arrow; - Arrow = nullptr; - return; - } a_Player->GetWorld()->BroadcastSoundEffect( "random.bow", a_Player->GetPosX(), diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h index 3a2ef0275..e44eb09bb 100644 --- a/src/Items/ItemFishingRod.h +++ b/src/Items/ItemFishingRod.h @@ -244,9 +244,9 @@ public: } else { - cFloater * Floater = new cFloater(a_Player->GetPosX(), a_Player->GetStance(), a_Player->GetPosZ(), a_Player->GetLookVector() * 15, a_Player->GetUniqueID(), static_cast<int>(100 + static_cast<unsigned int>(a_World->GetTickRandomNumber(800)) - (a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100))); - Floater->Initialize(*a_World); + auto Floater = cpp14::make_unique<cFloater>(a_Player->GetPosX(), a_Player->GetStance(), a_Player->GetPosZ(), a_Player->GetLookVector() * 15, a_Player->GetUniqueID(), static_cast<int>(100 + static_cast<unsigned int>(a_World->GetTickRandomNumber(800)) - (a_Player->GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::enchLure) * 100))); a_Player->SetIsFishing(true, Floater->GetUniqueID()); + Floater->Initialize(std::move(Floater), *a_World); } return true; } diff --git a/src/Items/ItemItemFrame.h b/src/Items/ItemItemFrame.h index 77a5bf47c..a670d6cac 100644 --- a/src/Items/ItemItemFrame.h +++ b/src/Items/ItemItemFrame.h @@ -38,11 +38,9 @@ public: if (Block == E_BLOCK_AIR) { - cItemFrame * ItemFrame = new cItemFrame(a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); - if (!ItemFrame->Initialize(*a_World)) + auto ItemFrame = cpp14::make_unique<cItemFrame>(a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); + if (!ItemFrame->Initialize(std::move(ItemFrame), *a_World)) { - delete ItemFrame; - ItemFrame = nullptr; return false; } diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index 6344c0178..d7ea18719 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -59,21 +59,8 @@ public: double x = static_cast<double>(a_BlockX) + 0.5; double y = static_cast<double>(a_BlockY) + 0.5; double z = static_cast<double>(a_BlockZ) + 0.5; - cMinecart * Minecart = nullptr; - switch (m_ItemType) - { - case E_ITEM_MINECART: Minecart = new cRideableMinecart (x, y, z, cItem(), 1); break; - case E_ITEM_CHEST_MINECART: Minecart = new cMinecartWithChest (x, y, z); break; - case E_ITEM_FURNACE_MINECART: Minecart = new cMinecartWithFurnace (x, y, z); break; - case E_ITEM_MINECART_WITH_TNT: Minecart = new cMinecartWithTNT (x, y, z); break; - case E_ITEM_MINECART_WITH_HOPPER: Minecart = new cMinecartWithHopper (x, y, z); break; - default: - { - ASSERT(!"Unhandled minecart item"); - return false; - } - } // switch (m_ItemType) - Minecart->Initialize(*a_World); + + a_World->SpawnMinecart(x, y, z, m_ItemType); if (!a_Player->IsGameModeCreative()) { diff --git a/src/Items/ItemPainting.h b/src/Items/ItemPainting.h index dd35931dd..60a231d2b 100644 --- a/src/Items/ItemPainting.h +++ b/src/Items/ItemPainting.h @@ -70,8 +70,8 @@ public: { "BurningSkull" } }; - cPainting * Painting = new cPainting(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); - Painting->Initialize(*a_World); + auto Painting = cpp14::make_unique<cPainting>(gPaintingTitlesList[a_World->GetTickRandomNumber(ARRAYCOUNT(gPaintingTitlesList) - 1)].Title, a_BlockFace, a_BlockX, a_BlockY, a_BlockZ); + Painting->Initialize(std::move(Painting), *a_World); if (!a_Player->IsGameModeCreative()) { diff --git a/src/MobSpawner.cpp b/src/MobSpawner.cpp index 60f7cfb43..b6ad261b5 100644 --- a/src/MobSpawner.cpp +++ b/src/MobSpawner.cpp @@ -347,15 +347,14 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_R -cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int & a_MaxPackSize) +std::unique_ptr<cMonster> cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int & a_MaxPackSize) { - cMonster * toReturn = nullptr; if (m_NewPack) { m_MobType = ChooseMobType(a_Biome); if (m_MobType == mtInvalidType) { - return toReturn; + return nullptr; } if (m_MobType == mtWolf) { @@ -373,14 +372,15 @@ cMonster * cMobSpawner::TryToSpawnHere(cChunk * a_Chunk, int a_RelX, int a_RelY, if ((m_AllowedTypes.find(m_MobType) != m_AllowedTypes.end()) && CanSpawnHere(a_Chunk, a_RelX, a_RelY, a_RelZ, m_MobType, a_Biome)) { - cMonster * newMob = cMonster::NewMonsterFromType(m_MobType); + auto newMob = cMonster::NewMonsterFromType(m_MobType); if (newMob) { - m_Spawned.insert(newMob); + m_Spawned.insert(std::move(newMob)); } - toReturn = newMob; + return newMob; } - return toReturn; + + return nullptr; } diff --git a/src/MobSpawner.h b/src/MobSpawner.h index 3a2776df4..935ded519 100644 --- a/src/MobSpawner.h +++ b/src/MobSpawner.h @@ -38,7 +38,7 @@ public : If this is the first of a Pack, determine the type of monster a_Biome, BlockType & BlockMeta are used to decide what kind of Mob can Spawn here a_MaxPackSize is set to the maximal size for a pack this type of mob */ - cMonster * TryToSpawnHere(cChunk * a_Chunk, int A_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int & a_MaxPackSize); + std::unique_ptr<cMonster> TryToSpawnHere(cChunk * a_Chunk, int A_RelX, int a_RelY, int a_RelZ, EMCSBiome a_Biome, int & a_MaxPackSize); /** Mark the beginning of a new Pack. All mobs of the same Pack are the same type */ @@ -47,7 +47,7 @@ public : // return true if there is at least one allowed type bool CanSpawnAnything(void); - typedef const std::set<cMonster *> tSpawnedContainer; + typedef const std::set<std::unique_ptr<cMonster>> tSpawnedContainer; tSpawnedContainer & getSpawned(void); /** Returns true if specified type of mob can spawn on specified block */ @@ -65,7 +65,7 @@ protected : std::set<eMonsterType> m_AllowedTypes; bool m_NewPack; eMonsterType m_MobType; - std::set<cMonster*> m_Spawned; + std::set<std::unique_ptr<cMonster>> m_Spawned; cFastRandom m_Random; } ; diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index d002e14e7..1fcf086d5 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -39,17 +39,11 @@ bool cBlaze::Attack(std::chrono::milliseconds a_Dt) // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; Speed.y = Speed.y + 1; - cFireChargeEntity * FireCharge = new cFireChargeEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (FireCharge == nullptr) + auto FireCharge = cpp14::make_unique<cFireChargeEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + if (!FireCharge->Initialize(std::move(FireCharge), *m_World)) { return false; } - if (!FireCharge->Initialize(*m_World)) - { - delete FireCharge; - FireCharge = nullptr; - return false; - } ResetAttackCooldown(); // ToDo: Shoot 3 fireballs instead of 1. return true; diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp index 0544255df..d40545b1d 100644 --- a/src/Mobs/Ghast.cpp +++ b/src/Mobs/Ghast.cpp @@ -39,17 +39,11 @@ bool cGhast::Attack(std::chrono::milliseconds a_Dt) // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; Speed.y = Speed.y + 1; - cGhastFireballEntity * GhastBall = new cGhastFireballEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (GhastBall == nullptr) + auto GhastBall = cpp14::make_unique<cGhastFireballEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + if (!GhastBall->Initialize(std::move(GhastBall), *m_World)) { return false; } - if (!GhastBall->Initialize(*m_World)) - { - delete GhastBall; - GhastBall = nullptr; - return false; - } ResetAttackCooldown(); return true; } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 3b0fdd36c..738e5b983 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -123,7 +123,7 @@ cMonster::~cMonster() void cMonster::Destroyed() { - SetTarget(nullptr); // Tell them we're no longer targeting them. + SetTarget(nullptr); super::Destroyed(); } @@ -912,47 +912,26 @@ int cMonster::GetSpawnDelay(cMonster::eFamily a_MobFamily) - -/** Sets the target. */ -void cMonster::SetTarget (cPawn * a_NewTarget) +void cMonster::SetTarget(cPawn * a_NewTarget) { - ASSERT((a_NewTarget == nullptr) || (IsTicking())); - if (m_Target == a_NewTarget) - { - return; - } - cPawn * OldTarget = m_Target; - m_Target = a_NewTarget; + ASSERT((a_NewTarget == nullptr) || IsTicking()); - if (OldTarget != nullptr) + if (a_NewTarget == nullptr) { - // Notify the old target that we are no longer targeting it. - OldTarget->NoLongerTargetingMe(this); - } - - if (a_NewTarget != nullptr) - { - ASSERT(a_NewTarget->IsTicking()); - // Notify the new target that we are now targeting it. - m_Target->TargetingMe(this); + m_Target = nullptr; + return; } + ASSERT(a_NewTarget->IsTicking()); + m_Target = a_NewTarget; + ASSERT(GetTarget() != nullptr); } -void cMonster::UnsafeUnsetTarget() -{ - m_Target = nullptr; -} - - - - - -cPawn * cMonster::GetTarget () +cPawn * cMonster::GetTarget() { return m_Target; } @@ -961,29 +940,25 @@ cPawn * cMonster::GetTarget () -cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) +std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType) { cFastRandom Random; - cMonster * toReturn = nullptr; // Create the mob entity switch (a_MobType) { case mtMagmaCube: { - toReturn = new cMagmaCube(1 << Random.NextInt(3)); // Size 1, 2 or 4 - break; + return cpp14::make_unique<cMagmaCube>(1 << Random.NextInt(3)); // Size 1, 2 or 4 } case mtSlime: { - toReturn = new cSlime(1 << Random.NextInt(3)); // Size 1, 2 or 4 - break; + return cpp14::make_unique<cSlime>(1 << Random.NextInt(3)); // Size 1, 2 or 4 } case mtSkeleton: { // TODO: Actual detection of spawning in Nether - toReturn = new cSkeleton((Random.NextInt(1) == 0) ? false : true); - break; + return cpp14::make_unique<cSkeleton>((Random.NextInt(1) == 0) ? false : true); } case mtVillager: { @@ -994,8 +969,7 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) VillagerType = 0; } - toReturn = new cVillager(static_cast<cVillager::eVillagerType>(VillagerType)); - break; + return cpp14::make_unique<cVillager>(static_cast<cVillager::eVillagerType>(VillagerType)); } case mtHorse: { @@ -1011,42 +985,41 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) HorseType = 0; } - toReturn = new cHorse(HorseType, HorseColor, HorseStyle, HorseTameTimes); - break; + return cpp14::make_unique<cHorse>(HorseType, HorseColor, HorseStyle, HorseTameTimes); } - case mtBat: toReturn = new cBat(); break; - case mtBlaze: toReturn = new cBlaze(); break; - case mtCaveSpider: toReturn = new cCaveSpider(); break; - case mtChicken: toReturn = new cChicken(); break; - case mtCow: toReturn = new cCow(); break; - case mtCreeper: toReturn = new cCreeper(); break; - case mtEnderDragon: toReturn = new cEnderDragon(); break; - case mtEnderman: toReturn = new cEnderman(); break; - case mtGhast: toReturn = new cGhast(); break; - case mtGiant: toReturn = new cGiant(); break; - case mtGuardian: toReturn = new cGuardian(); break; - case mtIronGolem: toReturn = new cIronGolem(); break; - case mtMooshroom: toReturn = new cMooshroom(); break; - case mtOcelot: toReturn = new cOcelot(); break; - case mtPig: toReturn = new cPig(); break; - case mtRabbit: toReturn = new cRabbit(); break; - case mtSheep: toReturn = new cSheep(); break; - case mtSilverfish: toReturn = new cSilverfish(); break; - case mtSnowGolem: toReturn = new cSnowGolem(); break; - case mtSpider: toReturn = new cSpider(); break; - case mtSquid: toReturn = new cSquid(); break; - case mtWitch: toReturn = new cWitch(); break; - case mtWither: toReturn = new cWither(); break; - case mtWolf: toReturn = new cWolf(); break; - case mtZombie: toReturn = new cZombie(false); break; // TODO: Infected zombie parameter - case mtZombiePigman: toReturn = new cZombiePigman(); break; + case mtBat: return cpp14::make_unique<cBat>(); + case mtBlaze: return cpp14::make_unique<cBlaze>(); + case mtCaveSpider: return cpp14::make_unique<cCaveSpider>(); + case mtChicken: return cpp14::make_unique<cChicken>(); + case mtCow: return cpp14::make_unique<cCow>(); + case mtCreeper: return cpp14::make_unique < cCreeper>(); + case mtEnderDragon: return cpp14::make_unique<cEnderDragon>(); + case mtEnderman: return cpp14::make_unique<cEnderman>(); + case mtGhast: return cpp14::make_unique<cGhast>(); + case mtGiant: return cpp14::make_unique<cGiant>(); + case mtGuardian: return cpp14::make_unique<cGuardian>(); + case mtIronGolem: return cpp14::make_unique<cIronGolem>(); + case mtMooshroom: return cpp14::make_unique<cMooshroom>(); + case mtOcelot: return cpp14::make_unique<cOcelot>(); + case mtPig: return cpp14::make_unique<cPig>(); + case mtRabbit: return cpp14::make_unique<cRabbit>(); + case mtSheep: return cpp14::make_unique<cSheep>(); + case mtSilverfish: return cpp14::make_unique<cSilverfish>(); + case mtSnowGolem: return cpp14::make_unique<cSnowGolem>(); + case mtSpider: return cpp14::make_unique<cSpider>(); + case mtSquid: return cpp14::make_unique<cSquid>(); + case mtWitch: return cpp14::make_unique<cWitch>(); + case mtWither: return cpp14::make_unique<cWither>(); + case mtWolf: return cpp14::make_unique<cWolf>(); + case mtZombie: return cpp14::make_unique<cZombie>(false); // TODO: Infected zombie parameter + case mtZombiePigman: return cpp14::make_unique<cZombiePigman>(); default: { ASSERT(!"Unhandled mob type whilst trying to spawn mob!"); + return nullptr; } } - return toReturn; } diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 2155a4a7c..62c2a3564 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -161,20 +161,16 @@ public: // tolua_end /** Sets the target that this mob will chase. Pass a nullptr to unset. */ - void SetTarget (cPawn * a_NewTarget); - - /** Unset the target without notifying the target entity. Do not use this, use SetTarget(nullptr) instead. - This is only used by cPawn internally. */ - void UnsafeUnsetTarget(); + void SetTarget(cPawn * a_NewTarget); /** Returns the current target. */ - cPawn * GetTarget (); + cPawn * GetTarget(); /** Creates a new object of the specified mob. a_MobType is the type of the mob to be created Asserts and returns null if mob type is not specified */ - static cMonster * NewMonsterFromType(eMonsterType a_MobType); + static std::unique_ptr<cMonster> NewMonsterFromType(eMonsterType a_MobType); protected: @@ -200,7 +196,11 @@ protected: bool ReachedFinalDestination(void) { return ((m_FinalDestination - GetPosition()).SqrLength() < WAYPOINT_RADIUS * WAYPOINT_RADIUS); } /** Returns whether or not the target is close enough for attack. */ - bool TargetIsInRange(void) { ASSERT(m_Target != nullptr); return ((m_Target->GetPosition() - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); } + bool TargetIsInRange(void) + { + ASSERT(GetTarget() != nullptr); + return ((GetTarget()->GetPosition() - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); + } /** Returns if a monster can reach a given height by jumping. */ inline bool DoesPosYRequireJump(int a_PosY) @@ -267,7 +267,9 @@ protected: void AddRandomWeaponDropItem(cItems & a_Drops, unsigned int a_LootingLevel); private: - /** A pointer to the entity this mobile is aiming to reach */ + /** A pointer to the entity this mobile is aiming to reach. + The validity of this pointer SHALL be guaranteed by the pointee; + it MUST be reset when the pointee changes worlds or is destroyed. */ cPawn * m_Target; } ; // tolua_export diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index 7697f1279..01a4c54fb 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -57,17 +57,11 @@ bool cSkeleton::Attack(std::chrono::milliseconds a_Dt) Vector3d Inaccuracy = Vector3d(Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25); Vector3d Speed = (GetTarget()->GetPosition() + Inaccuracy - GetPosition()) * 5; Speed.y = Speed.y - 1 + Random.NextInt(3); - cArrowEntity * Arrow = new cArrowEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (Arrow == nullptr) + auto Arrow = cpp14::make_unique<cArrowEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + if (!Arrow->Initialize(std::move(Arrow), *m_World)) { return false; } - if (!Arrow->Initialize(*m_World)) - { - delete Arrow; - Arrow = nullptr; - return false; - } ResetAttackCooldown(); return true; diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp index 316f68523..e4ef069ec 100644 --- a/src/Mobs/Slime.cpp +++ b/src/Mobs/Slime.cpp @@ -78,10 +78,10 @@ void cSlime::KilledBy(TakeDamageInfo & a_TDI) double AddX = (i % 2 - 0.5) * m_Size / 4.0; double AddZ = (i / 2 - 0.5) * m_Size / 4.0; - cSlime * NewSlime = new cSlime(m_Size / 2); + auto NewSlime = cpp14::make_unique<cSlime>(m_Size / 2); NewSlime->SetPosition(GetPosX() + AddX, GetPosY() + 0.5, GetPosZ() + AddZ); NewSlime->SetYaw(Random.NextFloat(1.0f) * 360.0f); - m_World->SpawnMobFinalize(NewSlime); + m_World->SpawnMobFinalize(std::move(NewSlime)); } } super::KilledBy(a_TDI); diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 6ef81ce1b..fa9cb56f4 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -15,6 +15,7 @@ cWither::cWither(void) : m_WitherInvulnerableTicks(220) { SetMaxHealth(300); + SetHealth(GetMaxHealth() / 3); } @@ -30,18 +31,6 @@ bool cWither::IsArmored(void) const -bool cWither::Initialize(cWorld & a_World) -{ - // Set health before BroadcastSpawnEntity() - SetHealth(GetMaxHealth() / 3); - - return super::Initialize(a_World); -} - - - - - bool cWither::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType == dtDrowning) diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index b430588c9..5f6ec607c 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -25,7 +25,6 @@ public: bool IsArmored(void) const; // cEntity overrides - virtual bool Initialize(cWorld & a_World) override; virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index d3773ee41..e1d1f9c2b 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -61,8 +61,8 @@ void cSandSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, Pos.x, Pos.y, Pos.z, ItemTypeToString(BlockType).c_str(), ItemTypeToString(BlockBelow).c_str() ); */ - cFallingBlock * FallingBlock = new cFallingBlock(Pos, BlockType, a_Chunk->GetMeta(itr->x, itr->y, itr->z)); - FallingBlock->Initialize(m_World); + auto FallingBlock = cpp14::make_unique<cFallingBlock>(Pos, BlockType, a_Chunk->GetMeta(itr->x, itr->y, itr->z)); + FallingBlock->Initialize(std::move(FallingBlock), m_World); a_Chunk->SetBlock(itr->x, itr->y, itr->z, E_BLOCK_AIR, 0); } } diff --git a/src/World.cpp b/src/World.cpp index 399776320..a9d6b2b13 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -930,7 +930,7 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt) // do the spawn for (cMobSpawner::tSpawnedContainer::const_iterator itr2 = Spawner.getSpawned().begin(); itr2 != Spawner.getSpawned().end(); ++itr2) { - SpawnMobFinalize(*itr2); + SpawnMobFinalize(std::move(const_cast<std::unique_ptr<cMonster> &>(*itr2))); } } } // for i - AllFamilies[] @@ -1307,7 +1307,7 @@ bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback -bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, std::function<bool(cChunk &)> a_Callback) +bool cWorld::DoWithChunk(int a_ChunkX, int a_ChunkZ, std::function<bool(cChunk &)> a_Callback) { struct cCallBackWrapper : cChunkCallback { @@ -1904,11 +1904,11 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double float SpeedY = static_cast<float>(a_FlyAwaySpeed * GetTickRandomNumber(50)); float SpeedZ = static_cast<float>(a_FlyAwaySpeed * (GetTickRandomNumber(10) - 5)); - cPickup * Pickup = new cPickup( + auto Pickup = cpp14::make_unique<cPickup>( a_BlockX, a_BlockY, a_BlockZ, *itr, IsPlayerCreated, SpeedX, SpeedY, SpeedZ ); - Pickup->Initialize(*this); + Pickup->Initialize(std::move(Pickup), *this); } } @@ -1925,11 +1925,11 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double continue; } - cPickup * Pickup = new cPickup( + auto Pickup = cpp14::make_unique<cPickup>( a_BlockX, a_BlockY, a_BlockZ, *itr, IsPlayerCreated, static_cast<float>(a_SpeedX), static_cast<float>(a_SpeedY), static_cast<float>(a_SpeedZ) ); - Pickup->Initialize(*this); + Pickup->Initialize(std::move(Pickup), *this); } } @@ -1939,9 +1939,10 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double UInt32 cWorld::SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta) { - cFallingBlock * FallingBlock = new cFallingBlock(Vector3i(a_X, a_Y, a_Z), BlockType, BlockMeta); - FallingBlock->Initialize(*this); - return FallingBlock->GetUniqueID(); + auto FallingBlock = cpp14::make_unique<cFallingBlock>(Vector3i(a_X, a_Y, a_Z), BlockType, BlockMeta); + auto ID = FallingBlock->GetUniqueID(); + FallingBlock->Initialize(std::move(FallingBlock), *this); + return ID; } @@ -1956,9 +1957,10 @@ UInt32 cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Rewa return cEntity::INVALID_ID; } - cExpOrb * ExpOrb = new cExpOrb(a_X, a_Y, a_Z, a_Reward); - ExpOrb->Initialize(*this); - return ExpOrb->GetUniqueID(); + auto ExpOrb = cpp14::make_unique<cExpOrb>(a_X, a_Y, a_Z, a_Reward); + auto ID = ExpOrb->GetUniqueID(); + ExpOrb->Initialize(std::move(ExpOrb), *this); + return ID; } @@ -1967,21 +1969,23 @@ UInt32 cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Rewa UInt32 cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartType, const cItem & a_Content, int a_BlockHeight) { - cMinecart * Minecart; + std::unique_ptr<cMinecart> Minecart; switch (a_MinecartType) { - case E_ITEM_MINECART: Minecart = new cRideableMinecart (a_X, a_Y, a_Z, a_Content, a_BlockHeight); break; - case E_ITEM_CHEST_MINECART: Minecart = new cMinecartWithChest (a_X, a_Y, a_Z); break; - case E_ITEM_FURNACE_MINECART: Minecart = new cMinecartWithFurnace (a_X, a_Y, a_Z); break; - case E_ITEM_MINECART_WITH_TNT: Minecart = new cMinecartWithTNT (a_X, a_Y, a_Z); break; - case E_ITEM_MINECART_WITH_HOPPER: Minecart = new cMinecartWithHopper (a_X, a_Y, a_Z); break; + case E_ITEM_MINECART: Minecart = cpp14::make_unique<cRideableMinecart>(a_X, a_Y, a_Z, a_Content, a_BlockHeight); break; + case E_ITEM_CHEST_MINECART: Minecart = cpp14::make_unique<cMinecartWithChest>(a_X, a_Y, a_Z); break; + case E_ITEM_FURNACE_MINECART: Minecart = cpp14::make_unique<cMinecartWithFurnace>(a_X, a_Y, a_Z); break; + case E_ITEM_MINECART_WITH_TNT: Minecart = cpp14::make_unique<cMinecartWithTNT>(a_X, a_Y, a_Z); break; + case E_ITEM_MINECART_WITH_HOPPER: Minecart = cpp14::make_unique<cMinecartWithHopper>(a_X, a_Y, a_Z); break; default: { return cEntity::INVALID_ID; } } // switch (a_MinecartType) - Minecart->Initialize(*this); - return Minecart->GetUniqueID(); + + auto ID = Minecart->GetUniqueID(); + Minecart->Initialize(std::move(Minecart), *this); + return ID; } @@ -1990,17 +1994,13 @@ UInt32 cWorld::SpawnMinecart(double a_X, double a_Y, double a_Z, int a_MinecartT UInt32 cWorld::SpawnBoat(double a_X, double a_Y, double a_Z) { - cBoat * Boat = new cBoat(a_X, a_Y, a_Z); - if (Boat == nullptr) - { - return cEntity::INVALID_ID; - } - if (!Boat->Initialize(*this)) + auto Boat = cpp14::make_unique<cBoat>(a_X, a_Y, a_Z); + auto ID = Boat->GetUniqueID(); + if (!Boat->Initialize(std::move(Boat), *this)) { - delete Boat; return cEntity::INVALID_ID; } - return Boat->GetUniqueID(); + return ID; } @@ -2008,14 +2008,15 @@ UInt32 cWorld::SpawnBoat(double a_X, double a_Y, double a_Z) UInt32 cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, int a_FuseTicks, double a_InitialVelocityCoeff) { - cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTicks); - TNT->Initialize(*this); + auto TNT = cpp14::make_unique<cTNTEntity>(a_X, a_Y, a_Z, a_FuseTicks); + auto ID = TNT->GetUniqueID(); TNT->SetSpeed( - a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1), /** -1, 0, 1 */ + a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1), /* -1, 0, 1 */ a_InitialVelocityCoeff * 2, a_InitialVelocityCoeff * (GetTickRandomNumber(2) - 1) ); - return TNT->GetUniqueID(); + TNT->Initialize(std::move(TNT), *this); + return ID; } @@ -2591,10 +2592,9 @@ void cWorld::SetChunkData(cSetChunkData & a_SetChunkData) // Initialise the entities: cEntityList Entities; - std::swap(a_SetChunkData.GetEntities(), Entities); - for (cEntityList::iterator itr = Entities.begin(), end = Entities.end(); itr != end; ++itr) + for (auto & Entity : a_SetChunkData.GetEntities()) { - (*itr)->Initialize(*this); + Entity->Initialize(std::move(Entity), *this); } // Save the chunk right after generating, so that we don't have to generate it again on next run @@ -3159,8 +3159,9 @@ void cWorld::ScheduleTask(int a_DelayTicks, std::function<void (cWorld &)> a_Tas -void cWorld::AddEntity(cEntity * a_Entity) +void cWorld::AddEntity(std::unique_ptr<cEntity> a_Entity) { + m_ChunkMap->AddEntity(std::move(a_Entity)); } @@ -3274,9 +3275,7 @@ bool cWorld::IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ) UInt32 cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby) { - cMonster * Monster = nullptr; - - Monster = cMonster::NewMonsterFromType(a_MonsterType); + auto Monster = cMonster::NewMonsterFromType(a_MonsterType); if (Monster == nullptr) { return cEntity::INVALID_ID; @@ -3288,13 +3287,13 @@ UInt32 cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterTyp Monster->SetAge(-1); } - return SpawnMobFinalize(Monster); + return SpawnMobFinalize(std::move(Monster)); } -UInt32 cWorld::SpawnMobFinalize(cMonster * a_Monster) +UInt32 cWorld::SpawnMobFinalize(std::unique_ptr<cMonster> a_Monster) { ASSERT(a_Monster != nullptr); @@ -3304,22 +3303,20 @@ UInt32 cWorld::SpawnMobFinalize(cMonster * a_Monster) // A plugin doesn't agree with the spawn. bail out. if (cPluginManager::Get()->CallHookSpawningMonster(*this, *a_Monster)) { - delete a_Monster; - a_Monster = nullptr; return cEntity::INVALID_ID; } + auto & Monster = *a_Monster; + // Initialize the monster into the current world. - if (!a_Monster->Initialize(*this)) + if (!a_Monster->Initialize(std::move(a_Monster), *this)) { - delete a_Monster; - a_Monster = nullptr; return cEntity::INVALID_ID; } - cPluginManager::Get()->CallHookSpawnedMonster(*this, *a_Monster); + cPluginManager::Get()->CallHookSpawnedMonster(*this, Monster); - return a_Monster->GetUniqueID(); + return Monster.GetUniqueID(); } @@ -3328,18 +3325,15 @@ UInt32 cWorld::SpawnMobFinalize(cMonster * a_Monster) UInt32 cWorld::CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed) { - cProjectileEntity * Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Item, a_Speed); - if (Projectile == nullptr) - { - return cEntity::INVALID_ID; - } - if (!Projectile->Initialize(*this)) + auto Projectile = cProjectileEntity::Create(a_Kind, a_Creator, a_PosX, a_PosY, a_PosZ, a_Item, a_Speed); + auto ID = Projectile->GetUniqueID(); + + if ((Projectile == nullptr) || !Projectile->Initialize(std::move(Projectile), *this)) { - delete Projectile; - Projectile = nullptr; return cEntity::INVALID_ID; } - return Projectile->GetUniqueID(); + + return ID; } diff --git a/src/World.h b/src/World.h index f6fbfae0f..de7fcac2e 100644 --- a/src/World.h +++ b/src/World.h @@ -276,7 +276,7 @@ public: /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr. The entity is added lazily - this function only puts it in a queue that is then processed by the Tick thread. */ - void AddEntity(cEntity * a_Entity); + void AddEntity(std::unique_ptr<cEntity> a_Entity); /** Returns true if an entity with the specified UniqueID exists in the world. Note: Only loaded chunks are considered. */ @@ -770,7 +770,7 @@ public: /** Spawns a mob of the specified type. Returns the mob's UniqueID if recognized and spawned, cEntity::INVALID_ID otherwise */ virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby = false) override; // tolua_export - UInt32 SpawnMobFinalize(cMonster * a_Monster); + UInt32 SpawnMobFinalize(std::unique_ptr<cMonster> a_Monster); /** Creates a projectile of the specified type. Returns the projectile's UniqueID if successful, cEntity::INVALID_ID otherwise Item parameter is currently used for Fireworks to correctly set entity metadata based on item metadata. */ diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 1d81ac0b7..d89ef5e67 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1651,7 +1651,7 @@ void cWSSAnvil::LoadBoatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N { return; } - a_Entities.push_back(Boat.release()); + a_Entities.emplace_back(std::move(Boat)); } @@ -1665,7 +1665,7 @@ void cWSSAnvil::LoadEnderCrystalFromNBT(cEntityList & a_Entities, const cParsedN { return; } - a_Entities.push_back(EnderCrystal.release()); + a_Entities.emplace_back(std::move(EnderCrystal)); } @@ -1690,7 +1690,7 @@ void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedN { return; } - a_Entities.push_back(FallingBlock.release()); + a_Entities.emplace_back(std::move(FallingBlock)); } @@ -1704,7 +1704,7 @@ void cWSSAnvil::LoadMinecartRFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - a_Entities.push_back(Minecart.release()); + a_Entities.emplace_back(std::move(Minecart)); } @@ -1736,7 +1736,7 @@ void cWSSAnvil::LoadMinecartCFromNBT(cEntityList & a_Entities, const cParsedNBT Minecart->SetSlot(a_NBT.GetByte(Slot), Item); } } // for itr - ItemDefs[] - a_Entities.push_back(Minecart.release()); + a_Entities.emplace_back(std::move(Minecart)); } @@ -1753,7 +1753,7 @@ void cWSSAnvil::LoadMinecartFFromNBT(cEntityList & a_Entities, const cParsedNBT // TODO: Load the Push and Fuel tags - a_Entities.push_back(Minecart.release()); + a_Entities.emplace_back(std::move(Minecart)); } @@ -1770,7 +1770,7 @@ void cWSSAnvil::LoadMinecartTFromNBT(cEntityList & a_Entities, const cParsedNBT // TODO: Everything to do with TNT carts - a_Entities.push_back(Minecart.release()); + a_Entities.emplace_back(std::move(Minecart)); } @@ -1787,7 +1787,7 @@ void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT // TODO: Everything to do with hopper carts - a_Entities.push_back(Minecart.release()); + a_Entities.emplace_back(std::move(Minecart)); } @@ -1821,7 +1821,7 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a Pickup->SetAge(a_NBT.GetShort(Age)); } - a_Entities.push_back(Pickup.release()); + a_Entities.emplace_back(std::move(Pickup)); } @@ -1843,7 +1843,7 @@ void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB TNT->SetFuseTicks(static_cast<int>(a_NBT.GetByte(FuseTicks))); } - a_Entities.push_back(TNT.release()); + a_Entities.emplace_back(std::move(TNT)); } @@ -1872,7 +1872,7 @@ void cWSSAnvil::LoadExpOrbFromNBT(cEntityList & a_Entities, const cParsedNBT & a ExpOrb->SetReward(a_NBT.GetShort(Reward)); } - a_Entities.push_back(ExpOrb.release()); + a_Entities.emplace_back(std::move(ExpOrb)); } @@ -1937,7 +1937,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT ItemFrame->SetItemRotation(static_cast<Byte>(a_NBT.GetByte(Rotation))); } - a_Entities.push_back(ItemFrame.release()); + a_Entities.emplace_back(std::move(ItemFrame)); } @@ -1960,7 +1960,7 @@ void cWSSAnvil::LoadPaintingFromNBT(cEntityList & a_Entities, const cParsedNBT & } LoadHangingFromNBT(*Painting.get(), a_NBT, a_TagIdx); - a_Entities.push_back(Painting.release()); + a_Entities.emplace_back(std::move(Painting)); } @@ -2031,7 +2031,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ } // Store the new arrow in the entities list: - a_Entities.push_back(Arrow.release()); + a_Entities.emplace_back(std::move(Arrow)); } @@ -2054,7 +2054,7 @@ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedN SplashPotion->SetPotionColor(a_NBT.FindChildByName(a_TagIdx, "PotionName")); // Store the new splash potion in the entities list: - a_Entities.push_back(SplashPotion.release()); + a_Entities.emplace_back(std::move(SplashPotion)); } @@ -2070,7 +2070,7 @@ void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & } // Store the new snowball in the entities list: - a_Entities.push_back(Snowball.release()); + a_Entities.emplace_back(std::move(Snowball)); } @@ -2086,7 +2086,7 @@ void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB } // Store the new egg in the entities list: - a_Entities.push_back(Egg.release()); + a_Entities.emplace_back(std::move(Egg)); } @@ -2102,7 +2102,7 @@ void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & } // Store the new fireball in the entities list: - a_Entities.push_back(Fireball.release()); + a_Entities.emplace_back(std::move(Fireball)); } @@ -2118,7 +2118,7 @@ void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT } // Store the new FireCharge in the entities list: - a_Entities.push_back(FireCharge.release()); + a_Entities.emplace_back(std::move(FireCharge)); } @@ -2134,7 +2134,7 @@ void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cPar } // Store the new enderpearl in the entities list: - a_Entities.push_back(Enderpearl.release()); + a_Entities.emplace_back(std::move(Enderpearl)); } @@ -2154,7 +2154,7 @@ void cWSSAnvil::LoadBatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2174,7 +2174,7 @@ void cWSSAnvil::LoadBlazeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2194,7 +2194,7 @@ void cWSSAnvil::LoadCaveSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2214,7 +2214,7 @@ void cWSSAnvil::LoadChickenFromNBT(cEntityList & a_Entities, const cParsedNBT & return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2234,7 +2234,7 @@ void cWSSAnvil::LoadCowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2254,7 +2254,7 @@ void cWSSAnvil::LoadCreeperFromNBT(cEntityList & a_Entities, const cParsedNBT & return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2274,7 +2274,7 @@ void cWSSAnvil::LoadEnderDragonFromNBT(cEntityList & a_Entities, const cParsedNB return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2294,7 +2294,7 @@ void cWSSAnvil::LoadEndermanFromNBT(cEntityList & a_Entities, const cParsedNBT & return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2314,7 +2314,7 @@ void cWSSAnvil::LoadGhastFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2334,7 +2334,7 @@ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2354,7 +2354,7 @@ void cWSSAnvil::LoadGuardianFromNBT(cEntityList & a_Entities, const cParsedNBT & return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2400,7 +2400,7 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2420,7 +2420,7 @@ void cWSSAnvil::LoadIronGolemFromNBT(cEntityList & a_Entities, const cParsedNBT return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2449,7 +2449,7 @@ void cWSSAnvil::LoadMagmaCubeFromNBT(cEntityList & a_Entities, const cParsedNBT return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2469,7 +2469,7 @@ void cWSSAnvil::LoadMooshroomFromNBT(cEntityList & a_Entities, const cParsedNBT return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2502,7 +2502,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2535,7 +2535,7 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2579,7 +2579,7 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2625,7 +2625,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2645,7 +2645,7 @@ void cWSSAnvil::LoadSilverfishFromNBT(cEntityList & a_Entities, const cParsedNBT return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2673,7 +2673,7 @@ void cWSSAnvil::LoadSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT & return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2702,7 +2702,7 @@ void cWSSAnvil::LoadSlimeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2722,7 +2722,7 @@ void cWSSAnvil::LoadSnowGolemFromNBT(cEntityList & a_Entities, const cParsedNBT return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2742,7 +2742,7 @@ void cWSSAnvil::LoadSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT & a return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2762,7 +2762,7 @@ void cWSSAnvil::LoadSquidFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2804,7 +2804,7 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2824,7 +2824,7 @@ void cWSSAnvil::LoadWitchFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2850,7 +2850,7 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a Monster->SetWitherInvulnerableTicks(static_cast<unsigned int>(a_NBT.GetInt(CurrLine))); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2917,7 +2917,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2958,7 +2958,7 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } @@ -2991,7 +2991,7 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT Monster->SetAge(Age); } - a_Entities.push_back(Monster.release()); + a_Entities.emplace_back(std::move(Monster)); } |