summaryrefslogblamecommitdiffstats
path: root/source/Pawn.cpp
blob: ae8133420c2a8ac7afd3388aadda4fc17caeec26 (plain) (tree)
1
2
3
4
5
6
7
8
9


                                                                                              





                          

                     

                    

















                                         

                         























                                
                                                            



                                      
                                                                                                         
 








                                                    

                                      



                             
 
                                                                  


                          
                                         






         
                                        







                                                                                                              
                                                                  





 
                                                
 
                                                                                  









                                                                                             
                                                   







                            
                                                                                            















                                                      
                                          

















































































                                                                                                

#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "Pawn.h"
#include "Root.h"
#include "Server.h"
#include "World.h"
#include "Player.h"
#include "PluginManager.h"
#include "Vector3d.h"
#include "BlockID.h"
#include "Defines.h"





CLASS_DEFINITION( cPawn, cEntity )





cPawn::cPawn()
	: cEntity( 0, 0, 0 )
	, m_LastPosX( 0.0 )
	, m_LastPosY( 0.0 )
	, m_LastPosZ( 0.0 )
	, m_TimeLastTeleportPacket( 0.f )
	, m_bBurnable(true)
	, m_MetaData(NORMAL)
{
	SetMaxHealth(20);
}





cPawn::~cPawn()
{

}





void cPawn::Heal( int a_Health )
{
	(void)a_Health;
}





void cPawn::TakeDamage(int a_Damage, cEntity * a_Instigator)
{
	TakeDamageInfo TDI;
	TDI.Damage = a_Damage;
	TDI.Instigator = a_Instigator;
	cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_TAKE_DAMAGE, 2, this, &TDI);

	if (TDI.Damage == 0)
	{
		return;
	}
	if (m_Health <= 0)
	{
		// Can't take damage if already dead
		return;
	}

	m_Health -= (short)TDI.Damage;
	if (m_Health < 0)
	{
		m_Health = 0;
	}

	m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_HURT);

	if (m_Health <= 0)
	{
		KilledBy(TDI.Instigator);
	}
}





void cPawn::KilledBy(cEntity * a_Killer)
{
	m_Health = 0;

	if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer ) )
	{
		return; // Give plugins a chance to 'unkill' the pawn.
	}

	m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_DEAD);
}





void cPawn::TeleportToEntity(cEntity * a_Entity)
{
	TeleportTo(a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ());
}





void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ )
{
	SetPosition( a_PosX, a_PosY, a_PosZ );

	GetWorld()->BroadcastTeleportEntity(*this);
}





void cPawn::Tick(float a_Dt)
{
	CheckMetaDataBurn();  // Check to see if pawn should burn based on block they are on
	
	if (GetMetaData() == BURNING)
	{
		InStateBurning(a_Dt);
	}
}






void cPawn::SetMetaData(MetaData a_MetaData)
{
	//Broadcast new status to clients in the chunk
	m_MetaData = a_MetaData;
	m_World->BroadcastMetadata(*this);
}





//----Change Entity MetaData
void cPawn::CheckMetaDataBurn()
{
	char Block = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y, (int) m_Pos.z);
	char BlockAbove = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y + 1, (int) m_Pos.z);
	char BlockBelow = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y - 1, (int) m_Pos.z);
	
	if (
		(GetMetaData() == BURNING) &&
		(IsBlockWater(Block) || IsBlockWater(BlockAbove) || IsBlockWater(BlockBelow))
	)
	{
		SetMetaData(NORMAL);
 	}
 	else if (
 		m_bBurnable && 
 		(GetMetaData() != BURNING) &&
		(
			IsBlockLava(Block) || (Block == E_BLOCK_FIRE) ||
			IsBlockLava(BlockAbove) || (BlockAbove == E_BLOCK_FIRE) ||
			IsBlockLava(BlockBelow) || (BlockBelow == E_BLOCK_FIRE)
		)
	)
	{
		SetMetaData(BURNING);  
	}
}





//What to do if On fire
void cPawn::InStateBurning(float a_Dt)
{
	m_FireDamageInterval += a_Dt;
	char Block = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z );
	char BlockAbove = GetWorld()->GetBlock( (int)m_Pos.x, (int)m_Pos.y + 1, (int)m_Pos.z );	
	if (m_FireDamageInterval > 800)
	{

		m_FireDamageInterval = 0;
		TakeDamage(1, this);

		m_BurnPeriod++;
		if (IsBlockLava(Block) || Block == E_BLOCK_FIRE
			|| IsBlockLava(BlockAbove) || BlockAbove == E_BLOCK_FIRE)
		{
			m_BurnPeriod = 0;
			TakeDamage(6, this);
		}
		else
		{
			TakeDamage(1, this);
		}
		
		if (m_BurnPeriod > 7)
		{
			SetMetaData(NORMAL);
			m_BurnPeriod = 0;
		}
	}
}





void cPawn::SetMaxHealth(short a_MaxHealth)
{
	this->m_MaxHealth = a_MaxHealth;

	//Reset health
	m_Health = a_MaxHealth;
}