1
0

Merge branch 'master' into threadsafequeue

This commit is contained in:
Tycho Bickerstaff 2013-12-31 15:53:17 +00:00
commit 18fb814c34
22 changed files with 70 additions and 95 deletions

View File

@ -19,5 +19,6 @@ SamJBarney
worktycho worktycho
Sxw1212 Sxw1212
tonibm19 tonibm19
Diusrex
Please add yourself to this list if you contribute to MCServer. Please add yourself to this list if you contribute to MCServer.

View File

@ -494,10 +494,6 @@
RelativePath="..\src\Chunk.h" RelativePath="..\src\Chunk.h"
> >
</File> </File>
<File
RelativePath="..\src\Chunk.inl.h"
>
</File>
<File <File
RelativePath="..\src\ChunkDef.h" RelativePath="..\src\ChunkDef.h"
> >

View File

@ -28,6 +28,8 @@ template<typename Combinator> void InternalMergeBlocks(
Combinator a_Combinator Combinator a_Combinator
) )
{ {
UNUSED(a_SrcSizeY);
UNUSED(a_DstSizeY);
for (int y = 0; y < a_SizeY; y++) for (int y = 0; y < a_SizeY; y++)
{ {
int SrcBaseY = (y + a_SrcOffY) * a_SrcSizeX * a_SrcSizeZ; int SrcBaseY = (y + a_SrcOffY) * a_SrcSizeX * a_SrcSizeZ;

View File

@ -87,10 +87,9 @@ public:
virtual void SendTo(cClientHandle & a_Client) = 0; virtual void SendTo(cClientHandle & a_Client) = 0;
/// Ticks the entity; returns true if the chunk should be marked as dirty as a result of this ticking. By default does nothing. /// Ticks the entity; returns true if the chunk should be marked as dirty as a result of this ticking. By default does nothing.
virtual bool Tick(float a_Dt, cChunk & a_Chunk) virtual bool Tick(float a_Dt, cChunk & /* a_Chunk */)
{ {
UNUSED(a_Dt); UNUSED(a_Dt);
UNUSED(a_Chunk);
return false; return false;
} }

View File

@ -36,7 +36,14 @@ public:
/** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded /** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded
When this callback returns true, the tracing is aborted. When this callback returns true, the tracing is aborted.
*/ */
virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ, char a_EntryFace) { return false; } virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ, char a_EntryFace)
{
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_EntryFace);
return false;
}
/** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height)
The coords specify the exact point at which the path exited the world. The coords specify the exact point at which the path exited the world.
@ -44,7 +51,13 @@ public:
Note that some paths can go out of the world and come back again (parabola), Note that some paths can go out of the world and come back again (parabola),
in such a case this callback is followed by OnIntoWorld() and further OnNextBlock() calls in such a case this callback is followed by OnIntoWorld() and further OnNextBlock() calls
*/ */
virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) { return false; } virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ)
{
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
return false;
}
/** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height)
The coords specify the exact point at which the path entered the world. The coords specify the exact point at which the path entered the world.
@ -52,7 +65,13 @@ public:
Note that some paths can go out of the world and come back again (parabola), Note that some paths can go out of the world and come back again (parabola),
in such a case this callback is followed by further OnNextBlock() calls in such a case this callback is followed by further OnNextBlock() calls
*/ */
virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) { return false; } virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ)
{
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
return false;
}
/** Called when the path is sure not to hit any more blocks. /** Called when the path is sure not to hit any more blocks.
Note that for some shapes this might never happen (line with constant Y) Note that for some shapes this might never happen (line with constant Y)

View File

@ -773,7 +773,7 @@ void cByteBuffer::ReadAll(AString & a_Data)
bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, int a_NumBytes) bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes)
{ {
if (!a_Dst.CanWriteBytes(a_NumBytes) || !CanReadBytes(a_NumBytes)) if (!a_Dst.CanWriteBytes(a_NumBytes) || !CanReadBytes(a_NumBytes))
{ {
@ -781,9 +781,10 @@ bool cByteBuffer::ReadToByteBuffer(cByteBuffer & a_Dst, int a_NumBytes)
return false; return false;
} }
char buf[1024]; char buf[1024];
while (a_NumBytes > 0) // > 0 without generating warnings about unsigned comparisons where size_t is unsigned
while (a_NumBytes != 0)
{ {
int num = (a_NumBytes > sizeof(buf)) ? sizeof(buf) : a_NumBytes; size_t num = (a_NumBytes > sizeof(buf)) ? sizeof(buf) : a_NumBytes;
VERIFY(ReadBuf(buf, num)); VERIFY(ReadBuf(buf, num));
VERIFY(a_Dst.Write(buf, num)); VERIFY(a_Dst.Write(buf, num));
a_NumBytes -= num; a_NumBytes -= num;

View File

@ -110,7 +110,7 @@ public:
void ReadAll(AString & a_Data); void ReadAll(AString & a_Data);
/// Reads the specified number of bytes and writes it into the destinatio bytebuffer. Returns true on success. /// Reads the specified number of bytes and writes it into the destinatio bytebuffer. Returns true on success.
bool ReadToByteBuffer(cByteBuffer & a_Dst, int a_NumBytes); bool ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes);
/// Removes the bytes that have been read from the ringbuffer /// Removes the bytes that have been read from the ringbuffer
void CommitRead(void); void CommitRead(void);

View File

@ -527,9 +527,10 @@ void cChunk::SpawnMobs(cMobSpawner& a_MobSpawner)
// MG TODO : check that "Level" really means Y // MG TODO : check that "Level" really means Y
/*NIBBLETYPE SkyLight = 0; /*
NIBBLETYPE SkyLight = 0;
NIBBLETYPE BlockLight = 0;*/ NIBBLETYPE BlockLight = 0;
*/
if (IsLightValid()) if (IsLightValid())
{ {
@ -2323,8 +2324,9 @@ BLOCKTYPE cChunk::GetBlock(int a_BlockIdx) const
void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta)
{ {
a_BlockType = cChunkDef::GetBlock (m_BlockTypes, a_RelX, a_RelY, a_RelZ); int Idx = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); a_BlockType = cChunkDef::GetBlock (m_BlockTypes, Idx);
a_BlockMeta = cChunkDef::GetNibble(m_BlockMeta, Idx);
} }
@ -2896,11 +2898,3 @@ NIBBLETYPE cChunk::GetTimeAlteredLight(NIBBLETYPE a_Skylight) const
#if !C_CHUNK_USE_INLINE
# include "cChunk.inl.h"
#endif

