Initial implementation of explosions and TNT block
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1392 0a769ca7-a7f5-676a-18bf-c427514a06d6master
parent
a4be800a91
commit
b75fc5f4e8
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -36,3 +36,6 @@ public: // tolua_export
|
|||
|
||||
int x, y, z; // tolua_export
|
||||
}; // tolua_export
|
||||
|
||||
|
||||
typedef std::list< Vector3i * > cVector3iList;
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue