Initial implementation of explosions and TNT block

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1392 0a769ca7-a7f5-676a-18bf-c427514a06d6
master
keyboard.osh@gmail.com 2013-04-18 02:42:45 +00:00
parent a4be800a91
commit b75fc5f4e8
17 changed files with 266 additions and 2 deletions

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 04/13/13 22:59:55.
** Generated automatically by tolua++-1.0.92 on 04/17/13 19:40:39.
*/
#ifndef __cplusplus
@ -24409,6 +24409,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S)
tolua_constant(tolua_S,"etMob",cEntity::etMob);
tolua_constant(tolua_S,"etFallingBlock",cEntity::etFallingBlock);
tolua_constant(tolua_S,"etMinecart",cEntity::etMinecart);
tolua_constant(tolua_S,"etTNT",cEntity::etTNT);
tolua_constant(tolua_S,"eEntityType_Entity",cEntity::eEntityType_Entity);
tolua_constant(tolua_S,"eEntityType_Player",cEntity::eEntityType_Player);
tolua_constant(tolua_S,"eEntityType_Pickup",cEntity::eEntityType_Pickup);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 04/13/13 22:59:55.
** Generated automatically by tolua++-1.0.92 on 04/17/13 19:40:39.
*/
/* Exported function */

View File

@ -56,6 +56,7 @@
#include "BlockCauldron.h"
#include "BlockBrewingStand.h"
#include "BlockCobWeb.h"
#include "BlockTNT.h"
@ -171,6 +172,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType)
case E_BLOCK_STONE_SLAB: return new cBlockSlabHandler (a_BlockType);
case E_BLOCK_SUGARCANE: return new cBlockSugarcaneHandler (a_BlockType);
case E_BLOCK_TALL_GRASS: return new cBlockTallGrassHandler (a_BlockType);
case E_BLOCK_TNT: return new cBlockTNTHandler (a_BlockType);
case E_BLOCK_TORCH: return new cBlockTorchHandler (a_BlockType);
case E_BLOCK_VINES: return new cBlockVineHandler (a_BlockType);
case E_BLOCK_WALLSIGN: return new cBlockSignHandler (a_BlockType);

38
source/Blocks/BlockTNT.h Normal file
View File

@ -0,0 +1,38 @@
#pragma once
#include "BlockHandler.h"
#include "../Player.h"
#include "../TNTEntity.h"
class cBlockTNTHandler : public cBlockHandler
{
public:
cBlockTNTHandler(BLOCKTYPE a_BlockType)
: cBlockHandler(a_BlockType)
{
}
virtual void OnUse(cWorld * a_World, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override
{
if (a_Player->GetEquippedWeapon().m_ItemType == E_ITEM_FLINT_AND_STEEL)
{
a_World->BroadcastSoundEffect("random.fuse", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 0.5f, 0.6f);
cTNTEntity *TNT = new cTNTEntity(a_BlockX,a_BlockY,a_BlockZ,4); //4 seconds to boom
TNT->Initialize(a_World);
a_World->SetBlock(a_BlockX,a_BlockY,a_BlockZ, E_BLOCK_AIR, 0);
}
}
virtual bool IsUseable() override
{
return true;
}
};

View File

@ -1552,6 +1552,15 @@ void cClientHandle::SendEntityStatus(const cEntity & a_Entity, char a_Status)
void cClientHandle::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, cVector3iList a_BlocksAffected, float a_PlayerMotionX, float a_PlayerMotionY, float a_PlayerMotionZ)
{
m_Protocol->SendExplosion(a_BlockX,a_BlockY,a_BlockZ,a_Radius, a_BlocksAffected, a_PlayerMotionX, a_PlayerMotionY,a_PlayerMotionZ);
}
void cClientHandle::SendMetadata(const cPawn & a_Pawn)
{
m_Protocol->SendMetadata(a_Pawn);

View File

@ -98,6 +98,7 @@ public:
void SendEntRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item);
void SendEntityStatus (const cEntity & a_Entity, char a_Status);
void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, cVector3iList a_BlocksAffected, float a_PlayerMotionX, float a_PlayerMotionY, float a_PlayerMotionZ);
void SendGameMode (eGameMode a_GameMode);
void SendHealth (void);
void SendInventoryProgress (char a_WindowID, short a_Progressbar, short a_Value);

View File

@ -67,6 +67,7 @@ public:
etMob = etMonster, // DEPRECATED, use etMonster instead!
etFallingBlock,
etMinecart,
etTNT,
// DEPRECATED older constants, left over for compatibility reasons (plugins)
eEntityType_Entity = etEntity,

View File