View File

@ -12,19 +12,6 @@
#define C_CHUNK_USE_INLINE 1
// Do not touch
#if C_CHUNK_USE_INLINE
#define __C_CHUNK_INLINE__ inline
#else
#define __C_CHUNK_INLINE__
#endif
namespace Json namespace Json
{ {
class Value; class Value;
@ -436,8 +423,6 @@ private:
void RemoveBlockEntity(cBlockEntity * a_BlockEntity); void RemoveBlockEntity(cBlockEntity * a_BlockEntity);
void AddBlockEntity (cBlockEntity * a_BlockEntity); void AddBlockEntity (cBlockEntity * a_BlockEntity);
void SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff);
/// Creates a block entity for each block that needs a block entity and doesn't have one in the list /// Creates a block entity for each block that needs a block entity and doesn't have one in the list
void CreateBlockEntities(void); void CreateBlockEntities(void);
@ -482,11 +467,3 @@ typedef std::list<cChunkPtr> cChunkPtrList;
#if C_CHUNK_USE_INLINE
#include "Chunk.inl.h"
#endif

View File

@ -1,34 +0,0 @@
#ifndef __C_CHUNK_INL_H__
#define __C_CHUNK_INL_H__
#ifndef MAX
# define MAX(a,b) (((a)>(b))?(a):(b))
#endif
__C_CHUNK_INLINE__
void cChunk::SpreadLightOfBlock(NIBBLETYPE * a_LightBuffer, int a_X, int a_Y, int a_Z, char a_Falloff)
{
unsigned char CurrentLight = cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z );
cChunkDef::SetNibble( a_LightBuffer, a_X-1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X-1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
cChunkDef::SetNibble( a_LightBuffer, a_X+1, a_Y, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X+1, a_Y, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y-1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y-1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y+1, a_Z, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y+1, a_Z ), MAX(0,CurrentLight-a_Falloff) ) );
cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z-1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z-1 ), MAX(0,CurrentLight-a_Falloff) ) );
cChunkDef::SetNibble( a_LightBuffer, a_X, a_Y, a_Z+1, MAX(cChunkDef::GetNibble( a_LightBuffer, a_X, a_Y, a_Z+1 ), MAX(0,CurrentLight-a_Falloff) ) );
MarkDirty();
}
#endif

View File

