1
0
Fork 0

Refactored the TakeDamage API to take equipped weapon and armor into consideration (PvP untested)

http://forum.mc-server.org/showthread.php?tid=625

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1087 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-12-21 11:04:08 +00:00
parent 231d6aed35
commit 912a1e7adc
62 changed files with 2532 additions and 1140 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 11/20/12 22:18:11.
** Generated automatically by tolua++-1.0.92 on 12/21/12 19:26:06.
*/
/* Exported function */

View File

@ -918,7 +918,7 @@ void cClientHandle::HandleUseEntity(int a_TargetEntityID, bool a_IsLeftClick)
if (!a_Entity->GetWorld()->IsPVPEnabled())
{
// PVP is disabled
if (a_Entity->IsA("cPlayer") && Instigator->IsA("cPlayer"))
if (a_Entity->IsA("cPlayer") && m_Attacker->IsA("cPlayer"))
{
// Player is hurting another player which is not allowed when PVP is disabled so ignore it
return true;
@ -926,17 +926,15 @@ void cClientHandle::HandleUseEntity(int a_TargetEntityID, bool a_IsLeftClick)
}
if (a_Entity->IsA("cPawn"))
{
reinterpret_cast<cPawn *>(a_Entity)->TakeDamage(Damage, Instigator);
reinterpret_cast<cPawn *>(a_Entity)->TakeDamage(*m_Attacker);
}
return true;
}
public:
int Damage;
cEntity * Instigator;
cPawn * m_Attacker;
} Callback;
Callback.Damage = 1; // TODO: Find proper damage from current item equipped
Callback.Instigator = m_Player;
Callback.m_Attacker = m_Player;
cWorld * World = m_Player->GetWorld();
World->DoWithEntityByID(a_TargetEntityID, Callback);

View File

@ -7,7 +7,7 @@
cBat::cBat()
cBat::cBat(void)
{
m_MobType = 65;
GetMonsterConfig("Bat");
@ -17,29 +17,12 @@ cBat::cBat()
cBat::~cBat()
bool cBat::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cBat") == 0) || super::IsA(a_EntityType));
}
bool cBat::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cBat" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cBat::KilledBy( cEntity* a_Killer )
{
cMonster::KilledBy( a_Killer );
}

View File

@ -1,14 +1,23 @@
#pragma once
#include "PassiveMonster.h"
class cBat : public cPassiveMonster
class cBat :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cBat();
~cBat();
cBat(void);
virtual bool IsA(const char * a_EntityType) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -7,7 +7,7 @@
cBlaze::cBlaze()
cBlaze::cBlaze(void)
{
m_MobType = 61;
GetMonsterConfig("Blaze");
@ -17,31 +17,18 @@ cBlaze::cBlaze()
cBlaze::~cBlaze()
bool cBlaze::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cBlaze") == 0) || super::IsA(a_EntityType));
}
bool cBlaze::IsA( const char* a_EntityType )
void cBlaze::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cBlaze" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cBlaze::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 1, E_ITEM_BLAZE_ROD);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_BLAZE_ROD);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "AggressiveMonster.h"
class cBlaze : public cAggressiveMonster
class cBlaze :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cBlaze();
~cBlaze();
cBlaze(void);
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -7,7 +7,7 @@
cCavespider::cCavespider()
cCavespider::cCavespider(void)
{
m_MobType = 59;
GetMonsterConfig("Cavespider");
@ -17,18 +17,9 @@ cCavespider::cCavespider()
cCavespider::~cCavespider()
bool cCavespider::IsA(const char * a_EntityType)
{
}
bool cCavespider::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cCavespider" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
return ((strcmp(a_EntityType, "cCaveSpider") == 0) || super::IsA(a_EntityType));
}
@ -37,7 +28,8 @@ bool cCavespider::IsA( const char* a_EntityType )
void cCavespider::Tick(float a_Dt)
{
cMonster::Tick(a_Dt);
super::Tick(a_Dt);
// TODO: Check vanilla if cavespiders really get passive during the day
m_EMPersonality = (GetWorld()->GetTimeOfDay() < (12000 + 1000)) ? PASSIVE : AGGRESSIVE;
}
@ -45,13 +37,10 @@ void cCavespider::Tick(float a_Dt)
void cCavespider::KilledBy( cEntity* a_Killer )
void cCavespider::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING);
AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_STRING);
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_SPIDER_EYE);
}

View File

@ -1,15 +1,26 @@
#pragma once
#include "AggressiveMonster.h"
class cCavespider : public cAggressiveMonster
class cCavespider :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cCavespider();
~cCavespider();
cCavespider(void);
virtual bool IsA(const char * a_EntityType) override;
virtual void Tick(float a_Dt) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void Tick(float a_Dt);
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -7,13 +7,13 @@
// TODO Drop egg every 5-10 minutes
// TODO: Drop egg every 5-10 minutes
cChicken::cChicken()
cChicken::cChicken(void)
{
m_MobType = 93;
GetMonsterConfig("Chicken");
@ -23,32 +23,19 @@ cChicken::cChicken()
cChicken::~cChicken()
bool cChicken::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cChicken") == 0) || super::IsA(a_EntityType));
}
bool cChicken::IsA( const char* a_EntityType )
void cChicken::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cChicken" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cChicken::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_FEATHER);
Drops.push_back(cItem((GetMetaData() == BURNING) ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1));
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_FEATHER);
a_Drops.push_back(cItem((GetMetaData() == BURNING) ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1));
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "PassiveMonster.h"
class cChicken : public cPassiveMonster
class cChicken :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cChicken();
~cChicken();
cChicken(void);
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -13,7 +13,7 @@
cCow::cCow()
cCow::cCow(void)
{
m_MobType = 92;
GetMonsterConfig("Cow");
@ -23,32 +23,19 @@ cCow::cCow()
cCow::~cCow()
bool cCow::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cCow") == 0) || super::IsA(a_EntityType));
}
bool cCow::IsA( const char* a_EntityType )
void cCow::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cCow" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cCow::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_LEATHER);
AddRandomDropItem(Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_LEATHER);
AddRandomDropItem(a_Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "PassiveMonster.h"
class cCow : public cPassiveMonster
class cCow :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cCow();
~cCow();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -7,7 +7,7 @@
cCreeper::cCreeper()
cCreeper::cCreeper(void)
{
m_MobType = 50;
GetMonsterConfig("Creeper");
@ -17,34 +17,20 @@ cCreeper::cCreeper()
cCreeper::~cCreeper()
bool cCreeper::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cCreeper") == 0) || super::IsA(a_EntityType));
}
bool cCreeper::IsA( const char* a_EntityType )
void cCreeper::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cCreeper" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cCreeper::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER);
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_GUNPOWDER);
// TODO Check if killed by a skeleton, then drop random music disk
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "AggressiveMonster.h"
class cCreeper : public cAggressiveMonster
class cCreeper :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cCreeper();
~cCreeper();
cCreeper(void);
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -7,7 +7,7 @@
cEnderman::cEnderman()
cEnderman::cEnderman(void)
{
m_MobType = 58;
GetMonsterConfig("Enderman");
@ -17,18 +17,9 @@ cEnderman::cEnderman()
cEnderman::~cEnderman()
bool cEnderman::IsA(const char * a_EntityType)
{
}
bool cEnderman::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cEnderman" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
return ((strcmp(a_EntityType, "cEnderman") == 0) || super::IsA(a_EntityType));
}
@ -50,13 +41,9 @@ void cEnderman::Tick(float a_Dt)
void cEnderman::KilledBy( cEntity* a_Killer )
void cEnderman::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
cItems Drops;
AddRandomDropItem(Drops, 0, 1, E_ITEM_ENDER_PEARL);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_ENDER_PEARL);
}

View File

@ -1,15 +1,26 @@
#pragma once
#include "PassiveAggressiveMonster.h"
class cEnderman : public cPassiveAggressiveMonster
class cEnderman :
public cPassiveAggressiveMonster
{
typedef cPassiveAggressiveMonster super;
public:
cEnderman();
~cEnderman();
cEnderman(void);
virtual bool IsA(const char * a_EntityType) override;
virtual void Tick(float a_Dt) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void Tick(float a_Dt);
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -7,7 +7,7 @@
cGhast::cGhast()
cGhast::cGhast(void)
{
m_MobType = 56;
GetMonsterConfig("Ghast");
@ -17,31 +17,19 @@ cGhast::cGhast()
cGhast::~cGhast()
bool cGhast::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cGhast") == 0) || super::IsA(a_EntityType));
}
bool cGhast::IsA( const char* a_EntityType )
void cGhast::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cGhast" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cGhast::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_GUNPOWDER);
AddRandomDropItem(Drops, 0, 1, E_ITEM_GHAST_TEAR);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_GUNPOWDER);
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_GHAST_TEAR);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "AggressiveMonster.h"
class cGhast : public cAggressiveMonster
class cGhast :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cGhast();
~cGhast();
cGhast(void);
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -17,31 +17,18 @@ cMagmacube::cMagmacube()
cMagmacube::~cMagmacube()
bool cMagmacube::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cMagmacube") == 0) || super::IsA(a_EntityType));
}
bool cMagmacube::IsA( const char* a_EntityType )
void cMagmacube::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cMagmacube" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cMagmacube::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 1, E_ITEM_MAGMA_CREAM);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_MAGMA_CREAM);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "AggressiveMonster.h"
class cMagmacube : public cAggressiveMonster
class cMagmacube :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cMagmacube();
~cMagmacube();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -28,8 +28,8 @@
cMonster::cMonster()
: m_Target(0)
cMonster::cMonster(void)
: m_Target(NULL)
, m_bMovingToDestination(false)
, m_DestinationTime( 0 )
, m_Gravity( -9.81f)
@ -318,20 +318,23 @@ void cMonster::HandlePhysics(float a_Dt)
void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
void cMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
{
cPawn::TakeDamage( a_Damage, a_Instigator );
m_Target = a_Instigator;
AddReference( m_Target );
super::DoTakeDamage(a_TDI);
if (a_TDI.Attacker != NULL)
{
m_Target = a_TDI.Attacker;
AddReference(m_Target);
}
}
void cMonster::KilledBy( cEntity* a_Killer )
void cMonster::KilledBy(cPawn * a_Killer)
{
cPawn::KilledBy( a_Killer );
super::KilledBy(a_Killer);
m_DestroyTimer = 0;
}
@ -513,7 +516,7 @@ void cMonster::Attack(float a_Dt)
{
// Setting this higher gives us more wiggle room for attackrate
m_AttackInterval = 0.0;
((cPawn *)m_Target)->TakeDamage((int)m_AttackDamage, this);
((cPawn *)m_Target)->TakeDamage(*this);
}
}

View File

@ -17,14 +17,18 @@ class cClientHandle;
class cMonster : public cPawn //tolua_export
{ //tolua_export
// tolua_begin
class cMonster :
public cPawn
{
typedef cPawn super;
public:
cMonster();
// tolua_end
cMonster(void);
virtual ~cMonster();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType);
virtual void SpawnOn(cClientHandle & a_ClientHandle) override;
@ -33,8 +37,9 @@ public:
virtual void HandlePhysics(float a_Dt);
virtual void ReplicateMovement(void);
virtual void TakeDamage(int a_Damage, cEntity * a_Instigator) override;
virtual void KilledBy(cEntity * a_Killer) override;
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
virtual void KilledBy(cPawn * a_Killer) override;
virtual void MoveToPosition(const Vector3f & a_Position);
virtual bool ReachedDestination(void);
@ -47,7 +52,7 @@ public:
virtual void CheckEventSeePlayer();
virtual void EventSeePlayer(cEntity *);
float m_SightDistance;
virtual cPlayer *FindClosestPlayer(); //non static is easier. also virtual so other mobs can implement their own searching algo
virtual cPlayer * FindClosestPlayer(); // non static is easier. also virtual so other mobs can implement their own searching algo
virtual void GetMonsterConfig(const char* pm_name);
virtual void EventLosePlayer();
virtual void CheckEventLostPlayer();
@ -69,7 +74,7 @@ public:
protected:
cEntity* m_Target;
cEntity * m_Target;
float m_AttackRate;
float idle_interval;
@ -94,7 +99,7 @@ protected:
float m_AttackInterval;
void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0);
}; //tolua_export
} ; // tolua_export

View File

@ -13,7 +13,7 @@
cMooshroom::cMooshroom()
cMooshroom::cMooshroom(void)
{
m_MobType = 96;
GetMonsterConfig("Mooshroom");
@ -23,32 +23,19 @@ cMooshroom::cMooshroom()
cMooshroom::~cMooshroom()
bool cMooshroom::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cMooshroom") == 0) || super::IsA(a_EntityType));
}
bool cMooshroom::IsA( const char* a_EntityType )
void cMooshroom::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cMooshroom" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cMooshroom::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_LEATHER);
AddRandomDropItem(Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_LEATHER);
AddRandomDropItem(a_Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "PassiveMonster.h"
class cMooshroom : public cPassiveMonster
class cMooshroom :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cMooshroom();
~cMooshroom();
cMooshroom(void);
virtual bool IsA(const char * a_EntityType);
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -17,29 +17,12 @@ cOcelot::cOcelot()
cOcelot::~cOcelot()
bool cOcelot::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cOcelot") == 0) || super::IsA(a_EntityType));
}
bool cOcelot::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cOcelot" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cOcelot::KilledBy( cEntity* a_Killer )
{
cMonster::KilledBy( a_Killer );
}

View File

@ -1,14 +1,23 @@
#pragma once
#include "PassiveMonster.h"
class cOcelot : public cPassiveMonster
class cOcelot :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cOcelot();
~cOcelot();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
} ;
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -9,30 +9,27 @@
cPassiveAggressiveMonster::cPassiveAggressiveMonster()
cPassiveAggressiveMonster::cPassiveAggressiveMonster(void)
{
m_EMPersonality = PASSIVE;
}
cPassiveAggressiveMonster::~cPassiveAggressiveMonster()
{
}
void cPassiveAggressiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
void cPassiveAggressiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
{
cMonster::TakeDamage(a_Damage, a_Instigator);
if(m_Target->GetEntityType() == cEntity::eEntityType_Player)
if ((m_Target != NULL) && (m_Target->GetEntityType() == cEntity::eEntityType_Player))
{
cPlayer * Player = (cPlayer *) m_Target;
if(Player->GetGameMode() != 1)
if (Player->GetGameMode() != 1)
{
m_EMState = CHASING;
}
}
}
void cPassiveAggressiveMonster::EventSeePlayer(cEntity *a_Entity)
{
return cMonster::EventSeePlayer(a_Entity);
}

