From 14e48ccb4bbad6f43121dc27f042083cda160f45 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 26 Jan 2014 06:20:39 -0800 Subject: Refactored cBlockHandler::OnUse and dependents --- src/ChunkMap.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 5797eb453..d0bccb837 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1117,6 +1117,21 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer * a_Player) BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { + // First check if it isn't queued in the m_FastSetBlockQueue: + { + int X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; + int ChunkX, ChunkY, ChunkZ; + cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); + ChunkY = 0; + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == X) && (itr->y == Y) && (itr->z == Z) && (itr->ChunkX == ChunkX) && (itr->ChunkZ == ChunkZ)) + { + return itr->BlockType; + } + } // for itr - m_FastSetBlockQueue[] + } int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ ); @@ -1135,6 +1150,17 @@ BLOCKTYPE cChunkMap::GetBlock(int a_BlockX, int a_BlockY, int a_BlockZ) NIBBLETYPE cChunkMap::GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ) { + // First check if it isn't queued in the m_FastSetBlockQueue: + { + cCSLock Lock(m_CSFastSetBlock); + for (sSetBlockList::iterator itr = m_FastSetBlockQueue.begin(); itr != m_FastSetBlockQueue.end(); ++itr) + { + if ((itr->x == a_BlockX) && (itr->y == a_BlockY) && (itr->z == a_BlockZ)) + { + return itr->BlockMeta; + } + } // for itr - m_FastSetBlockQueue[] + } int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ ); @@ -1207,8 +1233,14 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP -void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +void cChunkMap::SetBlock(cWorldInterface * a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) { + cChunkInterface *ChunkInterface = new cChunkInterface(this); + if (a_BlockType == E_BLOCK_AIR) + { + BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); + } + int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); @@ -1219,6 +1251,8 @@ void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_B Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta ); m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); } + BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + delete ChunkInterface; } @@ -2692,6 +2726,28 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) +void cChunkMap::FastSetBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + cCSLock Lock(m_CSFastSetBlock); + m_FastSetBlockQueue.push_back(sSetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta)); +} + +void cChunkMap::FastSetQueuedBlocks() +{ + // Asynchronously set blocks: + sSetBlockList FastSetBlockQueueCopy; + { + cCSLock Lock(m_CSFastSetBlock); + std::swap(FastSetBlockQueueCopy, m_FastSetBlockQueue); + } + this->FastSetBlocks(FastSetBlockQueueCopy); + if (!FastSetBlockQueueCopy.empty()) + { + // Some blocks failed, store them for next tick: + cCSLock Lock(m_CSFastSetBlock); + m_FastSetBlockQueue.splice(m_FastSetBlockQueue.end(), FastSetBlockQueueCopy); + } +} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2801,4 +2857,3 @@ void cChunkStay::Disable(void) - -- cgit v1.2.3 From 25ec7750aac9800bec83a844020a6eeda5cd4d74 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 31 Jan 2014 15:17:41 -0800 Subject: Changed signitures of Several BLockHandler Methods Changed the signitures of the following to use interfaces: GetPlacementBlockTypeMeta OnPlaced OnPlacedByPlayer OnDestroyed OnNeighbourChanged NeighbourChanged OnUse CanBeAt Check --- src/ChunkMap.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index d0bccb837..fb2495dd1 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1235,10 +1235,10 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP void cChunkMap::SetBlock(cWorldInterface * a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) { - cChunkInterface *ChunkInterface = new cChunkInterface(this); + cChunkInterface ChunkInterface(this); if (a_BlockType == E_BLOCK_AIR) { - BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); + BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(&ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); } int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; @@ -1251,8 +1251,7 @@ void cChunkMap::SetBlock(cWorldInterface * a_WorldInterface, int a_BlockX, int a Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta ); m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); } - BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); - delete ChunkInterface; + BlockHandler(a_BlockType)->OnPlaced(&ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } -- cgit v1.2.3 From c6304b2b4faf31c2e4a91a07bcac298467898dba Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 1 Feb 2014 05:06:32 -0800 Subject: Changed pointers to references --- src/ChunkMap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index fb2495dd1..049bb5fb2 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1233,12 +1233,12 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP -void cChunkMap::SetBlock(cWorldInterface * a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) +void cChunkMap::SetBlock(cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta) { cChunkInterface ChunkInterface(this); if (a_BlockType == E_BLOCK_AIR) { - BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(&ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); + BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); } int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; @@ -1251,7 +1251,7 @@ void cChunkMap::SetBlock(cWorldInterface * a_WorldInterface, int a_BlockX, int a Chunk->SetBlock(X, Y, Z, a_BlockType, a_BlockMeta ); m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, Chunk); } - BlockHandler(a_BlockType)->OnPlaced(&ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + BlockHandler(a_BlockType)->OnPlaced(ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } -- cgit v1.2.3 From e56d41175b7db000a87346bd1bb14f17ecc5a66a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 19:16:38 +0000 Subject: TNT improvements + Added entity damage + Added entity propulsion * Fixed #67 and fixed #230 --- src/ChunkMap.cpp | 152 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 115 insertions(+), 37 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 5797eb453..e23a29a11 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -15,6 +15,9 @@ #include "Blocks/BlockHandler.h" #include "MobCensus.h" #include "MobSpawner.h" +#include "BoundingBox.h" + +#include "Entities/Pickup.h" #ifndef _WIN32 #include // abs @@ -1624,49 +1627,52 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ { return; } - + + bool ShouldDestroyBlocks = true; + // Don't explode if the explosion center is inside a liquid block: - switch (m_World->GetBlock((int)floor(a_BlockX), (int)floor(a_BlockY), (int)floor(a_BlockZ))) + if (IsBlockLiquid(m_World->GetBlock((int)floor(a_BlockX), (int)floor(a_BlockY), (int)floor(a_BlockZ)))) { - case E_BLOCK_WATER: - case E_BLOCK_STATIONARY_WATER: - case E_BLOCK_LAVA: - case E_BLOCK_STATIONARY_LAVA: - { - return; - } + ShouldDestroyBlocks = false; } - - cBlockArea area; + + int ExplosionSizeInt = (int)ceil(a_ExplosionSize); + int ExplosionSizeSq = ExplosionSizeInt * ExplosionSizeInt; + int bx = (int)floor(a_BlockX); int by = (int)floor(a_BlockY); int bz = (int)floor(a_BlockZ); - int ExplosionSizeInt = (int) ceil(a_ExplosionSize); - int ExplosionSizeSq = ExplosionSizeInt * ExplosionSizeInt; - a_BlocksAffected.reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt); + int MinY = std::max((int)floor(a_BlockY - ExplosionSizeInt), 0); int MaxY = std::min((int)ceil(a_BlockY + ExplosionSizeInt), cChunkDef::Height - 1); - area.Read(m_World, bx - ExplosionSizeInt, (int)ceil(a_BlockX + ExplosionSizeInt), MinY, MaxY, bz - ExplosionSizeInt, (int)ceil(a_BlockZ + ExplosionSizeInt)); - for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++) + + if (ShouldDestroyBlocks) { - for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++) + cBlockArea area; + + a_BlocksAffected.reserve(8 * ExplosionSizeInt * ExplosionSizeInt * ExplosionSizeInt); + + area.Read(m_World, bx - ExplosionSizeInt, (int)ceil(a_BlockX + ExplosionSizeInt), MinY, MaxY, bz - ExplosionSizeInt, (int)ceil(a_BlockZ + ExplosionSizeInt)); + for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++) { - if ((by + y >= cChunkDef::Height) || (by + y < 0)) + for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++) { - // Outside of the world - continue; - } - for (int z = -ExplosionSizeInt; z < ExplosionSizeInt; z++) - { - if ((x * x + y * y + z * z) > ExplosionSizeSq) + if ((by + y >= cChunkDef::Height) || (by + y < 0)) { - // Too far away + // Outside of the world continue; } - - BLOCKTYPE Block = area.GetBlockType(bx + x, by + y, bz + z); - switch (Block) + for (int z = -ExplosionSizeInt; z < ExplosionSizeInt; z++) { + if ((x * x + y * y + z * z) > ExplosionSizeSq) + { + // Too far away + continue; + } + + BLOCKTYPE Block = area.GetBlockType(bx + x, by + y, bz + z); + switch (Block) + { case E_BLOCK_TNT: { // Activate the TNT, with a random fuse between 10 to 30 game ticks @@ -1691,20 +1697,20 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_WATER); break; } - + case E_BLOCK_STATIONARY_LAVA: { // Turn into simulated lava: area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_LAVA); break; } - + case E_BLOCK_AIR: { // No pickups for air break; } - + default: { if (m_World->GetTickRandomNumber(100) <= 25) // 25% chance of pickups @@ -1713,16 +1719,88 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ cBlockHandler * Handler = BlockHandler(Block); Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. - m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + //m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); } - } // switch (BlockType) - } // for z - } // for y - } // for x - area.Write(m_World, bx - ExplosionSizeInt, MinY, bz - ExplosionSizeInt); + } // switch (BlockType) + } // for z + } // for y + } // for x + area.Write(m_World, bx - ExplosionSizeInt, MinY, bz - ExplosionSizeInt); + } + + class cTNTDamageCallback : + public cEntityCallback + { + public: + cTNTDamageCallback(cBoundingBox & a_bbTNT, Vector3d a_ExplosionPos, int a_ExplosionSize, int a_ExplosionSizeSq) : + m_bbTNT(a_bbTNT), + m_ExplosionPos(a_ExplosionPos), + m_ExplosionSize(a_ExplosionSize), + m_ExplosionSizeSq(a_ExplosionSizeSq) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + if (a_Entity->IsPickup()) + { + if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible + { + return false; + } + } + + Vector3d EntityPos = a_Entity->GetPosition(); + cBoundingBox bbEntity(EntityPos, a_Entity->GetWidth() / 2, a_Entity->GetHeight()); + + if (m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround + { + Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); + Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); + + AbsoluteEntityPos -= m_ExplosionPos; + AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; + + double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; + FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + if (FinalDamage > a_Entity->GetMaxHealth()) + FinalDamage = a_Entity->GetMaxHealth(); + else if (FinalDamage < 0) + return false; + + if (!a_Entity->IsTNT()) + { + a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); + } + + Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; + if (distance_explosion.SqrLength() < 4096.0) + { + distance_explosion.Normalize(); + distance_explosion *= m_ExplosionSizeSq; + + a_Entity->AddSpeed(distance_explosion); + } + } + return false; + } + + protected: + cBoundingBox & m_bbTNT; + Vector3d m_ExplosionPos; + int m_ExplosionSize; + int m_ExplosionSizeSq; + }; + + cBoundingBox bbTNT(Vector3d(a_BlockX, a_BlockY, a_BlockZ), 0.5, 1); + bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); + + + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSize, ExplosionSizeSq); + ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): WakeUpSimulatorsInArea( -- cgit v1.2.3 From ba398c06d78f6e11e7ac322e5ef46df4a91b5776 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 2 Feb 2014 21:24:06 +0000 Subject: Uncommented pickup spawner code --- src/ChunkMap.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index e23a29a11..53e5b956b 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1719,7 +1719,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ cBlockHandler * Handler = BlockHandler(Block); Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. - //m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); @@ -1747,7 +1747,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ { if (a_Entity->IsPickup()) { - if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible + if (((cPickup *)a_Entity)->GetAge() < 20) // If pickup age is smaller than one second, it is invincible (so we don't kill pickups that were just spawned) { return false; } @@ -1761,21 +1761,25 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); + // Work out how far we are from the edge of the TNT's explosive effect AbsoluteEntityPos -= m_ExplosionPos; AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + + // Clip damage values if (FinalDamage > a_Entity->GetMaxHealth()) FinalDamage = a_Entity->GetMaxHealth(); else if (FinalDamage < 0) return false; - if (!a_Entity->IsTNT()) + if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible { a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); } + // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; if (distance_explosion.SqrLength() < 4096.0) { -- cgit v1.2.3 From e3b9cdebc9c07a548c4aa219d53cf53c2c111b48 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 14:01:47 +0000 Subject: Inversed condition --- src/ChunkMap.cpp | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 53e5b956b..4511391ff 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1756,39 +1756,42 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Vector3d EntityPos = a_Entity->GetPosition(); cBoundingBox bbEntity(EntityPos, a_Entity->GetWidth() / 2, a_Entity->GetHeight()); - if (m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround + if (!m_bbTNT.IsInside(bbEntity)) // IsInside actually acts like DoesSurround { - Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); - Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); + return false; + } + + Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); + Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); - // Work out how far we are from the edge of the TNT's explosive effect - AbsoluteEntityPos -= m_ExplosionPos; - AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; + // Work out how far we are from the edge of the TNT's explosive effect + AbsoluteEntityPos -= m_ExplosionPos; + AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; - double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; - FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; + FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); - // Clip damage values - if (FinalDamage > a_Entity->GetMaxHealth()) - FinalDamage = a_Entity->GetMaxHealth(); - else if (FinalDamage < 0) - return false; + // Clip damage values + if (FinalDamage > a_Entity->GetMaxHealth()) + FinalDamage = a_Entity->GetMaxHealth(); + else if (FinalDamage < 0) + return false; - if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible - { - a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); - } + if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible + { + a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); + } - // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() - Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; - if (distance_explosion.SqrLength() < 4096.0) - { - distance_explosion.Normalize(); - distance_explosion *= m_ExplosionSizeSq; + // Apply force to entities around the explosion - code modified from World.cpp DoExplosionAt() + Vector3d distance_explosion = a_Entity->GetPosition() - m_ExplosionPos; + if (distance_explosion.SqrLength() < 4096.0) + { + distance_explosion.Normalize(); + distance_explosion *= m_ExplosionSizeSq; - a_Entity->AddSpeed(distance_explosion); - } + a_Entity->AddSpeed(distance_explosion); } + return false; } -- cgit v1.2.3 From d1b5f0859a4176a31f764b23cf0fce49743d245e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 22:55:15 +0000 Subject: Greatly improved TNT propulsion chances --- src/ChunkMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 1e2181f32..757396a20 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1808,7 +1808,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ if (FinalDamage > a_Entity->GetMaxHealth()) FinalDamage = a_Entity->GetMaxHealth(); else if (FinalDamage < 0) - return false; + FinalDamage = 0; if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible { -- cgit v1.2.3 From 630507fd5b8a7ac280ee75994f98b9ecfdcb7a70 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 23:07:22 +0000 Subject: Fixed a bunch of MSVS warnings * Possibly also fixed some bugs with pathfinding and TNT, though unlikely --- src/ChunkMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 1e2181f32..cb10e275d 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1839,7 +1839,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); - cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSize, ExplosionSizeSq); + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSizeInt, ExplosionSizeSq); ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): -- cgit v1.2.3 From 94c343fe079346caf24be265234cce194bc3b450 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 4 Feb 2014 23:40:58 +0000 Subject: Fixed explosions bug * Fixed bug where explosions would sometimes never be sent --- src/ChunkMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index cb10e275d..db2a1b1d9 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1839,7 +1839,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); - cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), a_ExplosionSizeInt, ExplosionSizeSq); + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), ExplosionSizeInt, ExplosionSizeSq); ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): -- cgit v1.2.3 From ea71bfa9b645cda80b7d4364c675ebaee8db8353 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 8 Feb 2014 21:55:21 +0100 Subject: Initial ChunkStay code. --- src/ChunkMap.cpp | 185 ++++++++++++++++++++++--------------------------------- 1 file changed, 72 insertions(+), 113 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 757396a20..a9f6bf00b 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -134,7 +134,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk(int a_ChunkX, int a_ChunkZ) -cChunkPtr cChunkMap::GetChunk( int a_ChunkX, int a_ChunkY, int a_ChunkZ ) +cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { // No need to lock m_CSLayers, since it's already locked by the operation that called us ASSERT(m_CSLayers.IsLockedByCurrentThread()); @@ -897,17 +897,25 @@ void cChunkMap::SetChunkData( bool a_MarkDirty ) { - cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); - if (Chunk == NULL) - { - return; - } - Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_BlockEntities); - - if (a_MarkDirty) { - Chunk->MarkDirty(); + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoLoad(a_ChunkX, ZERO_CHUNK_Y, a_ChunkZ); + if (Chunk == NULL) + { + return; + } + Chunk->SetAllData(a_BlockTypes, a_BlockMeta, a_BlockLight, a_BlockSkyLight, a_HeightMap, a_BiomeMap, a_BlockEntities); + + if (a_MarkDirty) + { + Chunk->MarkDirty(); + } + + // Notify relevant ChunkStays: + for (cChunkStays::iterator itr = m_ChunkStays.begin(), end = m_ChunkStays.end(); itr != end; ++itr) + { + (*itr)->ChunkAvailable(a_ChunkX, a_ChunkZ); + } // for itr - m_ChunkStays[] } // Notify plugins of the chunk becoming available @@ -2206,24 +2214,6 @@ bool cChunkMap::SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const ASt -void cChunkMap::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay) -{ - cCSLock Lock(m_CSLayers); - for (cChunkCoordsList::const_iterator itr = a_Chunks.begin(); itr != a_Chunks.end(); ++itr) - { - cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); - if (Chunk == NULL) - { - continue; - } - Chunk->Stay(a_Stay); - } -} - - - - - void cChunkMap::MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ) { cCSLock Lock(m_CSLayers); @@ -2810,12 +2800,16 @@ void cChunkMap::cChunkLayer::UnloadUnusedChunks(void) -void cChunkMap::FastSetBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +void cChunkMap::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { cCSLock Lock(m_CSFastSetBlock); - m_FastSetBlockQueue.push_back(sSetBlock(a_X, a_Y, a_Z, a_BlockType, a_BlockMeta)); + m_FastSetBlockQueue.push_back(sSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta)); } + + + + void cChunkMap::FastSetQueuedBlocks() { // Asynchronously set blocks: @@ -2834,110 +2828,75 @@ void cChunkMap::FastSetQueuedBlocks() } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cChunkStay: - -cChunkStay::cChunkStay(cWorld * a_World) : - m_World(a_World), - m_IsEnabled(false) -{ -} - - - - - -cChunkStay::~cChunkStay() -{ - Clear(); -} - - - - - -void cChunkStay::Clear(void) -{ - if (m_IsEnabled) - { - Disable(); - } - m_Chunks.clear(); -} - - -void cChunkStay::Add(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +void cChunkMap::AddChunkStay(cChunkStay & a_ChunkStay) { - ASSERT(!m_IsEnabled); - - for (cChunkCoordsList::const_iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + cCSLock Lock(m_CSLayers); + + // Add it to the list: + ASSERT(std::find(m_ChunkStays.begin(), m_ChunkStays.end(), &a_ChunkStay) == m_ChunkStays.end()); // Has not yet been added + m_ChunkStays.push_back(&a_ChunkStay); + + // Schedule all chunks to be loaded / generated, and mark each as locked: + const cChunkCoordsVector & WantedChunks = a_ChunkStay.GetChunks(); + for (cChunkCoordsVector::const_iterator itr = WantedChunks.begin(); itr != WantedChunks.end(); ++itr) { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + cChunkPtr Chunk = GetChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + if (Chunk == NULL) { - // Already present - return; + continue; } - } // for itr - Chunks[] - m_Chunks.push_back(cChunkCoords(a_ChunkX, a_ChunkY, a_ChunkZ)); + Chunk->Stay(true); + if (Chunk->IsValid()) + { + a_ChunkStay.ChunkAvailable(itr->m_ChunkX, itr->m_ChunkZ); + } + } // for itr - WantedChunks[] } -void cChunkStay::Remove(int a_ChunkX, int a_ChunkY, int a_ChunkZ) +/** Removes the specified cChunkStay descendant from the internal list of ChunkStays. */ +void cChunkMap::DelChunkStay(cChunkStay & a_ChunkStay) { - ASSERT(!m_IsEnabled); - - for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + cCSLock Lock(m_CSLayers); + + // Remove from the list of active chunkstays: + bool HasFound = false; + for (cChunkStays::iterator itr = m_ChunkStays.begin(), end = m_ChunkStays.end(); itr != end; ++itr) { - if ((itr->m_ChunkX == a_ChunkX) && (itr->m_ChunkY == a_ChunkY) && (itr->m_ChunkZ == a_ChunkZ)) + if (*itr == &a_ChunkStay) { - // Found, un-"stay" - m_Chunks.erase(itr); - return; + m_ChunkStays.erase(itr); + HasFound = true; + break; } - } // for itr - m_Chunks[] -} - - - - - -void cChunkStay::Enable(void) -{ - ASSERT(!m_IsEnabled); + } // for itr - m_ChunkStays[] - m_World->ChunksStay(*this, true); - m_IsEnabled = true; -} - - - - - -void cChunkStay::Load(void) -{ - for (cChunkCoordsList::iterator itr = m_Chunks.begin(); itr != m_Chunks.end(); ++itr) + if (!HasFound) + { + ASSERT(!"Removing a cChunkStay that hasn't been added!"); + return; + } + + // Unmark all contained chunks: + const cChunkCoordsVector & Chunks = a_ChunkStay.GetChunks(); + for (cChunkCoordsVector::const_iterator itr = Chunks.begin(), end = Chunks.end(); itr != end; ++itr) { - m_World->TouchChunk(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); - } // for itr - m_Chunks[] + cChunkPtr Chunk = GetChunkNoLoad(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ); + if (Chunk == NULL) + { + continue; + } + Chunk->Stay(false); + } // for itr - Chunks[] } -void cChunkStay::Disable(void) -{ - ASSERT(m_IsEnabled); - - m_World->ChunksStay(*this, false); - m_IsEnabled = false; -} - - - -- cgit v1.2.3 From 9cebc9157cf43ba639227b9d79b980b3613dda1e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 10 Feb 2014 22:47:10 +0100 Subject: Rewritten Lua ChunkStay API into a single function, cWorld:ChunkStay(). This fixes problems with indeterminate class object lifespan (Lua-GC) and forgetting to disable it or keep it until ready. --- src/ChunkMap.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 7726a0b7e..0c5a8d9b9 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -912,9 +912,18 @@ void cChunkMap::SetChunkData( } // Notify relevant ChunkStays: - for (cChunkStays::iterator itr = m_ChunkStays.begin(), end = m_ChunkStays.end(); itr != end; ++itr) + for (cChunkStays::iterator itr = m_ChunkStays.begin(); itr != m_ChunkStays.end(); ) { - (*itr)->ChunkAvailable(a_ChunkX, a_ChunkZ); + if ((*itr)->ChunkAvailable(a_ChunkX, a_ChunkZ)) + { + cChunkStays::iterator cur = itr; + ++itr; + m_ChunkStays.erase(cur); + } + else + { + ++itr; + } } // for itr - m_ChunkStays[] } -- cgit v1.2.3 From 803ea412361ee2f4b1d74a811ddbee05f50c9345 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 18 Feb 2014 13:06:18 +0100 Subject: Added cWorld:SetAreaBiome() API function. Fixes #675. --- src/ChunkMap.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 0c5a8d9b9..01195e8bc 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1390,10 +1390,10 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) { int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ; - cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ ); + cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); cCSLock Lock(m_CSLayers); - cChunkPtr Chunk = GetChunk( ChunkX, ZERO_CHUNK_Y, ChunkZ ); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); if ((Chunk != NULL) && Chunk->IsValid()) { return Chunk->GetBiomeAt(X, Z); @@ -1408,6 +1408,63 @@ EMCSBiome cChunkMap::GetBiomeAt (int a_BlockX, int a_BlockZ) +bool cChunkMap::SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome) +{ + int ChunkX, ChunkZ, X = a_BlockX, Y = 0, Z = a_BlockZ; + cChunkDef::AbsoluteToRelative(X, Y, Z, ChunkX, ChunkZ); + + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunk(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk != NULL) && Chunk->IsValid()) + { + Chunk->SetBiomeAt(X, Z, a_Biome); + return true; + } + return false; +} + + + + + +bool cChunkMap::SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome) +{ + // Translate coords to relative: + int Y = 0; + int MinChunkX, MinChunkZ, MinX = a_MinX, MinZ = a_MinZ; + int MaxChunkX, MaxChunkZ, MaxX = a_MaxX, MaxZ = a_MaxZ; + cChunkDef::AbsoluteToRelative(MinX, Y, MinZ, MinChunkX, MinChunkZ); + cChunkDef::AbsoluteToRelative(MaxX, Y, MaxZ, MaxChunkX, MaxChunkZ); + + // Go through all chunks, set: + bool res = true; + cCSLock Lock(m_CSLayers); + for (int x = MinChunkX; x <= MaxChunkX; x++) + { + int MinRelX = (x == MinChunkX) ? MinX : 0; + int MaxRelX = (x == MaxChunkX) ? MaxX : cChunkDef::Width - 1; + for (int z = MinChunkZ; z <= MaxChunkZ; z++) + { + int MinRelZ = (z == MinChunkZ) ? MinZ : 0; + int MaxRelZ = (z == MaxChunkZ) ? MaxZ : cChunkDef::Width - 1; + cChunkPtr Chunk = GetChunkNoLoad(x, ZERO_CHUNK_Y, z); + if ((Chunk != NULL) && Chunk->IsValid()) + { + Chunk->SetAreaBiome(MinRelX, MaxRelX, MinRelZ, MaxRelZ, a_Biome); + } + else + { + res = false; + } + } // for z + } // for x + return res; +} + + + + + bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure) { bool res = true; -- cgit v1.2.3 From 52c41f886927cf62ed592ba7fec974eee6b16844 Mon Sep 17 00:00:00 2001 From: Howaner Date: Tue, 18 Feb 2014 21:40:02 +0100 Subject: Add Heads completely --- src/ChunkMap.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 0c5a8d9b9..5f1674c03 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -2121,6 +2121,24 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c +bool cChunkMap::DoWithSkullBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cSkullBlockCallback & a_Callback) +{ + int ChunkX, ChunkZ; + int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; + cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk == NULL) && !Chunk->IsValid()) + { + return false; + } + return Chunk->DoWithSkullBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + + bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { int ChunkX, ChunkZ; -- cgit v1.2.3 From d63ce62f3bbe4b8e89b8c54af4b71d77bcc7e052 Mon Sep 17 00:00:00 2001 From: Howaner Date: Wed, 19 Feb 2014 14:45:09 +0100 Subject: Rename SkullEntity to MobHeadEntity --- src/ChunkMap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 5f1674c03..0d19ecd28 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -2121,7 +2121,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c -bool cChunkMap::DoWithSkullBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cSkullBlockCallback & a_Callback) +bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback) { int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; @@ -2132,7 +2132,7 @@ bool cChunkMap::DoWithSkullBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cSk { return false; } - return Chunk->DoWithSkullBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); + return Chunk->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); } -- cgit v1.2.3 From 728e3c68b61e68d4cb73071cf04b44d268742aca Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 23 Feb 2014 16:30:49 +0100 Subject: Fixed a possible crash in cWorld::WakeUpSimulatorsInArea(). The Y coords weren't checked. --- src/ChunkMap.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index fbb8706e0..b5795fbaf 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -805,6 +805,10 @@ void cChunkMap::WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) /// Wakes up the simulators for the specified area of blocks void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ) { + // Limit the Y coords: + a_MinBlockY = std::max(a_MinBlockY, 0); + a_MaxBlockY = std::min(a_MaxBlockY, cChunkDef::Height - 1); + cSimulatorManager * SimMgr = m_World->GetSimulatorManager(); int MinChunkX, MinChunkZ, MaxChunkX, MaxChunkZ; cChunkDef::BlockToChunk(a_MinBlockX, a_MinBlockZ, MinChunkX, MinChunkZ); -- cgit v1.2.3 From 53231bebd650b9398060cee1434ad4c44152d36e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 5 Mar 2014 22:12:48 +0000 Subject: Added extra awesomeness to TNT + TNT now has a chance of flinging FallingBlock entities around * Improved TNT damage * Improved TNT spawning visuals * Possible fix for 'SetSwimState failure' messages in debug --- src/ChunkMap.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index b5795fbaf..b13337b44 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1832,8 +1832,17 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } + else if (m_World->GetTickRandomNumber(100) < 20) // 20% chance of flinging stuff around + { + if (!cBlockInfo::FullyOccupiesVoxel(area.GetBlockType(bx + x, by + y, bz + z))) + { + break; + } + m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, area.GetBlockType(bx + x, by + y, bz + z), area.GetBlockMeta(bx + x, by + y, bz + z)); + } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); + break; } } // switch (BlockType) } // for z @@ -1846,11 +1855,10 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ public cEntityCallback { public: - cTNTDamageCallback(cBoundingBox & a_bbTNT, Vector3d a_ExplosionPos, int a_ExplosionSize, int a_ExplosionSizeSq) : + cTNTDamageCallback(cBoundingBox & a_bbTNT, Vector3d a_ExplosionPos, int a_ExplosionSize) : m_bbTNT(a_bbTNT), m_ExplosionPos(a_ExplosionPos), - m_ExplosionSize(a_ExplosionSize), - m_ExplosionSizeSq(a_ExplosionSizeSq) + m_ExplosionSize(a_ExplosionSize) { } @@ -1873,14 +1881,16 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } Vector3d AbsoluteEntityPos(abs(EntityPos.x), abs(EntityPos.y), abs(EntityPos.z)); - Vector3d MaxExplosionBoundary(m_ExplosionSizeSq, m_ExplosionSizeSq, m_ExplosionSizeSq); // Work out how far we are from the edge of the TNT's explosive effect AbsoluteEntityPos -= m_ExplosionPos; - AbsoluteEntityPos = MaxExplosionBoundary - AbsoluteEntityPos; - double FinalDamage = ((AbsoluteEntityPos.x + AbsoluteEntityPos.y + AbsoluteEntityPos.z) / 3) * m_ExplosionSize; - FinalDamage = a_Entity->GetMaxHealth() - abs(FinalDamage); + // All to positive + AbsoluteEntityPos.x = abs(AbsoluteEntityPos.x); + AbsoluteEntityPos.y = abs(AbsoluteEntityPos.y); + AbsoluteEntityPos.z = abs(AbsoluteEntityPos.z); + + double FinalDamage = (((1 / AbsoluteEntityPos.x) + (1 / AbsoluteEntityPos.y) + (1 / AbsoluteEntityPos.z)) * 2) * m_ExplosionSize; // Clip damage values if (FinalDamage > a_Entity->GetMaxHealth()) @@ -1888,7 +1898,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ else if (FinalDamage < 0) FinalDamage = 0; - if (!a_Entity->IsTNT()) // Don't apply damage to other TNT entities, they should be invincible + if (!a_Entity->IsTNT() && !a_Entity->IsFallingBlock()) // Don't apply damage to other TNT entities, they should be invincible { a_Entity->TakeDamage(dtExplosion, NULL, (int)FinalDamage, 0); } @@ -1898,7 +1908,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ if (distance_explosion.SqrLength() < 4096.0) { distance_explosion.Normalize(); - distance_explosion *= m_ExplosionSizeSq; + distance_explosion *= m_ExplosionSize * m_ExplosionSize; a_Entity->AddSpeed(distance_explosion); } @@ -1910,14 +1920,13 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ cBoundingBox & m_bbTNT; Vector3d m_ExplosionPos; int m_ExplosionSize; - int m_ExplosionSizeSq; }; cBoundingBox bbTNT(Vector3d(a_BlockX, a_BlockY, a_BlockZ), 0.5, 1); bbTNT.Expand(ExplosionSizeInt * 2, ExplosionSizeInt * 2, ExplosionSizeInt * 2); - cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), ExplosionSizeInt, ExplosionSizeSq); + cTNTDamageCallback TNTDamageCallback(bbTNT, Vector3d(a_BlockX, a_BlockY, a_BlockZ), ExplosionSizeInt); ForEachEntity(TNTDamageCallback); // Wake up all simulators for the area, so that water and lava flows and sand falls into the blasted holes (FS #391): -- cgit v1.2.3 From 787a71929cd4095681b37acf81332b7b9c3ddf89 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 7 Mar 2014 01:30:34 +0100 Subject: Add Flower Pots --- src/ChunkMap.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index b5795fbaf..7f999fd31 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -2200,6 +2200,24 @@ bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c +bool cChunkMap::DoWithFlowerPotAt(int a_BlockX, int a_BlockY, int a_BlockZ, cFlowerPotCallback & a_Callback) +{ + int ChunkX, ChunkZ; + int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; + cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if ((Chunk == NULL) && !Chunk->IsValid()) + { + return false; + } + return Chunk->DoWithFlowerPotAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); +} + + + + + bool cChunkMap::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4) { int ChunkX, ChunkZ; -- cgit v1.2.3 From c2090c0d11313bd67b02c482f1ca80d5c4567d27 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 7 Mar 2014 11:44:16 +0100 Subject: Add Lua Bindings for FlowerPotEntity.h and add documentation. --- src/ChunkMap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 7f999fd31..40964c654 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -2182,7 +2182,7 @@ bool cChunkMap::DoWithCommandBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c -bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadBlockCallback & a_Callback) +bool cChunkMap::DoWithMobHeadAt(int a_BlockX, int a_BlockY, int a_BlockZ, cMobHeadCallback & a_Callback) { int ChunkX, ChunkZ; int BlockX = a_BlockX, BlockY = a_BlockY, BlockZ = a_BlockZ; @@ -2193,7 +2193,7 @@ bool cChunkMap::DoWithMobHeadBlockAt(int a_BlockX, int a_BlockY, int a_BlockZ, c { return false; } - return Chunk->DoWithMobHeadBlockAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); + return Chunk->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback); } -- cgit v1.2.3 From 462829e23d8d3404e58ffc64fd19cf39e9be218f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 10 Mar 2014 18:35:02 +0000 Subject: Shrapnel now configurable --- src/ChunkMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index b13337b44..e750ad731 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1832,7 +1832,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } - else if (m_World->GetTickRandomNumber(100) < 20) // 20% chance of flinging stuff around + else if (m_World->IsTNTShrapnelEnabled() && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { if (!cBlockInfo::FullyOccupiesVoxel(area.GetBlockType(bx + x, by + y, bz + z))) { -- cgit v1.2.3 From b9fce71bf68768ee86ce128f353fea5533f50732 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 16 Mar 2014 14:01:22 +0100 Subject: Add new leaves to all classes. --- src/ChunkMap.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 40964c654..62c1ec544 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1383,6 +1383,13 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) } break; } + case E_BLOCK_NEW_LEAVES: + { + if (itr->BlockType == E_BLOCK_NEW_LOG) + { + Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); + } + } } } // for itr - a_Blocks[] } -- cgit v1.2.3 From 89027cb67510f49114b9cd99c585009465a3ef66 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 16 Mar 2014 22:00:28 +0100 Subject: Fixed double to float conversions. --- src/ChunkMap.cpp | 91 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 45 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 62c1ec544..60fbf39d4 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1791,57 +1791,58 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ BLOCKTYPE Block = area.GetBlockType(bx + x, by + y, bz + z); switch (Block) { - case E_BLOCK_TNT: - { - // Activate the TNT, with a random fuse between 10 to 30 game ticks - double FuseTime = (double)(10 + m_World->GetTickRandomNumber(20)) / 20; - m_World->SpawnPrimedTNT(a_BlockX + x + 0.5, a_BlockY + y + 0.5, a_BlockZ + z + 0.5, FuseTime); - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); - a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - break; - } - case E_BLOCK_OBSIDIAN: - case E_BLOCK_BEDROCK: - case E_BLOCK_WATER: - case E_BLOCK_LAVA: - { - // These blocks are not affected by explosions - break; - } - - case E_BLOCK_STATIONARY_WATER: - { - // Turn into simulated water: - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_WATER); - break; - } + case E_BLOCK_TNT: + { + // Activate the TNT, with a random fuse between 10 to 30 game ticks + int FuseTime = 10 + m_World->GetTickRandomNumber(20); + m_World->SpawnPrimedTNT(a_BlockX + x + 0.5, a_BlockY + y + 0.5, a_BlockZ + z + 0.5, FuseTime); + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); + a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); + break; + } + + case E_BLOCK_OBSIDIAN: + case E_BLOCK_BEDROCK: + case E_BLOCK_WATER: + case E_BLOCK_LAVA: + { + // These blocks are not affected by explosions + break; + } - case E_BLOCK_STATIONARY_LAVA: - { - // Turn into simulated lava: - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_LAVA); - break; - } + case E_BLOCK_STATIONARY_WATER: + { + // Turn into simulated water: + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_WATER); + break; + } - case E_BLOCK_AIR: - { - // No pickups for air - break; - } + case E_BLOCK_STATIONARY_LAVA: + { + // Turn into simulated lava: + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_LAVA); + break; + } - default: - { - if (m_World->GetTickRandomNumber(100) <= 25) // 25% chance of pickups + case E_BLOCK_AIR: { - cItems Drops; - cBlockHandler * Handler = BlockHandler(Block); + // No pickups for air + break; + } - Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. - m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + default: + { + if (m_World->GetTickRandomNumber(100) <= 25) // 25% chance of pickups + { + cItems Drops; + cBlockHandler * Handler = BlockHandler(Block); + + Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. + m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); + } + area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); + a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); } - area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); - a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); - } } // switch (BlockType) } // for z } // for y -- cgit v1.2.3 From 91f64da2a6895f2dee7d010e71282b0c5fb6bf02 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 18 Mar 2014 15:45:16 +0100 Subject: Fixed chunkmap tree block replacing. --- src/ChunkMap.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 60fbf39d4..ffba52d54 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1376,19 +1376,13 @@ void cChunkMap::ReplaceTreeBlocks(const sSetBlockVector & a_Blocks) break; } case E_BLOCK_LEAVES: - { - if (itr->BlockType == E_BLOCK_LOG) - { - Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); - } - break; - } case E_BLOCK_NEW_LEAVES: { - if (itr->BlockType == E_BLOCK_NEW_LOG) + if ((itr->BlockType == E_BLOCK_LOG) || (itr->BlockType == E_BLOCK_NEW_LOG)) { Chunk->SetBlock(itr->x, itr->y, itr->z, itr->BlockType, itr->BlockMeta); } + break; } } } // for itr - a_Blocks[] -- cgit v1.2.3 From 23ffaa19b7c93f076a2d5a85018f7fb1a2260ea8 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 18 Mar 2014 20:45:10 +0000 Subject: Added levels of shrapnel --- src/ChunkMap.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index ab4e01334..6ce928252 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1832,13 +1832,17 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } - else if (m_World->IsTNTShrapnelEnabled() && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around + else if ((m_World->GetTNTShrapnelLevel() > 0) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { - if (!cBlockInfo::FullyOccupiesVoxel(area.GetBlockType(bx + x, by + y, bz + z))) + if (!cBlockInfo::FullyOccupiesVoxel(Block)) { break; } - m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, area.GetBlockType(bx + x, by + y, bz + z), area.GetBlockMeta(bx + x, by + y, bz + z)); + else if ((m_World->GetTNTShrapnelLevel() == 1) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) + { + break; + } + m_World->SpawnFallingBlock(bx + x, by + y + 5, bz + z, Block, area.GetBlockMeta(bx + x, by + y, bz + z)); } area.SetBlockType(bx + x, by + y, bz + z, E_BLOCK_AIR); a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); -- cgit v1.2.3 From 0524d70774f830b08abb1dee4e8340b25c569d2a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 19 Mar 2014 23:06:39 +0000 Subject: ENUMified shrapnel level --- src/ChunkMap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ChunkMap.cpp') diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 867b37ed0..e695f0ab2 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1834,13 +1834,13 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ Handler->ConvertToPickups(Drops, area.GetBlockMeta(bx + x, by + y, bz + z)); // Stone becomes cobblestone, coal ore becomes coal, etc. m_World->SpawnItemPickups(Drops, bx + x, by + y, bz + z); } - else if ((m_World->GetTNTShrapnelLevel() > 0) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around + else if ((m_World->GetTNTShrapnelLevel() > slNone) && (m_World->GetTickRandomNumber(100) < 20)) // 20% chance of flinging stuff around { if (!cBlockInfo::FullyOccupiesVoxel(Block)) { break; } - else if ((m_World->GetTNTShrapnelLevel() == 1) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) + else if ((m_World->GetTNTShrapnelLevel() == slGravityAffectedOnly) && ((Block != E_BLOCK_SAND) && (Block != E_BLOCK_GRAVEL))) { break; } -- cgit v1.2.3