@ -67,6 +67,7 @@ public:
virtual void SendEntRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) = 0;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) = 0;
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) = 0;
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, cVector3iList a_BlocksAffected, float a_PlayerMotionX, float a_PlayerMotionY, float a_PlayerMotionZ) = 0;
virtual void SendGameMode (eGameMode a_GameMode) = 0;
virtual void SendHealth (void) = 0;
virtual void SendInventoryProgress (char a_WindowID, short a_Progressbar, short a_Value) = 0;

View File

@ -352,6 +352,34 @@ void cProtocol125::SendEntityStatus(const cEntity & a_Entity, char a_Status)
void cProtocol125::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, cVector3iList a_BlocksAffected, float a_PlayerMotionX, float a_PlayerMotionY, float a_PlayerMotionZ)
{
cCSLock Lock(m_CSPacket);
WriteByte(PACKET_EXPLOSION);
WriteDouble (a_BlockX);
WriteDouble (a_BlockY);
WriteDouble (a_BlockZ);
WriteFloat (a_Radius);
WriteInt (a_BlocksAffected.size());//it should be a_RecordCount
/*WriteByte (0); //It should be the record
WriteByte (0);
WriteByte (0);*/
for (cVector3iList::iterator itr = a_BlocksAffected.begin(); itr != a_BlocksAffected.end(); ++itr)
{
WriteByte ((Byte)((*itr)->x - a_BlockX));
WriteByte ((Byte)((*itr)->y - a_BlockY));
WriteByte ((Byte)((*itr)->z - a_BlockZ));
}
WriteFloat (a_PlayerMotionX);
WriteFloat (a_PlayerMotionY);
WriteFloat (a_PlayerMotionZ);
Flush();
}
void cProtocol125::SendEntRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
{
ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self

View File

@ -44,6 +44,7 @@ public:
virtual void SendEntRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, cVector3iList a_BlocksAffected, float a_PlayerMotionX, float a_PlayerMotionY, float a_PlayerMotionZ) override;
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHealth (void) override;
virtual void SendInventoryProgress (char a_WindowID, short a_Progressbar, short a_Value) override;

View File

@ -266,6 +266,16 @@ void cProtocolRecognizer::SendEntityStatus(const cEntity & a_Entity, char a_Stat
void cProtocolRecognizer::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, cVector3iList a_BlocksAffected, float a_PlayerMotionX, float a_PlayerMotionY, float a_PlayerMotionZ)
{
ASSERT(m_Protocol != NULL);
m_Protocol->SendExplosion(a_BlockX,a_BlockY,a_BlockZ,a_Radius, a_BlocksAffected, a_PlayerMotionX, a_PlayerMotionY,a_PlayerMotionZ);
}
void cProtocolRecognizer::SendGameMode(eGameMode a_GameMode)
{
ASSERT(m_Protocol != NULL);

View File

@ -71,6 +71,7 @@ public:
virtual void SendEntRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, cVector3iList a_BlocksAffected, float a_PlayerMotionX, float a_PlayerMotionY, float a_PlayerMotionZ) override;
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHealth (void) override;
virtual void SendInventoryProgress (char a_WindowID, short a_Progressbar, short a_Value) override;

70
source/TNTEntity.cpp Normal file
View File

@ -0,0 +1,70 @@
#include "Globals.h"
#include "TNTEntity.h"
#include "World.h"
#include "ClientHandle.h"
cTNTEntity::cTNTEntity(int a_X,int a_Y,int a_Z,float a_MaxFuseTime) :
super(etTNT, a_X + 0.5f, a_Y + 0.5f, a_Z + 0.5f)
{
m_MaxFuseTime = a_MaxFuseTime;
m_Counter = 0;
}
cTNTEntity::cTNTEntity(const Vector3i a_Pos,float a_MaxFuseTime) :
super(etTNT, a_Pos.x,a_Pos.y,a_Pos.z)
{
m_MaxFuseTime = a_MaxFuseTime;
m_Counter = 0;
}
void cTNTEntity::Initialize(cWorld * a_World)
{
super::Initialize(a_World);
a_World->BroadcastSpawn(*this);
}
void cTNTEntity::SpawnOn(cClientHandle & a_ClientHandle)
{
a_ClientHandle.SendSpawnObject(*this,50,1,0,0); //50 means TNT
m_bDirtyPosition = false;
m_bDirtySpeed = false;
m_bDirtyOrientation = false;
m_bDirtyHead = false;
}
void cTNTEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
float delta_time = a_Dt / 1000; //Convert miliseconds to seconds
m_Counter += delta_time;
if (m_Counter > m_MaxFuseTime) //Check if we go KABOOOM
{
Destroy();
LOGD("BOOM at {%f,%f,%f}",GetPosX(),GetPosY(),GetPosZ());
m_World->DoExplosiontAt(4.0,(int)floor(GetPosX()),(int)floor(GetPosY()),(int)floor(GetPosZ()));
return;
}
}