View File

@ -1,13 +1,23 @@
#pragma once
#include "AggressiveMonster.h"
class cPassiveAggressiveMonster : public cAggressiveMonster
{
public:
cPassiveAggressiveMonster();
~cPassiveAggressiveMonster();
virtual void TakeDamage(int a_Damage, cEntity* a_Instigator);
void EventSeePlayer(cEntity *a_Entity);
};
class cPassiveAggressiveMonster :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cPassiveAggressiveMonster(void);
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
} ;

View File

@ -8,21 +8,27 @@
cPassiveMonster::cPassiveMonster()
cPassiveMonster::cPassiveMonster(void)
{
m_EMPersonality = PASSIVE;
}
cPassiveMonster::~cPassiveMonster()
void cPassiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
{
super::DoTakeDamage(a_TDI);
if ((a_TDI.Attacker != this) && (a_TDI.Attacker != NULL))
{
m_EMState = ESCAPING;
}
}
void cPassiveMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
{
cMonster::TakeDamage(a_Damage, a_Instigator);
if(a_Instigator != this)
m_EMState = ESCAPING;
}
void cPassiveMonster::Tick(float a_Dt)
{
@ -30,17 +36,22 @@ void cPassiveMonster::Tick(float a_Dt)
m_SeePlayerInterval += a_Dt;
if(m_SeePlayerInterval > 1)
if (m_SeePlayerInterval > 1) // Check every second
{
MTRand r1;
int rem = r1.randInt() % 3 + 1; //check most of the time but miss occasionally
int rem = r1.randInt() % 3 + 1; // Check most of the time but miss occasionally
m_SeePlayerInterval = 0.0;
if(rem >= 2) {
if(m_EMState == ESCAPING)
if (rem >= 2)
{
if (m_EMState == ESCAPING)
{
CheckEventLostPlayer();
}
}
}
}
}

View File

@ -1,14 +1,26 @@
#pragma once
#include "Monster.h"
class cPassiveMonster : public cMonster
class cPassiveMonster :
public cMonster
{
typedef cMonster super;
public:
cPassiveMonster();
~cPassiveMonster();
cPassiveMonster(void);
virtual void Tick(float a_Dt) override;
/// When hit by someone, run away
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
} ;
virtual void Tick(float a_Dt);
virtual void TakeDamage(int a_Damage, cEntity* a_Instigator);
};

View File

@ -7,7 +7,7 @@
cPig::cPig()
cPig::cPig(void)
{
m_MobType = 90;
GetMonsterConfig("Pig");
@ -17,33 +17,18 @@ cPig::cPig()
cPig::~cPig()
bool cPig::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cPig") == 0) || super::IsA(a_EntityType));
}
bool cPig::IsA( const char* a_EntityType )
void cPig::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cPig" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cPig::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_RAW_MEAT);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
// TODO: Check for burning state
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_COOKED_PORKCHOP : E_ITEM_RAW_MEAT);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "PassiveMonster.h"
class cPig : public cPassiveMonster
class cPig :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cPig();
~cPig();
cPig(void);
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -2,12 +2,7 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Sheep.h"
//Todo: Implement color
#include "../BlockID.h"
@ -15,7 +10,7 @@
cSheep::cSheep(void) :
m_IsSheared(false),
m_WoolColor(0) // TODO: E_META_WOOL_WHITE
m_WoolColor(E_META_WOOL_WHITE)
{
m_MobType = 91;
GetMonsterConfig("Sheep");
@ -25,41 +20,23 @@ cSheep::cSheep(void) :
cSheep::~cSheep()
bool cSheep::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cSheep") == 0) || super::IsA(a_EntityType));
}
bool cSheep::IsA( const char* a_EntityType )
void cSheep::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if (strcmp( a_EntityType, "cSheep" ) == 0)
{
return true;
}
return cMonster::IsA( a_EntityType );
}
void cSheep::KilledBy( cEntity* a_Killer )
{
// TODO: Check whether it is sheared
// TODO: Check color
if (!m_IsSheared)
{
cItems Drops;
Drops.push_back(cItem(E_ITEM_WHITE_CLOTH, 1, m_WoolColor));
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
a_Drops.push_back(cItem(E_ITEM_WHITE_CLOTH, 1, m_WoolColor));
}
cMonster::KilledBy( a_Killer );
}

View File

@ -1,17 +1,28 @@
#pragma once
#include "PassiveMonster.h"
class cSheep : public cPassiveMonster
class cSheep :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cSheep();
~cSheep();
cSheep(void);
bool m_IsSheared;
NIBBLETYPE m_WoolColor; // Uses E_META_WOOL_ constants for colors
virtual bool IsA(const char * a_EntityType);
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void KilledBy(cEntity * a_Killer);
};

View File

@ -8,5 +8,5 @@ public:
cSilverfish();
~cSilverfish();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType);
};

View File

@ -7,7 +7,7 @@
cSkeleton::cSkeleton()
cSkeleton::cSkeleton(void)
{
m_MobType = 51;
GetMonsterConfig("Skeleton");
@ -17,18 +17,9 @@ cSkeleton::cSkeleton()
cSkeleton::~cSkeleton()
{
}
bool cSkeleton::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cSkeleton" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
return ((strcmp(a_EntityType, "cSkeleton") == 0) || super::IsA(a_EntityType));
}
@ -51,14 +42,10 @@ void cSkeleton::Tick(float a_Dt)
void cSkeleton::KilledBy( cEntity* a_Killer )
void cSkeleton::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_ARROW);
AddRandomDropItem(Drops, 0, 2, E_ITEM_BONE);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_ARROW);
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_BONE);
}

View File

@ -1,16 +1,26 @@
#pragma once
#include "AggressiveMonster.h"
class cSkeleton : public cAggressiveMonster
class cSkeleton :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cSkeleton();
~cSkeleton();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
virtual void Tick(float a_Dt) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void Tick(float a_Dt);
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -3,13 +3,13 @@
#include "Slime.h"
//TODO Implement sized slimes
// TODO: Implement sized slimes
cSlime::cSlime()
cSlime::cSlime(void)
{
m_MobType = 55;
GetMonsterConfig("Slime");
@ -19,32 +19,19 @@ cSlime::cSlime()
cSlime::~cSlime()
bool cSlime::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cSlime") == 0) || super::IsA(a_EntityType));
}
bool cSlime::IsA( const char* a_EntityType )
void cSlime::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cSlime" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cSlime::KilledBy( cEntity* a_Killer )
{
//TODO: only when tiny
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_SLIMEBALL);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
// TODO: only when tiny
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_SLIMEBALL);
}

View File

@ -1,14 +1,21 @@
#pragma once
#include "AggressiveMonster.h"
class cSlime : public cAggressiveMonster
class cSlime :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cSlime();
~cSlime();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -17,32 +17,19 @@ cSpider::cSpider()
cSpider::~cSpider()
bool cSpider::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cSpider") == 0) || super::IsA(a_EntityType));
}
bool cSpider::IsA( const char* a_EntityType )
void cSpider::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cSpider" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cSpider::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_STRING);
AddRandomDropItem(Drops, 0, 1, E_ITEM_SPIDER_EYE);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_STRING);
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_SPIDER_EYE);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "AggressiveMonster.h"
class cSpider : public cAggressiveMonster
class cSpider :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cSpider();
~cSpider();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -12,32 +12,25 @@ cSquid::cSquid()
{
m_MobType = 94;
GetMonsterConfig("Squid");
m_NoWater = 0.f;
}
cSquid::~cSquid()
bool cSquid::IsA(const char * a_EntityType)
{
}
bool cSquid::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cSquid" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
return ((strcmp(a_EntityType, "cSquid") == 0) || super::IsA(a_EntityType));
}
void cSquid::KilledBy( cEntity* a_Killer )
void cSquid::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
// Drops 0-3 Ink Sacs
cItems Drops;
AddRandomDropItem(Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK);
}
@ -46,15 +39,17 @@ void cSquid::KilledBy( cEntity* a_Killer )
void cSquid::Tick(float a_Dt)
{
cPassiveMonster::Tick(a_Dt);
super::Tick(a_Dt);
Vector3d Pos = GetPosition();
//TODO Not a real behavior, but cool :D
if(!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && GetMetaData() != BURNING)
// TODO: Not a real behavior, but cool :D
if (!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && GetMetaData() != BURNING)
{
SetMetaData(BURNING);
}
}
}

View File

@ -1,18 +1,26 @@
#pragma once
#include "PassiveMonster.h"
class cSquid : public cPassiveMonster
class cSquid :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cSquid();
~cSquid();
virtual void Tick(float a_Dt);
virtual void Tick(float a_Dt) override;
virtual bool IsA(const char * a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual bool IsA( const char* a_EntityType );
virtual void KilledBy( cEntity* a_Killer );
protected:
float m_NoWater;
};

View File

@ -17,27 +17,9 @@ cVillager::cVillager()
cVillager::~cVillager()
bool cVillager::IsA(const char * a_EntityType)
{
}
bool cVillager::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cVillager" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cVillager::KilledBy( cEntity* a_Killer )
{
cMonster::KilledBy( a_Killer );
return ((strcmp(a_EntityType, "cVillager") == 0) || super::IsA(a_EntityType));
}

View File

@ -1,14 +1,23 @@
#pragma once
#include "PassiveMonster.h"
class cVillager : public cPassiveMonster
class cVillager :
public cPassiveMonster
{
typedef cPassiveMonster super;
public:
cVillager();
~cVillager();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
} ;
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -17,37 +17,24 @@ cWitch::cWitch()
cWitch::~cWitch()
bool cWitch::IsA(const char * a_EntityType)
{
return ((strcmp(a_EntityType, "cWitch") == 0) || super::IsA(a_EntityType));
}
bool cWitch::IsA( const char* a_EntityType )
void cWitch::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
if( strcmp( a_EntityType, "cWitch" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
}
void cWitch::KilledBy( cEntity* a_Killer )
{
cItems Drops;
AddRandomDropItem(Drops, 0, 6, E_ITEM_GLASS_BOTTLE);
AddRandomDropItem(Drops, 0, 6, E_ITEM_GLOWSTONE_DUST);
AddRandomDropItem(Drops, 0, 6, E_ITEM_GUNPOWDER);
AddRandomDropItem(Drops, 0, 6, E_ITEM_REDSTONE_DUST);
AddRandomDropItem(Drops, 0, 6, E_ITEM_SPIDER_EYE);
AddRandomDropItem(Drops, 0, 6, E_ITEM_STICK);
AddRandomDropItem(Drops, 0, 6, E_ITEM_SUGAR);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_GLASS_BOTTLE);
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_GLOWSTONE_DUST);
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_GUNPOWDER);
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_REDSTONE_DUST);
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_SPIDER_EYE);
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_STICK);
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_SUGAR);
}

View File

@ -1,14 +1,25 @@
#pragma once
#include "AggressiveMonster.h"
class cWitch : public cAggressiveMonster
class cWitch :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cWitch();
~cWitch();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char* a_EntityType) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -17,18 +17,9 @@ cZombie::cZombie()
cZombie::~cZombie()
bool cZombie::IsA(const char * a_EntityType)
{
}
bool cZombie::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cZombie" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
return ((strcmp(a_EntityType, "cZombie") == 0) || super::IsA(a_EntityType));
}
@ -37,7 +28,7 @@ bool cZombie::IsA( const char* a_EntityType )
void cZombie::Tick(float a_Dt)
{
cMonster::Tick(a_Dt);
super::Tick(a_Dt);
// TODO Same as in cSkeleton :D
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && (GetMetaData() != BURNING))
@ -50,16 +41,11 @@ void cZombie::Tick(float a_Dt)
void cZombie::KilledBy( cEntity* a_Killer )
void cZombie::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
cItems Drops;
AddRandomDropItem(Drops, 0, 2, E_ITEM_ROTTEN_FLESH);
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_ROTTEN_FLESH);
// TODO: Rare drops
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
}

View File

@ -2,14 +2,24 @@
#include "AggressiveMonster.h"
class cZombie : public cAggressiveMonster
class cZombie :
public cAggressiveMonster
{
typedef cAggressiveMonster super;
public:
cZombie();
~cZombie();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
virtual void Tick(float a_Dt) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
} ;
virtual void Tick(float a_Dt);
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -17,18 +17,9 @@ cZombiepigman::cZombiepigman()
cZombiepigman::~cZombiepigman()
bool cZombiepigman::IsA(const char * a_EntityType)
{
}
bool cZombiepigman::IsA( const char* a_EntityType )
{
if( strcmp( a_EntityType, "cZombiepigman" ) == 0 ) return true;
return cMonster::IsA( a_EntityType );
return ((strcmp(a_EntityType, "cZombiepigman") == 0) || super::IsA(a_EntityType));
}
@ -37,7 +28,7 @@ bool cZombiepigman::IsA( const char* a_EntityType )
void cZombiepigman::Tick(float a_Dt)
{
cMonster::Tick(a_Dt);
super::Tick(a_Dt);
// TODO Same as noticed in cSkeleton AND Do they really burn by sun?? :D In the neather is no sun :D
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && (GetMetaData() != BURNING))
@ -50,17 +41,27 @@ void cZombiepigman::Tick(float a_Dt)
void cZombiepigman::KilledBy(cEntity * a_Killer)
void cZombiepigman::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
cItems Drops;
AddRandomDropItem(Drops, 0, 1, E_ITEM_ROTTEN_FLESH);
AddRandomDropItem(Drops, 0, 1, E_ITEM_GOLD_NUGGET);
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_ROTTEN_FLESH);
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_GOLD_NUGGET);
// TODO: Rare drops
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
cMonster::KilledBy( a_Killer );
}
void cZombiepigman::KilledBy(cPawn * a_Killer)
{
super::KilledBy(a_Killer);
if ((a_Killer != NULL) && (a_Killer->GetEntityType() == eEntityType_Player))
{
// TODO: Anger all nearby zombie pigmen
// TODO: In vanilla, if one player angers ZPs, do they attack any nearby player, or only that one attacker?
}
}

View File