@ -179,7 +179,7 @@ public:
/// Converts absolute block coords into relative (chunk + block) coords: /// Converts absolute block coords into relative (chunk + block) coords:
inline static void AbsoluteToRelative(/* in-out */ int & a_X, int& a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ )
{ {
UNUSED(a_Y); UNUSED(a_Y);
BlockToChunk(a_X, a_Z, a_ChunkX, a_ChunkZ); BlockToChunk(a_X, a_Z, a_ChunkX, a_ChunkZ);

View File

@ -1409,6 +1409,7 @@ void cClientHandle::SendData(const char * a_Data, int a_Size)
void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket) void cClientHandle::MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket)
{ {
UNUSED(a_World);
ASSERT(m_Player != NULL); ASSERT(m_Player != NULL);
if (a_SendRespawnPacket) if (a_SendRespawnPacket)

View File

@ -424,11 +424,13 @@ protected:
void Dereference( cEntity*& a_EntityPtr ); void Dereference( cEntity*& a_EntityPtr );
private: private:
// Measured in degrees (MAX 360 degrees) // Measured in degrees, [-180, +180)
double m_HeadYaw; double m_HeadYaw;
// Measured in meter/second (m/s) // Measured in meter/second (m/s)
Vector3d m_Speed; Vector3d m_Speed;
// Measured in degrees (MAX 360 degrees)
// Measured in degrees, [-180, +180)
Vector3d m_Rot; Vector3d m_Rot;
/// Position of the entity's XZ center and Y bottom /// Position of the entity's XZ center and Y bottom

View File

@ -908,8 +908,8 @@ bool cPlayer::IsGameModeSurvival(void) const
bool cPlayer::IsGameModeAdventure(void) const bool cPlayer::IsGameModeAdventure(void) const
{ {
return (m_GameMode == gmCreative) || // Either the player is explicitly in Adventure return (m_GameMode == gmAdventure) || // Either the player is explicitly in Adventure
((m_GameMode == gmNotSet) && m_World->IsGameModeCreative()); // or they inherit from the world and the world is Adventure ((m_GameMode == gmNotSet) && m_World->IsGameModeAdventure()); // or they inherit from the world and the world is Adventure
} }

View File

@ -57,6 +57,8 @@ int cInventory::HowManyCanFit(const cItem & a_ItemStack, bool a_ConsiderEmptySlo
int cInventory::HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int a_EndSlotNum, bool a_ConsiderEmptySlots) int cInventory::HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int a_EndSlotNum, bool a_ConsiderEmptySlots)
{ {
UNUSED(a_ConsiderEmptySlots);
if ((a_BeginSlotNum < 0) || (a_BeginSlotNum >= invNumSlots)) if ((a_BeginSlotNum < 0) || (a_BeginSlotNum >= invNumSlots))
{ {
LOGWARNING("%s: Bad BeginSlotNum, got %d, there are %d slots; correcting to 0.", __FUNCTION__, a_BeginSlotNum, invNumSlots - 1); LOGWARNING("%s: Bad BeginSlotNum, got %d, there are %d slots; correcting to 0.", __FUNCTION__, a_BeginSlotNum, invNumSlots - 1);
@ -96,8 +98,6 @@ int cInventory::HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int
int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks, bool a_tryToFillEquippedFirst) int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks, bool a_tryToFillEquippedFirst)
{ {
cItem ToAdd(a_Item); cItem ToAdd(a_Item);

View File

@ -189,7 +189,7 @@ void cLightingThread::ChunkReady(int a_ChunkX, int a_ChunkZ)
{ {
if ( if (
(itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) && (itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) &&
(itr->x - a_ChunkX >= -1) && (itr->x - a_ChunkX <= 1) (itr->z - a_ChunkZ >= -1) && (itr->z - a_ChunkZ <= 1)
) )
{ {
// It is a neighbor // It is a neighbor
@ -495,6 +495,7 @@ void cLightingThread::CalcLightStep(
int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut int & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut
) )
{ {
UNUSED(a_IsSeedIn);
int NumSeedsOut = 0; int NumSeedsOut = 0;
for (int i = 0; i < a_NumSeedsIn; i++) for (int i = 0; i < a_NumSeedsIn; i++)
{ {

View File

@ -196,7 +196,6 @@ bool cLineBlockTracer::Item(cChunk * a_Chunk)
ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld() ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld()
// This is the actual line tracing loop. // This is the actual line tracing loop.
bool Finished = false;
while (true) while (true)
{ {
// Report the current block through the callbacks: // Report the current block through the callbacks:

View File

@ -173,6 +173,7 @@ void cServer::ClientMovedToWorld(const cClientHandle * a_Client)
void cServer::PlayerCreated(const cPlayer * a_Player) void cServer::PlayerCreated(const cPlayer * a_Player)
{ {
UNUSED(a_Player);
// To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread // To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread
cCSLock Lock(m_CSPlayerCountDiff); cCSLock Lock(m_CSPlayerCountDiff);
m_PlayerCountDiff += 1; m_PlayerCountDiff += 1;
@ -184,6 +185,7 @@ void cServer::PlayerCreated(const cPlayer * a_Player)
void cServer::PlayerDestroying(const cPlayer * a_Player) void cServer::PlayerDestroying(const cPlayer * a_Player)
{ {
UNUSED(a_Player);
// To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread // To avoid deadlocks, the player count is not handled directly, but rather posted onto the tick thread
cCSLock Lock(m_CSPlayerCountDiff); cCSLock Lock(m_CSPlayerCountDiff);
m_PlayerCountDiff -= 1; m_PlayerCountDiff -= 1;
@ -514,6 +516,7 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac
void cServer::PrintHelp(const AStringVector & a_Split, cCommandOutputCallback & a_Output) void cServer::PrintHelp(const AStringVector & a_Split, cCommandOutputCallback & a_Output)
{ {
UNUSED(a_Split);
typedef std::pair<AString, AString> AStringPair; typedef std::pair<AString, AString> AStringPair;
typedef std::vector<AStringPair> AStringPairs; typedef std::vector<AStringPair> AStringPairs;
@ -525,6 +528,8 @@ void cServer::PrintHelp(const AStringVector & a_Split, cCommandOutputCallback &
virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) override virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) override
{ {
UNUSED(a_Plugin);
UNUSED(a_Permission);
if (!a_HelpString.empty()) if (!a_HelpString.empty())
{ {
m_Commands.push_back(AStringPair(a_Command, a_HelpString)); m_Commands.push_back(AStringPair(a_Command, a_HelpString));

View File

@ -27,8 +27,14 @@ public:
} }
// cSimulator overrides: // cSimulator overrides:
virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override {} virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override
virtual void Simulate(float a_Dt) override {} {
UNUSED(a_BlockX);
UNUSED(a_BlockY);
UNUSED(a_BlockZ);
UNUSED(a_Chunk);
}
virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);}
} ; } ;

View File

@ -305,6 +305,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque
void cWebAdmin::HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) void cWebAdmin::HandleRootRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request)
{ {
UNUSED(a_Request);
static const char LoginForm[] = \ static const char LoginForm[] = \
"<h1>MCServer WebAdmin</h1>" \ "<h1>MCServer WebAdmin</h1>" \
"<center>" \ "<center>" \
@ -450,6 +451,7 @@ AString cWebAdmin::GetBaseURL(const AStringVector & a_URLSplit)
void cWebAdmin::OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) void cWebAdmin::OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request)
{ {
UNUSED(a_Connection);
const AString & URL = a_Request.GetURL(); const AString & URL = a_Request.GetURL();
if ( if (
(strncmp(URL.c_str(), "/webadmin", 9) == 0) || (strncmp(URL.c_str(), "/webadmin", 9) == 0) ||
@ -473,6 +475,7 @@ void cWebAdmin::OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_
void cWebAdmin::OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size) void cWebAdmin::OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, int a_Size)
{ {
UNUSED(a_Connection);
cRequestData * Data = (cRequestData *)(a_Request.GetUserData()); cRequestData * Data = (cRequestData *)(a_Request.GetUserData());
if (Data == NULL) if (Data == NULL)
{ {

View File

@ -723,6 +723,7 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
void cWorld::TickWeather(float a_Dt) void cWorld::TickWeather(float a_Dt)
{ {
UNUSED(a_Dt);
// There are no weather changes anywhere but in the Overworld: // There are no weather changes anywhere but in the Overworld:
if (GetDimension() != dimOverworld) if (GetDimension() != dimOverworld)
{ {
@ -794,7 +795,7 @@ void cWorld::TickMobs(float a_Dt)
cMonster::mfAmbient, cMonster::mfAmbient,
cMonster::mfWater, cMonster::mfWater,
} ; } ;
for (int i = 0; i < ARRAYCOUNT(AllFamilies); i++) for (size_t i = 0; i < ARRAYCOUNT(AllFamilies); i++)
{ {
cMonster::eFamily Family = AllFamilies[i]; cMonster::eFamily Family = AllFamilies[i];
int SpawnDelay = cMonster::GetSpawnDelay(Family); int SpawnDelay = cMonster::GetSpawnDelay(Family);
@ -1643,6 +1644,7 @@ int cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward)
void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff) void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff)
{ {
UNUSED(a_InitialVelocityCoeff);
cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTimeInSec); cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTimeInSec);
TNT->Initialize(this); TNT->Initialize(this);
// TODO: Add a bit of speed in horiz and vert axes, based on the a_InitialVelocityCoeff // TODO: Add a bit of speed in horiz and vert axes, based on the a_InitialVelocityCoeff

View File

@ -78,6 +78,7 @@ public:
class cTask class cTask
{ {
public: public:
virtual ~cTask(){};
virtual void Run(cWorld & a_World) = 0; virtual void Run(cWorld & a_World) = 0;
} ; } ;