33
source/TNTEntity.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include "Entity.h"
#include "Defines.h"
class cTNTEntity :
public cEntity
{
typedef cEntity super;
public:
CLASS_PROTODEF(cTNTEntity);
cTNTEntity(int a_X,int a_Y,int a_Z,float a_MaxFuseTime);
cTNTEntity(const Vector3i a_Pos,float a_MaxFuseTime);
// cEntity overrides:
virtual void Initialize(cWorld * a_World) override;
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
private:
float m_Counter; //In seconds too
float m_MaxFuseTime; //in seconds
};

View File

@ -36,3 +36,6 @@ public: // tolua_export
int x, y, z; // tolua_export
}; // tolua_export
typedef std::list< Vector3i * > cVector3iList;

View File

@ -703,6 +703,68 @@ bool cWorld::ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback
void cWorld::DoExplosiontAt(float a_ExplosionSize, int a_BlockX, int a_BlockY, int a_BlockZ)
{
//TODO implement explosion using cBlockArea, add damage to pawns, add support for pickups, and implement block hardiness
Vector3d explosion_pos = Vector3d(a_BlockX,a_BlockY,a_BlockZ);
cVector3iList BlocksAffected;
for (int i=0;i<a_ExplosionSize;i++)
{
for (int j=0;j<a_ExplosionSize;j++)
{
for (int k=0;k<a_ExplosionSize;k++)
{
DigBlock(a_BlockX+i,a_BlockY+j,a_BlockZ+k);
DigBlock(a_BlockX+i,a_BlockY-j,a_BlockZ+k);
DigBlock(a_BlockX-i,a_BlockY-j,a_BlockZ-k);
DigBlock(a_BlockX-i,a_BlockY+j,a_BlockZ-k);
DigBlock(a_BlockX+i,a_BlockY+j,a_BlockZ-k);
DigBlock(a_BlockX+i,a_BlockY-j,a_BlockZ-k);
DigBlock(a_BlockX-i,a_BlockY+j,a_BlockZ+k);
DigBlock(a_BlockX-i,a_BlockY-j,a_BlockZ+k);
BlocksAffected.push_back(&Vector3i(a_BlockX+i,a_BlockY+j,a_BlockZ+k));
BlocksAffected.push_back(&Vector3i(a_BlockX+i,a_BlockY-j,a_BlockZ+k));
BlocksAffected.push_back(&Vector3i(a_BlockX-i,a_BlockY-j,a_BlockZ-k));
BlocksAffected.push_back(&Vector3i(a_BlockX-i,a_BlockY+j,a_BlockZ-k));
BlocksAffected.push_back(&Vector3i(a_BlockX+i,a_BlockY+j,a_BlockZ-k));
BlocksAffected.push_back(&Vector3i(a_BlockX+i,a_BlockY-j,a_BlockZ-k));
BlocksAffected.push_back(&Vector3i(a_BlockX-i,a_BlockY+j,a_BlockZ+k));
BlocksAffected.push_back(&Vector3i(a_BlockX-i,a_BlockY-j,a_BlockZ+k));
}
}
}
BroadcastSoundEffect("random.explode", a_BlockX * 8, a_BlockY * 8, a_BlockZ * 8, 1.0f, 0.6f);
{
cCSLock Lock(m_CSPlayers);
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
cClientHandle * ch = (*itr)->GetClientHandle();
if ((ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed())
{
continue;
}
Vector3d distance_explosion = (*itr)->GetPosition() - explosion_pos;
if (distance_explosion.SqrLength() < 4096.0)
{
double real_distance = sqrt( distance_explosion.SqrLength());
if (real_distance <= 0.0004)
real_distance = 0.0004;
double power = a_ExplosionSize / real_distance;
if (power <= 1)
power = 0;
distance_explosion.Normalize();
distance_explosion *= power;
ch->SendExplosion(a_BlockX,a_BlockY,a_BlockZ,a_ExplosionSize,BlocksAffected,(float)distance_explosion.x,(float)distance_explosion.y,(float)distance_explosion.z);
}
}
}
}
bool cWorld::DoWithChestAt(int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback)
{
return m_ChunkMap->DoWithChestAt(a_BlockX, a_BlockY, a_BlockZ, a_Callback);

View File

@ -338,6 +338,9 @@ public:
/// Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true
bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp
/// Does an explosion with the specified strength at the specified coordinate
void DoExplosiontAt (float a_ExplosionSzie, int a_BlockX, int a_BlockY, int a_BlockZ); //
/// Calls the callback for the chest at the specified coords; returns false if there's no chest at those coords, true if found
bool DoWithChestAt (int a_BlockX, int a_BlockY, int a_BlockZ, cChestCallback & a_Callback); // Exported in ManualBindings.cpp