@ -1,15 +1,27 @@
#pragma once
#include "PassiveAggressiveMonster.h"
class cZombiepigman : public cPassiveAggressiveMonster
class cZombiepigman :
public cPassiveAggressiveMonster
{
typedef cPassiveAggressiveMonster super;
public:
cZombiepigman();
~cZombiepigman();
virtual bool IsA( const char* a_EntityType );
virtual bool IsA(const char * a_EntityType) override;
virtual void Tick(float a_Dt) override;
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
virtual void KilledBy(cPawn * a_Killer) override;
} ;
virtual void Tick(float a_Dt);
virtual void KilledBy( cEntity* a_Killer );
};

View File

@ -21,8 +21,10 @@ CLASS_DEFINITION( cPawn, cEntity )
cPawn::cPawn()
cPawn::cPawn(void)
: cEntity( 0, 0, 0 )
, m_Health(1)
, m_MaxHealth(1)
, m_LastPosX( 0.0 )
, m_LastPosY( 0.0 )
, m_LastPosZ( 0.0 )
@ -30,7 +32,6 @@ cPawn::cPawn()
, m_bBurnable(true)
, m_MetaData(NORMAL)
{
SetMaxHealth(20);
}
@ -39,40 +40,83 @@ cPawn::cPawn()
cPawn::~cPawn()
{
// Nothing needed yet
}
void cPawn::Heal( int a_Health )
void cPawn::Heal(int a_HitPoints)
{
(void)a_Health;
m_Health += a_HitPoints;
if (m_Health > m_MaxHealth)
{
m_Health = m_MaxHealth;
}
}
void cPawn::TakeDamage(int a_Damage, cEntity * a_Instigator)
void cPawn::TakeDamage(cPawn & a_Attacker)
{
int RawDamage = a_Attacker.GetRawDamageAgainst(*this);
TakeDamage(dtAttack, &a_Attacker, RawDamage, a_Attacker.GetKnockbackAmountAgainst(*this));
}
void cPawn::TakeDamage(eDamageType a_DamageType, cPawn * a_Attacker, int a_RawDamage, double a_KnockbackAmount)
{
int FinalDamage = a_RawDamage - GetArmorCoverAgainst(a_Attacker, a_DamageType, a_RawDamage);
TakeDamage(a_DamageType, a_Attacker, a_RawDamage, FinalDamage, a_KnockbackAmount);
}
void cPawn::TakeDamage(eDamageType a_DamageType, cPawn * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount)
{
TakeDamageInfo TDI;
TDI.Damage = a_Damage;
TDI.Instigator = a_Instigator;
cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_TAKE_DAMAGE, 2, this, &TDI);
TDI.DamageType = a_DamageType;
TDI.Attacker = a_Attacker;
TDI.RawDamage = a_RawDamage;
TDI.FinalDamage = a_FinalDamage;
Vector3d Heading;
Heading.x = sin(m_Rot.x);
Heading.y = 0.4; // TODO: adjust the amount of "up" knockback when testing
Heading.z = cos(m_Rot.x);
TDI.Knockback = Heading * a_KnockbackAmount;
DoTakeDamage(TDI);
}
if (TDI.Damage == 0)
void cPawn::DoTakeDamage(TakeDamageInfo & a_TDI)
{
if (cRoot::Get()->GetPluginManager()->CallHookTakeDamage(*this, a_TDI))
{
return;
}
if (m_Health <= 0)
{
// Can't take damage if already dead
return;
}
m_Health -= (short)TDI.Damage;
m_Health -= (short)a_TDI.FinalDamage;
// TODO: Apply damage to armor
if (m_Health < 0)
{
m_Health = 0;
@ -82,7 +126,7 @@ void cPawn::TakeDamage(int a_Damage, cEntity * a_Instigator)
if (m_Health <= 0)
{
KilledBy(TDI.Instigator);
KilledBy(a_TDI.Attacker);
}
}
@ -90,15 +134,23 @@ void cPawn::TakeDamage(int a_Damage, cEntity * a_Instigator)
void cPawn::KilledBy(cEntity * a_Killer)
void cPawn::KilledBy(cPawn * a_Killer)
{
short OldHealth = m_Health;
m_Health = 0;
if( cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer ) )
if (cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_KILLED, 2, this, a_Killer))
{
return; // Give plugins a chance to 'unkill' the pawn.
// Plugin wants to 'unkill' the pawn. Set health back and abort
m_Health = OldHealth;
return;
}
// Drop loot:
cItems Drops;
GetDrops(Drops, a_Killer);
m_World->SpawnItemPickups(Drops, m_Pos.x, m_Pos.y, m_Pos.z);
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_DEAD);
}
@ -106,18 +158,147 @@ void cPawn::KilledBy(cEntity * a_Killer)
void cPawn::TeleportToEntity(cEntity * a_Entity)
int cPawn::GetRawDamageAgainst(const cPawn & a_Receiver)
{
TeleportTo(a_Entity->GetPosX(), a_Entity->GetPosY(), a_Entity->GetPosZ());
// Returns the hitpoints that this pawn can deal to a_Receiver using its equipped items
// Ref: http://www.minecraftwiki.net/wiki/Damage#Dealing_damage as of 2012_12_20
switch (this->GetEquippedWeapon().m_ItemType)
{
case E_ITEM_WOODEN_SWORD: return 4;
case E_ITEM_GOLD_SWORD: return 4;
case E_ITEM_STONE_SWORD: return 5;
case E_ITEM_IRON_SWORD: return 6;
case E_ITEM_DIAMOND_SWORD: return 7;
case E_ITEM_WOODEN_AXE: return 3;
case E_ITEM_GOLD_AXE: return 3;
case E_ITEM_STONE_AXE: return 4;
case E_ITEM_IRON_AXE: return 5;
case E_ITEM_DIAMOND_AXE: return 6;
case E_ITEM_WOODEN_PICKAXE: return 2;
case E_ITEM_GOLD_PICKAXE: return 2;
case E_ITEM_STONE_PICKAXE: return 3;
case E_ITEM_IRON_PICKAXE: return 4;
case E_ITEM_DIAMOND_PICKAXE: return 5;
case E_ITEM_WOODEN_SHOVEL: return 1;
case E_ITEM_GOLD_SHOVEL: return 1;
case E_ITEM_STONE_SHOVEL: return 2;
case E_ITEM_IRON_SHOVEL: return 3;
case E_ITEM_DIAMOND_SHOVEL: return 4;
}
// All other equipped items give a damage of 1:
return 1;
}
void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ )
int cPawn::GetArmorCoverAgainst(const cPawn * a_Attacker, eDamageType a_DamageType, int a_Damage)
{
SetPosition( a_PosX, a_PosY, a_PosZ );
// Returns the hitpoints out of a_RawDamage that the currently equipped armor would cover
// Filter out damage types that are not protected by armor:
// Ref.: http://www.minecraftwiki.net/wiki/Armor#Effects as of 2012_12_20
switch (a_DamageType)
{
case dtOnFire:
case dtSuffocating:
case dtDrowning: // TODO: This one could be a special case - in various MC versions (PC vs XBox) it is and isn't armor-protected
case dtStarving:
case dtInVoid:
case dtPoisoning:
case dtPotionOfHarming:
case dtFalling:
case dtLightning:
{
return 0;
}
}
// Add up all armor points:
// Ref.: http://www.minecraftwiki.net/wiki/Armor#Defense_points as of 2012_12_20
int ArmorValue = 0;
switch (GetEquippedHelmet().m_ItemType)
{
case E_ITEM_LEATHER_CAP: ArmorValue += 1; break;
case E_ITEM_GOLD_HELMET: ArmorValue += 2; break;
case E_ITEM_CHAIN_HELMET: ArmorValue += 2; break;
case E_ITEM_IRON_HELMET: ArmorValue += 2; break;
case E_ITEM_DIAMOND_HELMET: ArmorValue += 3; break;
}
switch (GetEquippedChestplate().m_ItemType)
{
case E_ITEM_LEATHER_TUNIC: ArmorValue += 3; break;
case E_ITEM_GOLD_CHESTPLATE: ArmorValue += 5; break;
case E_ITEM_CHAIN_CHESTPLATE: ArmorValue += 5; break;
case E_ITEM_IRON_CHESTPLATE: ArmorValue += 6; break;
case E_ITEM_DIAMOND_CHESTPLATE: ArmorValue += 8; break;
}
switch (GetEquippedLeggings().m_ItemType)
{
case E_ITEM_LEATHER_PANTS: ArmorValue += 2; break;
case E_ITEM_GOLD_LEGGINGS: ArmorValue += 3; break;
case E_ITEM_CHAIN_LEGGINGS: ArmorValue += 4; break;
case E_ITEM_IRON_LEGGINGS: ArmorValue += 5; break;
case E_ITEM_DIAMOND_LEGGINGS: ArmorValue += 6; break;
}
switch (GetEquippedBoots().m_ItemType)
{
case E_ITEM_LEATHER_BOOTS: ArmorValue += 1; break;
case E_ITEM_GOLD_BOOTS: ArmorValue += 1; break;
case E_ITEM_CHAIN_BOOTS: ArmorValue += 1; break;
case E_ITEM_IRON_BOOTS: ArmorValue += 2; break;
case E_ITEM_DIAMOND_BOOTS: ArmorValue += 3; break;
}
// TODO: Special armor cases, such as wool, saddles, dog's collar
// Ref.: http://www.minecraftwiki.net/wiki/Armor#Mob_armor as of 2012_12_20
// Now ArmorValue is in [0, 20] range, which corresponds to [0, 80%] protection. Calculate the hitpoints from that:
return a_Damage * (ArmorValue * 4) / 100;
}
double cPawn::GetKnockbackAmountAgainst(const cPawn & a_Receiver)
{
// Returns the knockback amount that the currently equipped items would cause to a_Receiver on a hit
// TODO: Enchantments
return 1;
}
void cPawn::GetDrops(cItems & a_Drops, cPawn * a_Killer)
{
UNUSED(a_Drops);
UNUSED(a_Killer);
}
void cPawn::TeleportToEntity(cEntity & a_Entity)
{
TeleportTo(a_Entity.GetPosX(), a_Entity.GetPosY(), a_Entity.GetPosZ());
}
void cPawn::TeleportTo(double a_PosX, double a_PosY, double a_PosZ)
{
SetPosition(a_PosX, a_PosY, a_PosZ);
GetWorld()->BroadcastTeleportEntity(*this);
}
@ -155,9 +336,9 @@ void cPawn::SetMetaData(MetaData a_MetaData)
//----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);
BLOCKTYPE Block = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y, (int) m_Pos.z);
BLOCKTYPE BlockAbove = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y + 1, (int) m_Pos.z);
BLOCKTYPE BlockBelow = GetWorld()->GetBlock((int) m_Pos.x, (int) m_Pos.y - 1, (int) m_Pos.z);
if (
(GetMetaData() == BURNING) &&
@ -184,35 +365,36 @@ void cPawn::CheckMetaDataBurn()
//What to do if On fire
// 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)
if (m_FireDamageInterval < 800)
{
return;
}
m_FireDamageInterval = 0;
TakeDamage(1, this);
BLOCKTYPE Block = GetWorld()->GetBlock((int)m_Pos.x, (int)m_Pos.y, (int)m_Pos.z);
BLOCKTYPE BlockAbove = GetWorld()->GetBlock((int)m_Pos.x, (int)m_Pos.y + 1, (int)m_Pos.z);
m_FireDamageInterval = 0;
TakeDamage(dtOnFire, NULL, 1, 0);
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;
}
m_BurnPeriod++;
if (
IsBlockLava(Block) ||
(Block == E_BLOCK_FIRE) ||
IsBlockLava(BlockAbove) ||
(BlockAbove == E_BLOCK_FIRE)
)
{
m_BurnPeriod = 0;
TakeDamage(dtLavaContact, NULL, 6, 0);
}
if (m_BurnPeriod > 7)
{
SetMetaData(NORMAL);
m_BurnPeriod = 0;
}
}
@ -224,7 +406,7 @@ void cPawn::SetMaxHealth(short a_MaxHealth)
{
this->m_MaxHealth = a_MaxHealth;
//Reset health
// Reset health
m_Health = a_MaxHealth;
}

View File

@ -2,38 +2,145 @@
#pragma once
#include "Entity.h"
#include "Item.h"
struct TakeDamageInfo //tolua_export
{ //tolua_export
int Damage; //tolua_export
cEntity* Instigator; //tolua_export
}; //tolua_export
// fwd:
class cPawn;
class cPawn : public cEntity //tolua_export
{ //tolua_export
// tolua_begin
enum eDamageType
{
// Canonical names for the types (as documented in the plugin wiki):
dtAttack, // Being attacked by a mob
dtLightning, // Hit by a lightning strike
dtFalling, // Falling down; dealt when hitting the ground
dtDrowning, // Drowning in water / lava
dtSuffocating, // Suffocating inside a block
dtStarving, // Hunger
dtCactusContact, // Contact with a cactus block
dtLavaContact, // Contact with a lava block
dtPoisoning, // Having the poison effect
dtOnFire, // Being on fire
dtFireContact, // Standing inside a fire block
dtInVoid, // Falling into the Void (Y < 0)
dtPotionOfHarming,
// Some common synonyms:
dtPawnAttack = dtAttack,
dtEntityAttack = dtAttack,
dtMob = dtAttack,
dtMobAttack = dtAttack,
dtFall = dtFalling,
dtDrown = dtDrowning,
dtSuffocation = dtSuffocating,
dtStarvation = dtStarving,
dtHunger = dtStarving,
dtCactus = dtCactusContact,
dtCactuses = dtCactusContact,
dtCacti = dtCactusContact,
dtLava = dtLavaContact,
dtPoison = dtPoisoning,
dtBurning = dtOnFire,
dtInFire = dtFireContact,
} ;
struct TakeDamageInfo
{
eDamageType DamageType; // Where does the damage come from? Being hit / on fire / contact with cactus / ...
cPawn * Attacker; // The attacking pawn; valid only for dtAttack
int RawDamage; // What damage would the receiver get without any armor. Usually: attacker mob type + weapons
int FinalDamage; // What actual damage will be received. Usually: m_RawDamage minus armor
Vector3d Knockback; // The amount and direction of knockback received from the damage
// TODO: Effects - list of effects that the hit is causing. Unknown representation yet
} ;
// tolua_end
// tolua_begin
class cPawn :
public cEntity
{
// tolua_end
public:
CLASS_PROTOTYPE()
cPawn();
cPawn(void);
virtual ~cPawn();
virtual void TeleportToEntity( cEntity* a_Entity ); //tolua_export
virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export
virtual void Tick(float a_Dt) override;
void Heal( int a_Health ); //tolua_export
virtual void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export
virtual void KilledBy( cEntity* a_Killer ); //tolua_export
int GetHealth() { return m_Health; } //tolua_export
// tolua_begin
/// Teleports to the entity specified
virtual void TeleportToEntity(cEntity & a_Entity);
/// Teleports to the coordinates specified
virtual void TeleportTo(double a_PosX, double a_PosY, double a_PosZ);
/// Heals the specified amount of HPs
void Heal(int a_HitPoints);
/// Returns the health of this pawn
int GetHealth(void) const { return m_Health; }
/// Makes this pawn take damage from an attack by a_Attacker. Damage values are calculated automatically and DoTakeDamage() called
void TakeDamage(cPawn & a_Attacker);
/// Makes this pawn take the specified damage. The final damage is calculated using current armor, then DoTakeDamage() called
void TakeDamage(eDamageType a_DamageType, cPawn * a_Attacker, int a_RawDamage, double a_KnockbackAmount);
/// Makes this pawn take the specified damage. The values are packed into a TDI, knockback calculated, then sent through DoTakeDamage()
void TakeDamage(eDamageType a_DamageType, cPawn * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount);
/// Makes this pawn take damage specified in the a_TDI. The TDI is sent through plugins first, then applied
virtual void DoTakeDamage(TakeDamageInfo & a_TDI);
/// Called when the health drops below zero. a_Killer may be NULL (environmental damage)
virtual void KilledBy(cPawn * a_Killer);
/// Returns the hitpoints that this pawn can deal to a_Receiver using its equipped items
virtual int GetRawDamageAgainst(const cPawn & a_Receiver);
/// Returns the hitpoints out of a_RawDamage that the currently equipped armor would cover
virtual int GetArmorCoverAgainst(const cPawn * a_Attacker, eDamageType a_DamageType, int a_RawDamage);
/// Returns the knockback amount that the currently equipped items would cause to a_Receiver on a hit
virtual double GetKnockbackAmountAgainst(const cPawn & a_Receiver);
/// Returns the curently equipped weapon; empty item if none
virtual cItem GetEquippedWeapon(void) const { return cItem(); }
/// Returns the currently equipped helmet; empty item if nonte
virtual cItem GetEquippedHelmet(void) const { return cItem(); }
/// Returns the currently equipped chestplate; empty item if nonte
virtual cItem GetEquippedChestplate(void) const { return cItem(); }
/// Returns the currently equipped leggings; empty item if nonte
virtual cItem GetEquippedLeggings(void) const { return cItem(); }
/// Returns the currently equipped boots; empty item if nonte
virtual cItem GetEquippedBoots(void) const { return cItem(); }
// tolua_end
/// Returns the list of drops for this pawn when it is killed. May check a_Killer for special handling (sword of looting etc.). Called from KilledBy().
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL);
enum MetaData {NORMAL, BURNING, CROUCHED, RIDING, SPRINTING, EATING, BLOCKING};
@ -48,10 +155,8 @@ public:
virtual short GetMaxHealth() { return m_MaxHealth; }
protected:
short m_Health;
short m_MaxHealth;
bool m_bBurnable;

View File

@ -70,6 +70,7 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
LOGD("Inventory window for player %p is at %p", this, m_InventoryWindow);
SetMaxHealth(20);
m_MaxFoodLevel = 20;
m_MaxFoodSaturationLevel = 20.f;
@ -222,18 +223,19 @@ void cPlayer::Tick(float a_Dt)
{
m_World->CollectPickupsByPlayer(this);
//Handle Health:
// Handle Health:
m_FoodTickTimer++;
if(m_FoodTickTimer >= 80)
if (m_FoodTickTimer >= 80)
{
m_FoodTickTimer = 0;
if(m_FoodLevel >= 17)
if (m_FoodLevel >= 17)
{
Heal(1);
}else if(m_FoodLevel == 0)
}
else if (m_FoodLevel == 0)
{
TakeDamage(1, NULL);
super::TakeDamage(dtStarving, NULL, 1, 1, 0);
}
}
@ -248,7 +250,7 @@ void cPlayer::Tick(float a_Dt)
}
else
{
m_FoodLevel = MAX(m_FoodLevel -1, 0);
m_FoodLevel = MAX(m_FoodLevel - 1, 0);
}
SendHealth();
@ -297,7 +299,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
m_LastJumpHeight = (float)m_Pos.y;
if (Damage > 0)
{
TakeDamage(Damage, 0);
super::TakeDamage(dtFalling, NULL, Damage, Damage, 0);
}
m_LastGroundHeight = (float)m_Pos.y;
@ -353,23 +355,30 @@ void cPlayer::SendHealth()
void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator )
void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
{
if (m_GameMode != eGameMode_Creative)
if (m_GameMode == eGameMode_Creative)
{
cPawn::TakeDamage( a_Damage, a_Instigator );
AddFoodExhaustion(0.3f);
SendHealth();
// No damage / health in creative mode
return;
}
super::DoTakeDamage(a_TDI);
if (a_TDI.Attacker != NULL)
{
// Only increase hunger if being attacked by a mob
AddFoodExhaustion(0.3f);
}
SendHealth();
}
void cPlayer::KilledBy(cEntity * a_Killer)
void cPlayer::KilledBy(cPawn * a_Killer)
{
cPawn::KilledBy(a_Killer);
@ -544,7 +553,7 @@ void cPlayer::SendMessage(const AString & a_Message)
void cPlayer::TeleportTo(const double & a_PosX, const double & a_PosY, const double & a_PosZ)
void cPlayer::TeleportTo(double a_PosX, double a_PosY, double a_PosZ)
{
SetPosition( a_PosX, a_PosY, a_PosZ );

View File

@ -17,9 +17,17 @@ class cClientHandle;
class cPlayer : public cPawn //tolua_export
{ //tolua_export
// tolua_begin
class cPlayer :
public cPawn
{
public:
enum
{
MAX_HEALTH = 20,
} ;
// tolua_end
typedef cPawn super;
CLASS_PROTOTYPE()
@ -33,6 +41,21 @@ public:
virtual void Tick(float a_Dt) override;
/// Returns the curently equipped weapon; empty item if none
virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
/// Returns the currently equipped helmet; empty item if nonte
virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); }
/// Returns the currently equipped chestplate; empty item if none
virtual cItem GetEquippedChestplate(void) const override { return m_Inventory.GetEquippedChestplate(); }
/// Returns the currently equipped leggings; empty item if none
virtual cItem GetEquippedLeggings(void) const override { return m_Inventory.GetEquippedLeggings(); }
/// Returns the currently equipped boots; empty item if none
virtual cItem GetEquippedBoots(void) const override { return m_Inventory.GetEquippedBoots(); }
void SetTouchGround( bool a_bTouchGround );
inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; }
double GetEyeHeight(); //tolua_export
@ -44,7 +67,7 @@ public:
inline const cItem & GetEquippedItem(void) const {return GetInventory().GetEquippedItem(); } // tolua_export
virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export
virtual void TeleportTo(double a_PosX, double a_PosY, double a_PosZ) override;
eGameMode GetGameMode(void) const { return m_GameMode; } //tolua_export
std::string GetIP() { return m_IP; } //tolua_export
@ -100,18 +123,18 @@ public:
void AddFoodExhaustion(float a_Exhaustion) { m_FoodExhaustionLevel += a_Exhaustion; } //tolua_export
void TakeDamage( int a_Damage, cEntity* a_Instigator ); //tolua_export
void KilledBy( cEntity* a_Killer ); //tolua_export
void Respawn(); //tolua_export
virtual void KilledBy(cPawn * a_Killer) override;
void Respawn(void); //tolua_export
void SetVisible( bool a_bVisible ); //tolua_export
bool IsVisible() { return m_bVisible; } //tolua_export
bool IsVisible(void) const { return m_bVisible; } //tolua_export
bool MoveToWorld( const char* a_WorldName ); //tolua_export
bool MoveToWorld(const char * a_WorldName ); //tolua_export
bool SaveToDisk();
bool LoadFromDisk();
void LoadPermissionsFromDisk(); //tolua_export
bool SaveToDisk(void);
bool LoadFromDisk(void);
void LoadPermissionsFromDisk(void); //tolua_export
const AString & GetLoadedWorldName() { return m_LoadedWorldName; }
@ -171,4 +194,12 @@ protected:
static const unsigned short PLAYER_LIST_TIME_MS = 1000; // 1000 = once per second
cClientHandle* m_ClientHandle;
}; //tolua_export
/// Filters out damage for creative mode
virtual void DoTakeDamage(TakeDamageInfo & TDI) override;
} ; //tolua_export

View File

@ -2,6 +2,7 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "Plugin.h"
#include "Pawn.h"
@ -228,10 +229,11 @@ bool cPlugin::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Gr
void cPlugin::OnTakeDamage(cPawn * a_Pawn, TakeDamageInfo * a_TakeDamageInfo)
bool cPlugin::OnTakeDamage(cPawn & a_Pawn, TakeDamageInfo & a_TakeDamageInfo)
{
UNUSED(a_Pawn);
UNUSED(a_TakeDamageInfo);
return false;
}

View File

@ -57,7 +57,7 @@ public:
virtual void OnPlayerSpawn (cPlayer* a_Player );
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual void OnTakeDamage (cPawn * a_Pawn, TakeDamageInfo * a_TakeDamageInfo );
virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo);
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player);
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
virtual bool OnWeatherChanged (cWorld * a_World);

View File

@ -253,21 +253,6 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...)
break;
}
case HOOK_TAKE_DAMAGE:
{
if( a_NumArgs != 2 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
cPawn* Pawn = va_arg(argptr, cPawn* );
TakeDamageInfo* TDI = va_arg(argptr, TakeDamageInfo* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
(*itr)->OnTakeDamage( Pawn, TDI );
}
break;
}
case HOOK_KILLED:
{
if( a_NumArgs != 2 ) break;
@ -482,27 +467,6 @@ bool cPluginManager::CallHookCollectPickup(cPlayer * a_Player, cPickup & a_Picku
bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PRE_CRAFTING);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPreCrafting(a_Player, a_Grid, a_Recipe))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_CRAFTING_NO_RECIPE);
@ -566,6 +530,48 @@ bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraft
bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_PRE_CRAFTING);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnPreCrafting(a_Player, a_Grid, a_Recipe))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookTakeDamage(cPawn & a_Receiver, TakeDamageInfo & a_TDI)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_TAKE_DAMAGE);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnTakeDamage(a_Receiver, a_TDI))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookBlockToPickup(
BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
const cPlayer * a_Player, const cItem & a_EquippedItem, cItems & a_Pickups

View File

@ -12,22 +12,26 @@ class cLuaCommandBinder;
class cPlugin;
// fwd: cWorld.h
// fwd: World.h
class cWorld;
// fwd: cLuaChunk.h
// fwd: LuaChunk.h
class cLuaChunk;
// fwd: cPlayer.h
// fwd: Player.h
class cPlayer;
// fwd: CraftingRecipes.h
class cCraftingGrid;
class cCraftingRecipe;
// fwd: cPickup.h
// fwd: Pickup.h
class cPickup;
// fwd: Pawn.h
struct TakeDamageInfo;
class cPawn;
@ -54,7 +58,7 @@ public: //tolua_export
HOOK_PLAYER_SPAWN,
HOOK_PLAYER_JOIN,
HOOK_PLAYER_MOVE,
HOOK_TAKE_DAMAGE,
HOOK_TAKE_DAMAGE, // cPawn, TakeDamageInfo
HOOK_KILLED,
HOOK_CHUNK_GENERATED,
HOOK_CHUNK_GENERATING,
@ -115,6 +119,7 @@ public: //tolua_export
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TDI);
bool CallHookUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player);
bool CallHookUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player);
bool CallHookWeatherChanged (cWorld * a_World);

View File

@ -366,16 +366,25 @@ void cPlugin_NewLua::OnPlayerMove( cPlayer* a_Player )
void cPlugin_NewLua::OnTakeDamage( cPawn* a_Pawn, TakeDamageInfo* a_TakeDamageInfo )
bool cPlugin_NewLua::OnTakeDamage(cPawn & a_Receiver, TakeDamageInfo & a_TDI)
{
cCSLock Lock( m_CriticalSection );
if( !PushFunction("OnTakeDamage") )
return;
cCSLock Lock(m_CriticalSection);
if (!PushFunction("OnTakeDamage"))
{
return false;
}
tolua_pushusertype(m_LuaState, a_Pawn, "cPawn");
tolua_pushusertype(m_LuaState, a_TakeDamageInfo, "TakeDamageInfo");
tolua_pushusertype(m_LuaState, &a_Receiver, "cPawn");
tolua_pushusertype(m_LuaState, &a_TDI, "TakeDamageInfo");
CallFunction(2, 0, "OnTakeDamage");
if (!CallFunction(2, 1, "OnTakeDamage"))
{
return false;
}
bool bRetVal = (tolua_toboolean(m_LuaState, -1, 0) != 0);
lua_pop(m_LuaState, 1);
return bRetVal;
}

View File

@ -14,9 +14,14 @@ typedef struct lua_State lua_State;
class cPlugin_NewLua : public cPlugin, public cWebPlugin //tolua_export
{ //tolua_export
public: //tolua_export
// tolua_begin
class cPlugin_NewLua :
public cPlugin,
public cWebPlugin
{
public:
// tolua_end
cPlugin_NewLua( const AString & a_PluginDirectory );
~cPlugin_NewLua();
@ -41,7 +46,7 @@ public: //tolua_export
virtual void OnPlayerSpawn (cPlayer * a_Player ) override;
virtual bool OnPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual void OnTakeDamage (cPawn * a_Pawn, TakeDamageInfo * a_TakeDamageInfo ) override;
virtual bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override;
virtual bool OnUpdatedSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnUpdatingSign (cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4, cPlayer * a_Player) override;
virtual bool OnWeatherChanged (cWorld * a_World) override;