Rewritten entity-on-fire management ("forever on fire" bugs)
Fixes FS #297 and part of FS #403. Added sizes to all entities. Moved all damage-related functions from cPawn to cEntity API change: renamed cPawn:TeleportTo() to cEntity:TeleportToCoords() git-svn-id: http://mc-server.googlecode.com/svn/trunk@1635 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
3cfe865df3
commit
37276a4430
@ -1,7 +1,7 @@
|
||||
function HandleSpawnCommand( Split, Player )
|
||||
function HandleSpawnCommand(Split, Player)
|
||||
World = Player:GetWorld()
|
||||
SetBackCoordinates( Player )
|
||||
Player:TeleportTo( World:GetSpawnX(), World:GetSpawnY(), World:GetSpawnZ() )
|
||||
LOGINFO( Player:GetName() .. " returned to spawn." )
|
||||
SetBackCoordinates(Player)
|
||||
Player:TeleportToCoords(World:GetSpawnX(), World:GetSpawnY(), World:GetSpawnZ())
|
||||
LOGINFO(Player:GetName() .. " returned to spawn.")
|
||||
return true
|
||||
end
|
3524
source/Bindings.cpp
3524
source/Bindings.cpp
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/*
|
||||
** Lua binding: AllToLua
|
||||
** Generated automatically by tolua++-1.0.92 on 06/29/13 17:21:36.
|
||||
** Generated automatically by tolua++-1.0.92 on 07/01/13 09:49:29.
|
||||
*/
|
||||
|
||||
/* Exported function */
|
||||
|
@ -510,16 +510,16 @@ void cChunkMap::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, c
|
||||
|
||||
|
||||
|
||||
void cChunkMap::BroadcastMetadata(const cPawn & a_Pawn, const cClientHandle * a_Exclude)
|
||||
void cChunkMap::BroadcastMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
cCSLock Lock(m_CSLayers);
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Pawn.GetChunkX(), ZERO_CHUNK_Y, a_Pawn.GetChunkZ());
|
||||
cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), ZERO_CHUNK_Y, a_Entity.GetChunkZ());
|
||||
if (Chunk == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// It's perfectly legal to broadcast packets even to invalid chunks!
|
||||
Chunk->BroadcastMetadata(a_Pawn, a_Exclude);
|
||||
Chunk->BroadcastMetadata(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
|
||||
void BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
void BroadcastMetadata(const cPawn & a_Pawn, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
void BroadcastSpawn(cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "Tracer.h"
|
||||
#include "Chunk.h"
|
||||
#include "Simulator/FluidSimulator.h"
|
||||
#include "PluginManager.h"
|
||||
|
||||
|
||||
|
||||
@ -24,8 +25,10 @@ cCriticalSection cEntity::m_CSCount;
|
||||
|
||||
|
||||
|
||||
cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z)
|
||||
cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height)
|
||||
: m_UniqueID(0)
|
||||
, m_Health(1)
|
||||
, m_MaxHealth(1)
|
||||
, m_AttachedTo(NULL)
|
||||
, m_Attachee(NULL)
|
||||
, m_Referencers(new cReferenceManager(cReferenceManager::RFMNGR_REFERENCERS))
|
||||
@ -49,9 +52,13 @@ cEntity::cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z)
|
||||
, m_TimeLastSpeedPacket(0)
|
||||
, m_EntityType(a_EntityType)
|
||||
, m_World(NULL)
|
||||
, m_FireDamageInterval(0.f)
|
||||
, m_BurnPeriod(0.f)
|
||||
, m_WaterSpeed( 0.0 , 0.0 , 0.0 )
|
||||
, m_TicksSinceLastBurnDamage(0)
|
||||
, m_TicksSinceLastLavaDamage(0)
|
||||
, m_TicksSinceLastFireDamage(0)
|
||||
, m_TicksLeftBurning(0)
|
||||
, m_WaterSpeed(0, 0, 0)
|
||||
, m_Width(a_Width)
|
||||
, m_Height(a_Height)
|
||||
{
|
||||
cCSLock Lock(m_CSCount);
|
||||
m_EntityCount++;
|
||||
@ -194,6 +201,236 @@ void cEntity::Destroy(bool a_ShouldBroadcast)
|
||||
|
||||
|
||||
|
||||
void cEntity::TakeDamage(cEntity & a_Attacker)
|
||||
{
|
||||
int RawDamage = a_Attacker.GetRawDamageAgainst(*this);
|
||||
|
||||
TakeDamage(dtAttack, &a_Attacker, RawDamage, a_Attacker.GetKnockbackAmountAgainst(*this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, double a_KnockbackAmount)
|
||||
{
|
||||
int FinalDamage = a_RawDamage - GetArmorCoverAgainst(a_Attacker, a_DamageType, a_RawDamage);
|
||||
cEntity::TakeDamage(a_DamageType, a_Attacker, a_RawDamage, FinalDamage, a_KnockbackAmount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount)
|
||||
{
|
||||
TakeDamageInfo TDI;
|
||||
TDI.DamageType = a_DamageType;
|
||||
TDI.Attacker = a_Attacker;
|
||||
TDI.RawDamage = a_RawDamage;
|
||||
TDI.FinalDamage = a_FinalDamage;
|
||||
Vector3d Heading;
|
||||
Heading.x = sin(GetRotation());
|
||||
Heading.y = 0.4; // TODO: adjust the amount of "up" knockback when testing
|
||||
Heading.z = cos(GetRotation());
|
||||
TDI.Knockback = Heading * a_KnockbackAmount;
|
||||
DoTakeDamage(TDI);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::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)a_TDI.FinalDamage;
|
||||
|
||||
// TODO: Apply damage to armor
|
||||
|
||||
if (m_Health < 0)
|
||||
{
|
||||
m_Health = 0;
|
||||
}
|
||||
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_HURT);
|
||||
|
||||
if (m_Health <= 0)
|
||||
{
|
||||
KilledBy(a_TDI.Attacker);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cEntity::GetRawDamageAgainst(const cEntity & a_Receiver)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cEntity::GetArmorCoverAgainst(const cEntity * a_Attacker, eDamageType a_DamageType, int a_Damage)
|
||||
{
|
||||
// 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 cEntity::GetKnockbackAmountAgainst(const cEntity & a_Receiver)
|
||||
{
|
||||
// Returns the knockback amount that the currently equipped items would cause to a_Receiver on a hit
|
||||
|
||||
// TODO: Enchantments
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::KilledBy(cEntity * a_Killer)
|
||||
{
|
||||
m_Health = 0;
|
||||
|
||||
cRoot::Get()->GetPluginManager()->CallHookKilling(*this, a_Killer);
|
||||
|
||||
if (m_Health > 0)
|
||||
{
|
||||
// Plugin wants to 'unkill' the pawn. Abort
|
||||
return;
|
||||
}
|
||||
|
||||
// Drop loot:
|
||||
cItems Drops;
|
||||
GetDrops(Drops, a_Killer);
|
||||
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ());
|
||||
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_DEAD);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::Heal(int a_HitPoints)
|
||||
{
|
||||
m_Health += a_HitPoints;
|
||||
if (m_Health > m_MaxHealth)
|
||||
{
|
||||
m_Health = m_MaxHealth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
if (m_AttachedTo != NULL)
|
||||
@ -207,6 +444,7 @@ void cEntity::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
HandlePhysics(a_Dt, a_Chunk);
|
||||
}
|
||||
TickBurning(a_Chunk);
|
||||
}
|
||||
|
||||
|
||||
@ -391,6 +629,226 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cEntity::TickBurning(cChunk & a_Chunk)
|
||||
{
|
||||
// Do the burning damage:
|
||||
if (m_TicksLeftBurning > 0)
|
||||
{
|
||||
m_TicksSinceLastBurnDamage++;
|
||||
if (m_TicksSinceLastBurnDamage >= BURN_TICKS_PER_DAMAGE)
|
||||
{
|
||||
TakeDamage(dtOnFire, NULL, BURN_DAMAGE, 0, 0);
|
||||
m_TicksSinceLastFireDamage = 0;
|
||||
}
|
||||
m_TicksLeftBurning--;
|
||||
if (m_TicksLeftBurning == 0)
|
||||
{
|
||||
OnFinishedBurning();
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the current burning state:
|
||||
bool HasBeenBurning = (m_TicksLeftBurning > 0);
|
||||
|
||||
// Update the burning times, based on surroundings:
|
||||
int MinRelX = (int)floor(GetPosX() - m_Width / 2) - a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int MaxRelX = (int)floor(GetPosX() + m_Width / 2) - a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int MinRelZ = (int)floor(GetPosZ() - m_Width / 2) - a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
int MaxRelZ = (int)floor(GetPosZ() + m_Width / 2) - a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
int MinY = std::max(0, std::min(cChunkDef::Height - 1, (int)floor(GetPosY())));
|
||||
int MaxY = std::max(0, std::min(cChunkDef::Height - 1, (int)ceil (GetPosY() + m_Height)));
|
||||
bool HasWater = false;
|
||||
bool HasLava = false;
|
||||
bool HasFire = false;
|
||||
|
||||
for (int x = MinRelX; x <= MaxRelX; x++)
|
||||
{
|
||||
for (int z = MinRelZ; z <= MaxRelZ; z++)
|
||||
{
|
||||
int RelX = x;
|
||||
int RelZ = z;
|
||||
cChunk * CurChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelX, RelZ);
|
||||
if (CurChunk == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (int y = MinY; y <= MaxY; y++)
|
||||
{
|
||||
switch (CurChunk->GetBlock(RelX, y, RelZ))
|
||||
{
|
||||
case E_BLOCK_FIRE:
|
||||
{
|
||||
HasFire = true;
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_LAVA:
|
||||
case E_BLOCK_STATIONARY_LAVA:
|
||||
{
|
||||
HasLava = true;
|
||||
break;
|
||||
}
|
||||
case E_BLOCK_STATIONARY_WATER:
|
||||
case E_BLOCK_WATER:
|
||||
{
|
||||
HasWater = true;
|
||||
break;
|
||||
}
|
||||
} // switch (BlockType)
|
||||
} // for y
|
||||
} // for z
|
||||
} // for x
|
||||
|
||||
if (HasWater)
|
||||
{
|
||||
// Extinguish the fire
|
||||
m_TicksLeftBurning = 0;
|
||||
}
|
||||
|
||||
if (HasLava)
|
||||
{
|
||||
// Burn:
|
||||
m_TicksLeftBurning = BURN_TICKS;
|
||||
|
||||
// Periodically damage:
|
||||
m_TicksSinceLastLavaDamage++;
|
||||
if (m_TicksSinceLastLavaDamage >= 10)
|
||||
{
|
||||
TakeDamage(dtLavaContact, NULL, LAVA_DAMAGE, 0);
|
||||
m_TicksSinceLastLavaDamage = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TicksSinceLastLavaDamage = 0;
|
||||
}
|
||||
|
||||
if (HasFire)
|
||||
{
|
||||
// Burn:
|
||||
m_TicksLeftBurning = BURN_TICKS;
|
||||
|
||||
// Periodically damage:
|
||||
m_TicksSinceLastFireDamage++;
|
||||
if (m_TicksSinceLastFireDamage >= FIRE_TICKS_PER_DAMAGE)
|
||||
{
|
||||
TakeDamage(dtFireContact, NULL, FIRE_DAMAGE, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TicksSinceLastFireDamage = 0;
|
||||
}
|
||||
|
||||
// If just started / finished burning, notify descendants:
|
||||
if ((m_TicksLeftBurning > 0) && !HasBeenBurning)
|
||||
{
|
||||
OnStartedBurning();
|
||||
}
|
||||
else if ((m_TicksLeftBurning <= 0) && HasBeenBurning)
|
||||
{
|
||||
OnFinishedBurning();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Called when the entity starts burning
|
||||
void cEntity::OnStartedBurning(void)
|
||||
{
|
||||
// Broadcast the change:
|
||||
m_World->BroadcastMetadata(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Called when the entity finishes burning
|
||||
void cEntity::OnFinishedBurning(void)
|
||||
{
|
||||
// Broadcast the change:
|
||||
m_World->BroadcastMetadata(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Sets the maximum value for the health
|
||||
void cEntity::SetMaxHealth(int a_MaxHealth)
|
||||
{
|
||||
m_MaxHealth = a_MaxHealth;
|
||||
|
||||
// Reset health, if too high:
|
||||
if (m_Health > a_MaxHealth)
|
||||
{
|
||||
m_Health = a_MaxHealth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Puts the entity on fire for the specified amount of ticks
|
||||
void cEntity::StartBurning(int a_TicksLeftBurning)
|
||||
{
|
||||
if (m_TicksLeftBurning > 0)
|
||||
{
|
||||
// Already burning, top up the ticks left burning and bail out:
|
||||
m_TicksLeftBurning = std::max(m_TicksLeftBurning, a_TicksLeftBurning);
|
||||
return;
|
||||
}
|
||||
|
||||
m_TicksLeftBurning = a_TicksLeftBurning;
|
||||
OnStartedBurning();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// Stops the entity from burning, resets all burning timers
|
||||
void cEntity::StopBurning(void)
|
||||
{
|
||||
bool HasBeenBurning = (m_TicksLeftBurning > 0);
|
||||
m_TicksLeftBurning = 0;
|
||||
m_TicksSinceLastBurnDamage = 0;
|
||||
m_TicksSinceLastFireDamage = 0;
|
||||
m_TicksSinceLastLavaDamage = 0;
|
||||
|
||||
// Notify if the entity has stopped burning
|
||||
if (HasBeenBurning)
|
||||
{
|
||||
OnFinishedBurning();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::TeleportToEntity(cEntity & a_Entity)
|
||||
{
|
||||
TeleportToCoords(a_Entity.GetPosX(), a_Entity.GetPosY(), a_Entity.GetPosZ());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
||||
{
|
||||
SetPosition(a_PosX, a_PosY, a_PosZ);
|
||||
m_World->BroadcastTeleportEntity(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cEntity::BroadcastMovementUpdate(const cClientHandle * a_Exclude)
|
||||
{
|
||||
//We need to keep updating the clients when there is movement or if there was a change in speed and after 2 ticks
|
||||
|
204
source/Entity.h
204
source/Entity.h
@ -1,9 +1,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
|
||||
#include "Item.h"
|
||||
#include "Vector3d.h"
|
||||
#include "Vector3f.h"
|
||||
|
||||
@ -43,6 +41,65 @@ class cChunk;
|
||||
|
||||
|
||||
|
||||
|
||||
// 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,
|
||||
dtAdmin, // Damage applied by an admin command
|
||||
|
||||
// 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,
|
||||
dtPlugin = dtAdmin,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct TakeDamageInfo
|
||||
{
|
||||
eDamageType DamageType; // Where does the damage come from? Being hit / on fire / contact with cactus / ...
|
||||
cEntity * Attacker; // The attacking entity; 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 cEntity
|
||||
{
|
||||
@ -58,6 +115,17 @@ public:
|
||||
ENTITY_STATUS_SHEEP_EATING = 10,
|
||||
} ;
|
||||
|
||||
enum
|
||||
{
|
||||
FIRE_TICKS_PER_DAMAGE = 10, ///< How many ticks to wait between damaging an entity when it stands in fire
|
||||
FIRE_DAMAGE = 1, ///< How much damage to deal when standing in fire
|
||||
LAVA_TICKS_PER_DAMAGE = 10, ///< How many ticks to wait between damaging an entity when it stands in lava
|
||||
LAVA_DAMAGE = 5, ///< How much damage to deal when standing in lava
|
||||
BURN_TICKS_PER_DAMAGE = 20, ///< How many ticks to wait between damaging an entity when it is burning
|
||||
BURN_DAMAGE = 1, ///< How much damage to deal when the entity is burning
|
||||
BURN_TICKS = 200, ///< How long to keep an entity burning after it has stood in lava / fire
|
||||
} ;
|
||||
|
||||
enum eEntityType
|
||||
{
|
||||
etEntity, // For all other types
|
||||
@ -78,7 +146,7 @@ public:
|
||||
|
||||
// tolua_end
|
||||
|
||||
cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z);
|
||||
cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height);
|
||||
virtual ~cEntity();
|
||||
|
||||
virtual void Initialize(cWorld * a_World);
|
||||
@ -164,17 +232,102 @@ public:
|
||||
/// Schedules the entity for destroying; if a_ShouldBroadcast is set to true, broadcasts the DestroyEntity packet
|
||||
void Destroy(bool a_ShouldBroadcast = true);
|
||||
|
||||
/// Makes this pawn take damage from an attack by a_Attacker. Damage values are calculated automatically and DoTakeDamage() called
|
||||
void TakeDamage(cEntity & a_Attacker);
|
||||
|
||||
/// Makes this entity take the specified damage. The final damage is calculated using current armor, then DoTakeDamage() called
|
||||
void TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, double a_KnockbackAmount);
|
||||
|
||||
/// Makes this entity take the specified damage. The values are packed into a TDI, knockback calculated, then sent through DoTakeDamage()
|
||||
void TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount);
|
||||
|
||||
// tolua_end
|
||||
|
||||
/// Makes this entity take damage specified in the a_TDI. The TDI is sent through plugins first, then applied
|
||||
virtual void DoTakeDamage(TakeDamageInfo & a_TDI);
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/// Returns the hitpoints that this pawn can deal to a_Receiver using its equipped items
|
||||
virtual int GetRawDamageAgainst(const cEntity & a_Receiver);
|
||||
|
||||
/// Returns the hitpoints out of a_RawDamage that the currently equipped armor would cover
|
||||
virtual int GetArmorCoverAgainst(const cEntity * 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 cEntity & 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(); }
|
||||
|
||||
/// Called when the health drops below zero. a_Killer may be NULL (environmental damage)
|
||||
virtual void KilledBy(cEntity * a_Killer);
|
||||
|
||||
/// Heals the specified amount of HPs
|
||||
void Heal(int a_HitPoints);
|
||||
|
||||
/// Returns the health of this pawn
|
||||
int GetHealth(void) const { return m_Health; }
|
||||
|
||||
// tolua_end
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk);
|
||||
|
||||
/// Handles the physics of the entity - updates position based on speed, updates speed based on environment
|
||||
virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk);
|
||||
|
||||
/// Updates the state related to this entity being on fire
|
||||
virtual void TickBurning(cChunk & a_Chunk);
|
||||
|
||||
/// Called when the entity starts burning
|
||||
virtual void OnStartedBurning(void);
|
||||
|
||||
/// Called when the entity finishes burning
|
||||
virtual void OnFinishedBurning(void);
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/// Sets the maximum value for the health
|
||||
void SetMaxHealth(int a_MaxHealth);
|
||||
|
||||
int GetMaxHealth(void) const { return m_MaxHealth; }
|
||||
|
||||
/// Puts the entity on fire for the specified amount of ticks
|
||||
void StartBurning(int a_TicksLeftBurning);
|
||||
|
||||
/// Stops the entity from burning, resets all burning timers
|
||||
void StopBurning(void);
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Descendants override this function to send a command to the specified client to spawn the entity on the client.
|
||||
To spawn on all eligible clients, use cChunkMap::BroadcastSpawnEntity()
|
||||
Needs to have a default implementation due to Lua bindings.
|
||||
*/
|
||||
virtual void SpawnOn(cClientHandle & a_Client) {ASSERT(!"SpawnOn() unimplemented!"); }
|
||||
|
||||
// tolua_begin
|
||||
|
||||
/// Teleports to the entity specified
|
||||
virtual void TeleportToEntity(cEntity & a_Entity);
|
||||
|
||||
/// Teleports to the coordinates specified
|
||||
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ);
|
||||
|
||||
// tolua_end
|
||||
|
||||
/// Updates clients of changes in the entity.
|
||||
virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = NULL);
|
||||
|
||||
@ -196,7 +349,7 @@ public:
|
||||
// tolua_begin
|
||||
|
||||
// Metadata flags; descendants may override the defaults:
|
||||
virtual bool IsOnFire (void) const {return (m_BurnPeriod > 0); }
|
||||
virtual bool IsOnFire (void) const {return (m_TicksLeftBurning > 0); }
|
||||
virtual bool IsCrouched (void) const {return false; }
|
||||
virtual bool IsRiding (void) const {return false; }
|
||||
virtual bool IsSprinting(void) const {return false; }
|
||||
@ -207,12 +360,18 @@ public:
|
||||
/// Called when the specified player right-clicks this entity
|
||||
virtual void OnRightClicked(cPlayer & a_Player) {};
|
||||
|
||||
/// 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, cEntity * a_Killer = NULL) {}
|
||||
|
||||
protected:
|
||||
static cCriticalSection m_CSCount;
|
||||
static int m_EntityCount;
|
||||
|
||||
int m_UniqueID;
|
||||
|
||||
int m_Health;
|
||||
int m_MaxHealth;
|
||||
|
||||
/// The entity to which this entity is attached (vehicle), NULL if none
|
||||
cEntity * m_AttachedTo;
|
||||
|
||||
@ -243,8 +402,17 @@ protected:
|
||||
|
||||
cWorld * m_World;
|
||||
|
||||
float m_FireDamageInterval;
|
||||
float m_BurnPeriod;
|
||||
/// Time, in ticks, since the last damage dealt by being on fire. Valid only if on fire (IsOnFire())
|
||||
int m_TicksSinceLastBurnDamage;
|
||||
|
||||
/// Time, in ticks, since the last damage dealt by standing in lava. Reset to zero when moving out of lava.
|
||||
int m_TicksSinceLastLavaDamage;
|
||||
|
||||
/// Time, in ticks, since the last damage dealt by standing in fire. Reset to zero when moving out of fire.
|
||||
int m_TicksSinceLastFireDamage;
|
||||
|
||||
/// Time, in ticks, until the entity extinguishes its fire
|
||||
int m_TicksLeftBurning;
|
||||
|
||||
virtual void Destroyed(void) {} // Called after the entity has been destroyed
|
||||
|
||||
@ -254,22 +422,28 @@ protected:
|
||||
void AddReference( cEntity*& a_EntityPtr );
|
||||
void ReferencedBy( cEntity*& a_EntityPtr );
|
||||
void Dereference( cEntity*& a_EntityPtr );
|
||||
|
||||
private:
|
||||
//Measured in degrees (MAX 360°)
|
||||
// Measured in degrees (MAX 360°)
|
||||
double m_HeadYaw;
|
||||
//Measured in meter/second (m/s)
|
||||
// Measured in meter/second (m/s)
|
||||
Vector3d m_Speed;
|
||||
//Measured in degrees (MAX 360°)
|
||||
// Measured in degrees (MAX 360°)
|
||||
Vector3d m_Rot;
|
||||
//Measured in meters (1 meter = 1 block) (m)
|
||||
|
||||
/// Position of the entity's XZ center and Y bottom
|
||||
Vector3d m_Pos;
|
||||
//Measured in meter/second
|
||||
|
||||
// Measured in meter / second
|
||||
Vector3d m_WaterSpeed;
|
||||
//Measured in Kilograms (Kg)
|
||||
|
||||
// Measured in Kilograms (Kg)
|
||||
double m_Mass;
|
||||
//It's Width.
|
||||
|
||||
/// Width of the entity, in the XZ plane. Since entities are represented as cylinders, this is more of a diameter.
|
||||
double m_Width;
|
||||
//It's height
|
||||
|
||||
/// Height of the entity (Y axis)
|
||||
double m_Height;
|
||||
} ; // tolua_export
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
|
||||
cFallingBlock::cFallingBlock(const Vector3i & a_BlockPosition, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) :
|
||||
super(etFallingBlock, a_BlockPosition.x + 0.5f, a_BlockPosition.y + 0.5f, a_BlockPosition.z + 0.5f),
|
||||
super(etFallingBlock, a_BlockPosition.x + 0.5f, a_BlockPosition.y + 0.5f, a_BlockPosition.z + 0.5f, 0.98, 0.98),
|
||||
m_BlockType(a_BlockType),
|
||||
m_BlockMeta(a_BlockMeta),
|
||||
m_OriginalPosition(a_BlockPosition)
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) :
|
||||
super(etMinecart, a_X, a_Y, a_Z),
|
||||
super(etMinecart, a_X, a_Y, a_Z, 0.98, 0.7),
|
||||
m_Payload(a_Payload)
|
||||
{
|
||||
}
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
|
||||
|
||||
cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath) :
|
||||
super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath),
|
||||
cAggressiveMonster::cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
|
||||
super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height),
|
||||
m_ChaseTime(999999)
|
||||
{
|
||||
m_EMPersonality = AGGRESSIVE;
|
||||
|
@ -13,7 +13,7 @@ class cAggressiveMonster :
|
||||
typedef cMonster super;
|
||||
|
||||
public:
|
||||
cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
||||
cAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
|
||||
|
||||
virtual void Tick (float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void InStateChasing(float a_Dt) override;
|
||||
|
@ -14,7 +14,8 @@ class cBat :
|
||||
|
||||
public:
|
||||
cBat(void) :
|
||||
super("Bat", 65, "mob.bat.hurt", "mob.bat.death")
|
||||
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
|
||||
super("Bat", 65, "mob.bat.hurt", "mob.bat.death", 0.7, 0.7)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
|
||||
cBlaze::cBlaze(void) :
|
||||
super("Blaze", 61, "mob.blaze.hit", "mob.blaze.death")
|
||||
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
|
||||
super("Blaze", 61, "mob.blaze.hit", "mob.blaze.death", 0.7, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,7 +17,7 @@ cBlaze::cBlaze(void) :
|
||||
|
||||
|
||||
|
||||
void cBlaze::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_BLAZE_ROD);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cBlaze);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
|
||||
cCavespider::cCavespider(void) :
|
||||
super("Cavespider", 59, "mob.spider.say", "mob.spider.death")
|
||||
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
|
||||
super("Cavespider", 59, "mob.spider.say", "mob.spider.death", 0.9, 0.6)
|
||||
{
|
||||
}
|
||||
|
||||
@ -28,7 +29,7 @@ void cCavespider::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cCavespider::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cCavespider::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_STRING);
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_SPIDER_EYE);
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
CLASS_PROTODEF(cCaveSpider);
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
cChicken::cChicken(void) :
|
||||
super("Chicken", 93, "mob.chicken.hurt", "mob.chicken.hurt")
|
||||
super("Chicken", 93, "mob.chicken.hurt", "mob.chicken.hurt", 0.3, 0.4)
|
||||
{
|
||||
}
|
||||
|
||||
@ -22,10 +22,10 @@ cChicken::cChicken(void) :
|
||||
|
||||
|
||||
|
||||
void cChicken::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cChicken::GetDrops(cItems & a_Drops, cEntity * 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));
|
||||
a_Drops.push_back(cItem(IsOnFire() ? E_ITEM_COOKED_CHICKEN : E_ITEM_RAW_CHICKEN, 1));
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cChicken);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
cCow::cCow(void) :
|
||||
super("Cow", 92, "mob.cow.hurt", "mob.cow.hurt")
|
||||
super("Cow", 92, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
|
||||
{
|
||||
}
|
||||
|
||||
@ -22,10 +22,10 @@ cCow::cCow(void) :
|
||||
|
||||
|
||||
|
||||
void cCow::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_LEATHER);
|
||||
AddRandomDropItem(a_Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
|
||||
AddRandomDropItem(a_Drops, 1, 3, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cCow);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cCreeper::cCreeper(void) :
|
||||
super("Creeper", 50, "mob.creeper.say", "mob.creeper.say")
|
||||
super("Creeper", 50, "mob.creeper.say", "mob.creeper.say", 0.6, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ cCreeper::cCreeper(void) :
|
||||
|
||||
|
||||
|
||||
void cCreeper::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_GUNPOWDER);
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cCreeper);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
|
||||
cEnderman::cEnderman(void) :
|
||||
super("Enderman", 58, "mob.endermen.hit", "mob.endermen.death")
|
||||
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
|
||||
super("Enderman", 58, "mob.endermen.hit", "mob.endermen.death", 0.5, 2.5)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,7 +17,7 @@ cEnderman::cEnderman(void) :
|
||||
|
||||
|
||||
|
||||
void cEnderman::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_ENDER_PEARL);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cEnderman);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cGhast::cGhast(void) :
|
||||
super("Ghast", 56, "mob.ghast.scream", "mob.ghast.death")
|
||||
super("Ghast", 56, "mob.ghast.scream", "mob.ghast.death", 4, 4)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ cGhast::cGhast(void) :
|
||||
|
||||
|
||||
|
||||
void cGhast::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_GUNPOWDER);
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_GHAST_TEAR);
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cGhast);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -7,8 +7,9 @@
|
||||
|
||||
|
||||
|
||||
cMagmacube::cMagmacube(void) :
|
||||
super("Magmacube", 62, "mob.magmacube.big", "mob.magmacube.big")
|
||||
cMagmacube::cMagmacube(int a_Size) :
|
||||
super("Magmacube", 62, "mob.magmacube.big", "mob.magmacube.big", 0.6 * a_Size, 0.6 * a_Size),
|
||||
m_Size(a_Size)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,7 +17,7 @@ cMagmacube::cMagmacube(void) :
|
||||
|
||||
|
||||
|
||||
void cMagmacube::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cMagmacube::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_MAGMA_CREAM);
|
||||
}
|
||||
|
@ -13,11 +13,17 @@ class cMagmacube :
|
||||
typedef cAggressiveMonster super;
|
||||
|
||||
public:
|
||||
cMagmacube();
|
||||
/// Creates a magmacube of the specified size; size is 1 .. 3, with 1 being the smallest
|
||||
cMagmacube(int a_Size);
|
||||
|
||||
CLASS_PROTODEF(cMagmacube);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
|
||||
protected:
|
||||
|
||||
/// Size of the magmacube, 1 .. 3, with 1 being the smallest
|
||||
int m_Size;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
|
||||
|
||||
|
||||
cMonster::cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath)
|
||||
: super(etMob)
|
||||
cMonster::cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height)
|
||||
: super(etMob, a_Width, a_Height)
|
||||
, m_Target(NULL)
|
||||
, m_bMovingToDestination(false)
|
||||
, m_DestinationTime( 0 )
|
||||
@ -204,10 +204,13 @@ void cMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||
|
||||
|
||||
|
||||
void cMonster::KilledBy(cPawn * a_Killer)
|
||||
void cMonster::KilledBy(cEntity * a_Killer)
|
||||
{
|
||||
super::KilledBy(a_Killer);
|
||||
if(m_SoundHurt != "") m_World->BroadcastSoundEffect(m_SoundDeath, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f);
|
||||
if (m_SoundHurt != "")
|
||||
{
|
||||
m_World->BroadcastSoundEffect(m_SoundDeath, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f);
|
||||
}
|
||||
m_DestroyTimer = 0;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ public:
|
||||
* a_ProtocolMobType is the ID of the mob used in the protocol ( http://wiki.vg/Entities#Mobs , 2012_12_22)
|
||||
* a_SoundHurt and a_SoundDeath are assigned into m_SoundHurt and m_SoundDeath, respectively
|
||||
*/
|
||||
cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
||||
cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
|
||||
|
||||
CLASS_PROTODEF(cMonster);
|
||||
|
||||
@ -41,7 +41,7 @@ public:
|
||||
|
||||
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
||||
|
||||
virtual void KilledBy(cPawn * a_Killer) override;
|
||||
virtual void KilledBy(cEntity * a_Killer) override;
|
||||
|
||||
virtual void MoveToPosition(const Vector3f & a_Position);
|
||||
virtual bool ReachedDestination(void);
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
|
||||
cMooshroom::cMooshroom(void) :
|
||||
super("Mooshroom", 96, "mob.cow.hurt", "mob.cow.hurt")
|
||||
super("Mooshroom", 96, "mob.cow.hurt", "mob.cow.hurt", 0.9, 1.3)
|
||||
{
|
||||
}
|
||||
|
||||
@ -22,10 +22,10 @@ cMooshroom::cMooshroom(void) :
|
||||
|
||||
|
||||
|
||||
void cMooshroom::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_LEATHER);
|
||||
AddRandomDropItem(a_Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
|
||||
AddRandomDropItem(a_Drops, 1, 3, IsOnFire() ? E_ITEM_STEAK : E_ITEM_RAW_BEEF);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cMooshroom);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -14,7 +14,8 @@ class cOcelot :
|
||||
|
||||
public:
|
||||
cOcelot(void) :
|
||||
super("Ocelot", 98, "mob.cat.hitt", "mob.cat.hitt")
|
||||
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
|
||||
super("Ocelot", 98, "mob.cat.hitt", "mob.cat.hitt", 0.9, 0.5)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
|
||||
|
||||
|
||||
cPassiveAggressiveMonster::cPassiveAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath) :
|
||||
super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath)
|
||||
cPassiveAggressiveMonster::cPassiveAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
|
||||
super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height)
|
||||
{
|
||||
m_EMPersonality = PASSIVE;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class cPassiveAggressiveMonster :
|
||||
typedef cAggressiveMonster super;
|
||||
|
||||
public:
|
||||
cPassiveAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
||||
cPassiveAggressiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
|
||||
|
||||
virtual void DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
||||
} ;
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
|
||||
cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath) :
|
||||
super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath)
|
||||
cPassiveMonster::cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height) :
|
||||
super(a_ConfigName, a_ProtocolMobType, a_SoundHurt, a_SoundDeath, a_Width, a_Height)
|
||||
{
|
||||
m_EMPersonality = PASSIVE;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class cPassiveMonster :
|
||||
typedef cMonster super;
|
||||
|
||||
public:
|
||||
cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath);
|
||||
cPassiveMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height);
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cPig::cPig(void) :
|
||||
super("Pig", 90, "mob.pig.say", "mob.pig.death")
|
||||
super("Pig", 90, "mob.pig.say", "mob.pig.death", 0.9, 0.9)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,9 +16,9 @@ cPig::cPig(void) :
|
||||
|
||||
|
||||
|
||||
void cPig::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cPig::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 1, 3, (GetMetaData() == BURNING) ? E_ITEM_COOKED_PORKCHOP : E_ITEM_RAW_PORKCHOP);
|
||||
AddRandomDropItem(a_Drops, 1, 3, IsOnFire() ? E_ITEM_COOKED_PORKCHOP : E_ITEM_RAW_PORKCHOP);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cPig);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
cSheep::cSheep(void) :
|
||||
super("Sheep", 91, "mob.sheep.say", "mob.sheep.say"),
|
||||
super("Sheep", 91, "mob.sheep.say", "mob.sheep.say", 0.6, 1.3),
|
||||
m_IsSheared(false),
|
||||
m_WoolColor(E_META_WOOL_WHITE)
|
||||
{
|
||||
@ -19,7 +19,7 @@ cSheep::cSheep(void) :
|
||||
|
||||
|
||||
|
||||
void cSheep::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
if (!m_IsSheared)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cSheep);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -14,7 +14,8 @@ class cSilverfish :
|
||||
|
||||
public:
|
||||
cSilverfish(void) :
|
||||
super("Silverfish", 60, "mob.silverfish.hit", "mob.silverfish.kill")
|
||||
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here
|
||||
super("Silverfish", 60, "mob.silverfish.hit", "mob.silverfish.kill", 0.9, 0.3)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cSkeleton::cSkeleton(void) :
|
||||
super("Skeleton", 51, "mob.skeleton.hurt", "mob.skeleton.death")
|
||||
super("Skeleton", 51, "mob.skeleton.hurt", "mob.skeleton.death", 0.6, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
@ -22,9 +22,10 @@ void cSkeleton::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
// TODO Outsource
|
||||
// TODO should do SkyLight check, mobs in the dark don´t burn
|
||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsBurning())
|
||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsOnFire())
|
||||
{
|
||||
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
||||
// Burn for 10 ticks, then decide again
|
||||
StartBurning(10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +33,7 @@ void cSkeleton::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cSkeleton::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_ARROW);
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_BONE);
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
CLASS_PROTODEF(cSkeleton);
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -9,8 +9,10 @@
|
||||
|
||||
|
||||
|
||||
cSlime::cSlime(void) :
|
||||
super("Slime", 55, "mob.slime.attack", "mob.slime.attack")
|
||||
/// Creates a slime of the specified size; size is 1 .. 3, with 1 being the smallest
|
||||
cSlime::cSlime(int a_Size) :
|
||||
super("Slime", 55, "mob.slime.attack", "mob.slime.attack", 0.6 * a_Size, 0.6 * a_Size),
|
||||
m_Size(a_Size)
|
||||
{
|
||||
}
|
||||
|
||||
@ -18,7 +20,7 @@ cSlime::cSlime(void) :
|
||||
|
||||
|
||||
|
||||
void cSlime::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cSlime::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
// TODO: only when tiny
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_SLIMEBALL);
|
||||
|
@ -13,11 +13,17 @@ class cSlime :
|
||||
typedef cAggressiveMonster super;
|
||||
|
||||
public:
|
||||
cSlime(void);
|
||||
/// Creates a slime of the specified size; size is 1 .. 3, with 1 being the smallest
|
||||
cSlime(int a_Size);
|
||||
|
||||
CLASS_PROTODEF(cSlime);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
|
||||
protected:
|
||||
|
||||
/// Size of the slime, 1 .. 3, with 1 being the smallest
|
||||
int m_Size;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cSpider::cSpider(void) :
|
||||
super("Spider", 52, "mob.spider.say", "mob.spider.death")
|
||||
super("Spider", 52, "mob.spider.say", "mob.spider.death", 1.4, 0.9)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ cSpider::cSpider(void) :
|
||||
|
||||
|
||||
|
||||
void cSpider::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_STRING);
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_SPIDER_EYE);
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cSpider);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -3,13 +3,14 @@
|
||||
|
||||
#include "Squid.h"
|
||||
#include "../Vector3d.h"
|
||||
#include "../Chunk.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cSquid::cSquid(void) :
|
||||
super("Squid", 94, "", "")
|
||||
super("Squid", 94, "", "", 0.95, 0.95)
|
||||
{
|
||||
}
|
||||
|
||||
@ -17,7 +18,7 @@ cSquid::cSquid(void) :
|
||||
|
||||
|
||||
|
||||
void cSquid::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cSquid::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
// Drops 0-3 Ink Sacs
|
||||
AddRandomDropItem(a_Drops, 0, 3, E_ITEM_DYE, E_META_DYE_BLACK);
|
||||
@ -29,15 +30,17 @@ void cSquid::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
|
||||
void cSquid::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
// TODO: Rewrite this function to use a_Chunk instead of m_World
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
|
||||
Vector3d Pos = GetPosition();
|
||||
|
||||
// TODO: Not a real behavior, but cool :D
|
||||
if (!IsBlockWater(GetWorld()->GetBlock((int) Pos.x, (int) Pos.y, (int) Pos.z)) && !IsBurning())
|
||||
int RelX = (int)floor(Pos.x + 0.5) - a_Chunk.GetPosX() * cChunkDef::Width;
|
||||
int RelZ = (int)floor(Pos.z + 0.5) - a_Chunk.GetPosZ() * cChunkDef::Width;
|
||||
if (!IsBlockWater(a_Chunk.GetBlock(RelX, (int)Pos.y, RelZ)) && !IsOnFire())
|
||||
{
|
||||
SetMetaData(BURNING);
|
||||
// Burn for 10 ticks, then decide again
|
||||
StartBurning(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cSquid);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cVillager::cVillager(void) :
|
||||
super("Villager", 120, "", "")
|
||||
super("Villager", 120, "", "", 0.6, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cWitch::cWitch(void) :
|
||||
super("Witch", 66, "", "")
|
||||
super("Witch", 66, "", "", 0.6, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ cWitch::cWitch(void) :
|
||||
|
||||
|
||||
|
||||
void cWitch::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cWitch::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_GLASS_BOTTLE);
|
||||
AddRandomDropItem(a_Drops, 0, 6, E_ITEM_GLOWSTONE_DUST);
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cWitch);
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -14,7 +14,8 @@ class cWolf :
|
||||
|
||||
public:
|
||||
cWolf(void) :
|
||||
super("Wolf", 95, "mob.wolf.hurt", "mob.wolf.death")
|
||||
// TODO: The size is only a guesstimate, measure in vanilla and fix the size values here (wiki.vg values are suspicious)
|
||||
super("Wolf", 95, "mob.wolf.hurt", "mob.wolf.death", 0.9, 0.9)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cZombie::cZombie(void) :
|
||||
super("Zombie", 54, "mob.zombie.hurt", "mob.zombie.death")
|
||||
super("Zombie", 54, "mob.zombie.hurt", "mob.zombie.death", 0.6, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
@ -21,9 +21,10 @@ void cZombie::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
|
||||
// TODO Same as in cSkeleton :D
|
||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsBurning())
|
||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsOnFire())
|
||||
{
|
||||
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
||||
// Burn for 10 ticks, then decide again
|
||||
StartBurning(10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +32,7 @@ void cZombie::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cZombie::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cZombie::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 2, E_ITEM_ROTTEN_FLESH);
|
||||
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
CLASS_PROTODEF(cZombie);
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
cZombiepigman::cZombiepigman(void) :
|
||||
super("Zombiepigman", 57, "mob.zombiepig.zpighurt", "mob.zombiepig.zpigdeath")
|
||||
super("Zombiepigman", 57, "mob.zombiepig.zpighurt", "mob.zombiepig.zpigdeath", 0.6, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
@ -21,9 +21,10 @@ void cZombiepigman::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
|
||||
// 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)) && !IsBurning())
|
||||
if ((GetWorld()->GetTimeOfDay() < (12000 + 1000)) && !IsOnFire())
|
||||
{
|
||||
SetMetaData(BURNING); // BURN, BABY, BURN! >:D
|
||||
// Burn for 10 ticks, then decide again
|
||||
StartBurning(10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +32,7 @@ void cZombiepigman::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
void cZombiepigman::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
void cZombiepigman::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_ROTTEN_FLESH);
|
||||
AddRandomDropItem(a_Drops, 0, 1, E_ITEM_GOLD_NUGGET);
|
||||
@ -43,7 +44,7 @@ void cZombiepigman::GetDrops(cItems & a_Drops, cPawn * a_Killer)
|
||||
|
||||
|
||||
|
||||
void cZombiepigman::KilledBy(cPawn * a_Killer)
|
||||
void cZombiepigman::KilledBy(cEntity * a_Killer)
|
||||
{
|
||||
super::KilledBy(a_Killer);
|
||||
|
||||
|
@ -18,8 +18,8 @@ public:
|
||||
CLASS_PROTODEF(cZombiepigman);
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cPawn * a_Killer = NULL) override;
|
||||
virtual void KilledBy(cPawn * a_Killer) override;
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override;
|
||||
virtual void KilledBy(cEntity * a_Killer) override;
|
||||
} ;
|
||||
|
||||
|
||||
|
378
source/Pawn.cpp
378
source/Pawn.cpp
@ -15,12 +15,9 @@
|
||||
|
||||
|
||||
|
||||
cPawn::cPawn(eEntityType a_EntityType)
|
||||
: cEntity(a_EntityType, 0, 0, 0)
|
||||
, m_Health(1)
|
||||
, m_MaxHealth(1)
|
||||
cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height)
|
||||
: cEntity(a_EntityType, 0, 0, 0, a_Width, a_Height)
|
||||
, m_bBurnable(true)
|
||||
, m_MetaData(NORMAL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -28,374 +25,3 @@ cPawn::cPawn(eEntityType a_EntityType)
|
||||
|
||||
|
||||
|
||||
void cPawn::Heal(int a_HitPoints)
|
||||
{
|
||||
m_Health += a_HitPoints;
|
||||
if (m_Health > m_MaxHealth)
|
||||
{
|
||||
m_Health = m_MaxHealth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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.DamageType = a_DamageType;
|
||||
TDI.Attacker = a_Attacker;
|
||||
TDI.RawDamage = a_RawDamage;
|
||||
TDI.FinalDamage = a_FinalDamage;
|
||||
Vector3d Heading;
|
||||
Heading.x = sin(GetRotation());
|
||||
Heading.y = 0.4; // TODO: adjust the amount of "up" knockback when testing
|
||||
Heading.z = cos(GetRotation());
|
||||
TDI.Knockback = Heading * a_KnockbackAmount;
|
||||
DoTakeDamage(TDI);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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)a_TDI.FinalDamage;
|
||||
|
||||
// TODO: Apply damage to armor
|
||||
|
||||
if (m_Health < 0)
|
||||
{
|
||||
m_Health = 0;
|
||||
}
|
||||
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_HURT);
|
||||
|
||||
if (m_Health <= 0)
|
||||
{
|
||||
KilledBy(a_TDI.Attacker);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPawn::KilledBy(cPawn * a_Killer)
|
||||
{
|
||||
m_Health = 0;
|
||||
|
||||
cRoot::Get()->GetPluginManager()->CallHookKilling(*this, a_Killer);
|
||||
|
||||
if (m_Health > 0)
|
||||
{
|
||||
// Plugin wants to 'unkill' the pawn. Abort
|
||||
return;
|
||||
}
|
||||
|
||||
// Drop loot:
|
||||
cItems Drops;
|
||||
GetDrops(Drops, a_Killer);
|
||||
m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ());
|
||||
|
||||
m_World->BroadcastEntityStatus(*this, ENTITY_STATUS_DEAD);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cPawn::GetRawDamageAgainst(const cPawn & a_Receiver)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cPawn::GetArmorCoverAgainst(const cPawn * a_Attacker, eDamageType a_DamageType, int a_Damage)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPawn::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
CheckMetaDataBurn(a_Chunk); // Check to see if pawn should burn based on block they are on
|
||||
|
||||
if (IsBurning())
|
||||
{
|
||||
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(cChunk & a_Chunk)
|
||||
{
|
||||
// TODO: Rewrite this function to use a_Chunk instead of m_World
|
||||
|
||||
if ((GetPosY() < 1) || (GetPosY() >= 254))
|
||||
{
|
||||
// Y coord out of range
|
||||
return;
|
||||
}
|
||||
|
||||
BLOCKTYPE Block = GetWorld()->GetBlock((int) GetPosX(), (int) GetPosY(), (int) GetPosZ());
|
||||
BLOCKTYPE BlockAbove = GetWorld()->GetBlock((int) GetPosX(), (int) GetPosY() + 1, (int) GetPosZ());
|
||||
BLOCKTYPE BlockBelow = GetWorld()->GetBlock((int) GetPosX(), (int) GetPosY() - 1, (int) GetPosZ());
|
||||
|
||||
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;
|
||||
if (m_FireDamageInterval < 800)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BLOCKTYPE Block = GetWorld()->GetBlock((int)GetPosX(), (int)GetPosY(), (int)GetPosZ());
|
||||
BLOCKTYPE BlockAbove = GetWorld()->GetBlock((int)GetPosX(), (int)GetPosY() + 1, (int)GetPosZ());
|
||||
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(dtLavaContact, NULL, 6, 0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
149
source/Pawn.h
149
source/Pawn.h
@ -8,71 +8,6 @@
|
||||
|
||||
|
||||
|
||||
// fwd:
|
||||
class cPawn;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 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,
|
||||
dtAdmin, // Damage applied by an admin command
|
||||
|
||||
// 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,
|
||||
dtPlugin = dtAdmin,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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
|
||||
@ -83,91 +18,11 @@ class cPawn :
|
||||
public:
|
||||
CLASS_PROTODEF(cPawn);
|
||||
|
||||
cPawn(eEntityType a_EntityType);
|
||||
|
||||
virtual void Tick(float a_Dt, cChunk & a_Chunk) override;
|
||||
|
||||
// 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};
|
||||
|
||||
virtual void SetMetaData(MetaData a_MetaData);
|
||||
virtual MetaData GetMetaData(void) const { return m_MetaData; }
|
||||
|
||||
virtual void InStateBurning(float a_Dt);
|
||||
|
||||
virtual void CheckMetaDataBurn(cChunk & a_Chunk);
|
||||
|
||||
virtual void SetMaxHealth(short a_MaxHealth);
|
||||
virtual short GetMaxHealth() { return m_MaxHealth; }
|
||||
|
||||
bool IsBurning(void) const { return (m_MetaData == BURNING); }
|
||||
cPawn(eEntityType a_EntityType, double a_Width, double a_Height);
|
||||
|
||||
protected:
|
||||
short m_Health;
|
||||
short m_MaxHealth;
|
||||
|
||||
bool m_bBurnable;
|
||||
|
||||
MetaData m_MetaData;
|
||||
|
||||
}; // tolua_export
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
|
||||
cPickup::cPickup(int a_MicroPosX, int a_MicroPosY, int a_MicroPosZ, const cItem & a_Item, float a_SpeedX /* = 0.f */, float a_SpeedY /* = 0.f */, float a_SpeedZ /* = 0.f */)
|
||||
: cEntity(etPickup, ((double)(a_MicroPosX)) / 32, ((double)(a_MicroPosY)) / 32, ((double)(a_MicroPosZ)) / 32)
|
||||
: cEntity(etPickup, ((double)(a_MicroPosX)) / 32, ((double)(a_MicroPosY)) / 32, ((double)(a_MicroPosZ)) / 32, 0.2, 0.2)
|
||||
, m_Health(5)
|
||||
, m_Timer( 0.f )
|
||||
, m_Item(a_Item)
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
|
||||
cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
|
||||
: super(etPlayer)
|
||||
: super(etPlayer, 0.6, 1.8)
|
||||
, m_GameMode(eGameMode_NotSet)
|
||||
, m_IP("")
|
||||
, m_LastBlockActionTime( 0 )
|
||||
@ -197,7 +197,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
|
||||
}
|
||||
else if (m_FoodLevel == 0)
|
||||
{
|
||||
super::TakeDamage(dtStarving, NULL, 1, 1, 0);
|
||||
TakeDamage(dtStarving, NULL, 1, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
|
||||
m_LastJumpHeight = (float)GetPosY();
|
||||
if (Damage > 0)
|
||||
{
|
||||
super::TakeDamage(dtFalling, NULL, Damage, Damage, 0);
|
||||
TakeDamage(dtFalling, NULL, Damage, Damage, 0);
|
||||
}
|
||||
|
||||
m_LastGroundHeight = (float)GetPosY();
|
||||
@ -396,9 +396,9 @@ void cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||
|
||||
|
||||
|
||||
void cPlayer::KilledBy(cPawn * a_Killer)
|
||||
void cPlayer::KilledBy(cEntity * a_Killer)
|
||||
{
|
||||
cPawn::KilledBy(a_Killer);
|
||||
super::KilledBy(a_Killer);
|
||||
|
||||
if (m_Health > 0)
|
||||
{
|
||||
@ -425,10 +425,10 @@ void cPlayer::Respawn(void)
|
||||
|
||||
m_ClientHandle->SendRespawn();
|
||||
|
||||
// Set non Burning
|
||||
SetMetaData(NORMAL);
|
||||
// Extinguish the fire:
|
||||
StopBurning();
|
||||
|
||||
TeleportTo(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ());
|
||||
TeleportToCoords(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ());
|
||||
|
||||
SetVisible(true);
|
||||
}
|
||||
@ -437,12 +437,15 @@ void cPlayer::Respawn(void)
|
||||
|
||||
|
||||
|
||||
double cPlayer::GetEyeHeight()
|
||||
double cPlayer::GetEyeHeight(void) const
|
||||
{
|
||||
return m_Stance;
|
||||
}
|
||||
|
||||
Vector3d cPlayer::GetEyePosition()
|
||||
|
||||
|
||||
|
||||
Vector3d cPlayer::GetEyePosition(void) const
|
||||
{
|
||||
return Vector3d( GetPosX(), m_Stance, GetPosZ() );
|
||||
}
|
||||
@ -574,7 +577,7 @@ void cPlayer::SendMessage(const AString & a_Message)
|
||||
|
||||
|
||||
|
||||
void cPlayer::TeleportTo(double a_PosX, double a_PosY, double a_PosZ)
|
||||
void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
||||
{
|
||||
SetPosition( a_PosX, a_PosY, a_PosZ );
|
||||
|
||||
|
@ -61,8 +61,8 @@ public:
|
||||
|
||||
void SetTouchGround( bool a_bTouchGround );
|
||||
inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; }
|
||||
double GetEyeHeight(); // tolua_export
|
||||
Vector3d GetEyePosition(); // tolua_export
|
||||
double GetEyeHeight(void) const; // tolua_export
|
||||
Vector3d GetEyePosition(void) const; // tolua_export
|
||||
inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export
|
||||
inline const double GetStance(void) const { return GetPosY() + 1.62; } // tolua_export // TODO: Proper stance when crouching etc.
|
||||
inline cInventory & GetInventory(void) { return m_Inventory; } // tolua_export
|
||||
@ -70,7 +70,7 @@ public:
|
||||
|
||||
inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); } // tolua_export
|
||||
|
||||
virtual void TeleportTo(double a_PosX, double a_PosY, double a_PosZ) override;
|
||||
virtual void TeleportToCoords(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
|
||||
@ -138,7 +138,7 @@ public:
|
||||
|
||||
void AddFoodExhaustion(float a_Exhaustion) { m_FoodExhaustionLevel += a_Exhaustion; } // tolua_export
|
||||
|
||||
virtual void KilledBy(cPawn * a_Killer) override;
|
||||
virtual void KilledBy(cEntity * a_Killer) override;
|
||||
|
||||
void Respawn(void); // tolua_export
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "Plugin.h"
|
||||
#include "Pawn.h"
|
||||
// #include "Pawn.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
#include "CommandOutput.h"
|
||||
@ -187,7 +187,7 @@ bool cPlugin::OnHandshake(cClientHandle * a_Client, const AString & a_Username)
|
||||
|
||||
|
||||
|
||||
bool cPlugin::OnKilling(cPawn & a_Victim, cEntity * a_Killer)
|
||||
bool cPlugin::OnKilling(cEntity & a_Victim, cEntity * a_Killer)
|
||||
{
|
||||
UNUSED(a_Victim);
|
||||
UNUSED(a_Killer);
|
||||
@ -468,9 +468,9 @@ bool cPlugin::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Gr
|
||||
|
||||
|
||||
|
||||
bool cPlugin::OnTakeDamage(cPawn & a_Pawn, TakeDamageInfo & a_TakeDamageInfo)
|
||||
bool cPlugin::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TakeDamageInfo)
|
||||
{
|
||||
UNUSED(a_Pawn);
|
||||
UNUSED(a_Receiver);
|
||||
UNUSED(a_TakeDamageInfo);
|
||||
return false;
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ class cPlayer;
|
||||
class cPickup;
|
||||
class cItem;
|
||||
class cEntity;
|
||||
class cPawn;
|
||||
class cWorld;
|
||||
class cChunkDesc;
|
||||
struct TakeDamageInfo;
|
||||
@ -60,7 +59,7 @@ public:
|
||||
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason);
|
||||
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split);
|
||||
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username);
|
||||
virtual bool OnKilling (cPawn & a_Victim, cEntity * a_Killer);
|
||||
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer);
|
||||
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
|
||||
virtual bool OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
@ -80,7 +79,7 @@ public:
|
||||
virtual bool OnPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
|
||||
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 bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo);
|
||||
virtual bool OnTakeDamage (cEntity & 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);
|
||||
|
@ -447,7 +447,7 @@ bool cPluginManager::CallHookHandshake(cClientHandle * a_ClientHandle, const ASt
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookKilling(cPawn & a_Victim, cEntity * a_Killer)
|
||||
bool cPluginManager::CallHookKilling(cEntity & a_Victim, cEntity * a_Killer)
|
||||
{
|
||||
HookMap::iterator Plugins = m_Hooks.find(HOOK_KILLING);
|
||||
if (Plugins == m_Hooks.end())
|
||||
@ -867,7 +867,7 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::CallHookTakeDamage(cPawn & a_Receiver, TakeDamageInfo & a_TDI)
|
||||
bool cPluginManager::CallHookTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI)
|
||||
{
|
||||
HookMap::iterator Plugins = m_Hooks.find(HOOK_TAKE_DAMAGE);
|
||||
if (Plugins == m_Hooks.end())
|
||||
|
@ -126,7 +126,7 @@ public: // tolua_export
|
||||
bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason);
|
||||
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split); // If a_Player == NULL, it is a console cmd
|
||||
bool CallHookHandshake (cClientHandle * a_ClientHandle, const AString & a_Username);
|
||||
bool CallHookKilling (cPawn & a_Victim, cEntity * a_Killer);
|
||||
bool CallHookKilling (cEntity & a_Victim, cEntity * a_Killer);
|
||||
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
|
||||
bool CallHookPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
bool CallHookPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);
|
||||
@ -146,7 +146,7 @@ public: // tolua_export
|
||||
bool CallHookPlayerUsingItem (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ);
|
||||
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 CallHookTakeDamage (cEntity & 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);
|
||||
|
@ -549,7 +549,7 @@ bool cPlugin_NewLua::OnHandshake(cClientHandle * a_Client, const AString & a_Use
|
||||
|
||||
|
||||
|
||||
bool cPlugin_NewLua::OnKilling(cPawn & a_Victim, cEntity * a_Killer)
|
||||
bool cPlugin_NewLua::OnKilling(cEntity & a_Victim, cEntity * a_Killer)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
const char * FnName = GetHookFnName(cPluginManager::HOOK_KILLING);
|
||||
@ -559,7 +559,7 @@ bool cPlugin_NewLua::OnKilling(cPawn & a_Victim, cEntity * a_Killer)
|
||||
return false;
|
||||
}
|
||||
|
||||
tolua_pushusertype(m_LuaState, &a_Victim, "cPawn");
|
||||
tolua_pushusertype(m_LuaState, &a_Victim, "cEntity");
|
||||
tolua_pushusertype(m_LuaState, a_Killer, "cEntity");
|
||||
|
||||
if (!CallFunction(2, 1, FnName))
|
||||
@ -1150,7 +1150,7 @@ bool cPlugin_NewLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid
|
||||
|
||||
|
||||
|
||||
bool cPlugin_NewLua::OnTakeDamage(cPawn & a_Receiver, TakeDamageInfo & a_TDI)
|
||||
bool cPlugin_NewLua::OnTakeDamage(cEntity & a_Receiver, TakeDamageInfo & a_TDI)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
const char * FnName = GetHookFnName(cPluginManager::HOOK_TAKE_DAMAGE);
|
||||
@ -1160,7 +1160,7 @@ bool cPlugin_NewLua::OnTakeDamage(cPawn & a_Receiver, TakeDamageInfo & a_TDI)
|
||||
return false;
|
||||
}
|
||||
|
||||
tolua_pushusertype(m_LuaState, &a_Receiver, "cPawn");
|
||||
tolua_pushusertype(m_LuaState, &a_Receiver, "cEntity");
|
||||
tolua_pushusertype(m_LuaState, &a_TDI, "TakeDamageInfo");
|
||||
|
||||
if (!CallFunction(2, 1, FnName))
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override;
|
||||
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split) override;
|
||||
virtual bool OnHandshake (cClientHandle * a_Client, const AString & a_Username) override;
|
||||
virtual bool OnKilling (cPawn & a_Victim, cEntity * a_Killer) override;
|
||||
virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer) override;
|
||||
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
|
||||
virtual bool OnPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
virtual bool OnPlayerBrokenBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||
@ -69,7 +69,7 @@ public:
|
||||
virtual bool OnPlayerUsingItem (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;
|
||||
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 bool OnTakeDamage (cPawn & a_Receiver, TakeDamageInfo & a_TakeDamageInfo) override;
|
||||
virtual bool OnTakeDamage (cEntity & 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;
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, float a_FuseTimeInSec) :
|
||||
super(etTNT, a_X, a_Y, a_Z),
|
||||
super(etTNT, a_X, a_Y, a_Z, 0.98, 0.98),
|
||||
m_Counter(0),
|
||||
m_MaxFuseTime(a_FuseTimeInSec)
|
||||
{
|
||||
@ -20,7 +20,7 @@ cTNTEntity::cTNTEntity(double a_X, double a_Y, double a_Z, float a_FuseTimeInSec
|
||||
|
||||
|
||||
cTNTEntity::cTNTEntity(const Vector3d & a_Pos, float a_FuseTimeInSec) :
|
||||
super(etTNT, a_Pos.x, a_Pos.y, a_Pos.z),
|
||||
super(etTNT, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98),
|
||||
m_Counter(0),
|
||||
m_MaxFuseTime(a_FuseTimeInSec)
|
||||
{
|
||||
|
@ -1523,9 +1523,9 @@ void cWorld::BroadcastEntityStatus(const cEntity & a_Entity, char a_Status, cons
|
||||
|
||||
|
||||
|
||||
void cWorld::BroadcastMetadata(const cPawn & a_Pawn, const cClientHandle * a_Exclude)
|
||||
void cWorld::BroadcastMetadata(const cEntity & a_Entity, const cClientHandle * a_Exclude)
|
||||
{
|
||||
m_ChunkMap->BroadcastMetadata(a_Pawn, a_Exclude);
|
||||
m_ChunkMap->BroadcastMetadata(a_Entity, a_Exclude);
|
||||
}
|
||||
|
||||
|
||||
@ -2317,31 +2317,33 @@ int cWorld::SpawnMob(double a_PosX, double a_PosY, double a_PosZ, int a_EntityTy
|
||||
{
|
||||
cMonster * Monster = NULL;
|
||||
|
||||
int Size = GetTickRandomNumber(2) + 1; // 1 .. 3
|
||||
|
||||
switch (a_EntityType)
|
||||
{
|
||||
case E_ENTITY_TYPE_BAT: Monster = new cBat(); break;
|
||||
case E_ENTITY_TYPE_BLAZE: Monster = new cBlaze(); break;
|
||||
case E_ENTITY_TYPE_CAVE_SPIDER: Monster = new cCavespider(); break;
|
||||
case E_ENTITY_TYPE_CHICKEN: Monster = new cChicken(); break;
|
||||
case E_ENTITY_TYPE_COW: Monster = new cCow(); break;
|
||||
case E_ENTITY_TYPE_CREEPER: Monster = new cCreeper(); break;
|
||||
case E_ENTITY_TYPE_ENDERMAN: Monster = new cEnderman(); break;
|
||||
case E_ENTITY_TYPE_GHAST: Monster = new cGhast(); break;
|
||||
case E_ENTITY_TYPE_MAGMA_CUBE: Monster = new cMagmacube(); break;
|
||||
case E_ENTITY_TYPE_MOOSHROOM: Monster = new cMooshroom(); break;
|
||||
case E_ENTITY_TYPE_OCELOT: Monster = new cOcelot(); break;
|
||||
case E_ENTITY_TYPE_PIG: Monster = new cPig(); break;
|
||||
case E_ENTITY_TYPE_SHEEP: Monster = new cSheep(); break;
|
||||
case E_ENTITY_TYPE_SILVERFISH: Monster = new cSilverfish(); break;
|
||||
case E_ENTITY_TYPE_SKELETON: Monster = new cSkeleton(); break;
|
||||
case E_ENTITY_TYPE_SLIME: Monster = new cSlime(); break;
|
||||
case E_ENTITY_TYPE_SPIDER: Monster = new cSpider(); break;
|
||||
case E_ENTITY_TYPE_SQUID: Monster = new cSquid(); break;
|
||||
case E_ENTITY_TYPE_VILLAGER: Monster = new cVillager(); break;
|
||||
case E_ENTITY_TYPE_WITCH: Monster = new cWitch(); break;
|
||||
case E_ENTITY_TYPE_WOLF: Monster = new cWolf(); break;
|
||||
case E_ENTITY_TYPE_ZOMBIE: Monster = new cZombie(); break;
|
||||
case E_ENTITY_TYPE_ZOMBIE_PIGMAN: Monster = new cZombiepigman(); break;
|
||||
case E_ENTITY_TYPE_BAT: Monster = new cBat(); break;
|
||||
case E_ENTITY_TYPE_BLAZE: Monster = new cBlaze(); break;
|
||||
case E_ENTITY_TYPE_CAVE_SPIDER: Monster = new cCavespider(); break;
|
||||
case E_ENTITY_TYPE_CHICKEN: Monster = new cChicken(); break;
|
||||
case E_ENTITY_TYPE_COW: Monster = new cCow(); break;
|
||||
case E_ENTITY_TYPE_CREEPER: Monster = new cCreeper(); break;
|
||||
case E_ENTITY_TYPE_ENDERMAN: Monster = new cEnderman(); break;
|
||||
case E_ENTITY_TYPE_GHAST: Monster = new cGhast(); break;
|
||||
case E_ENTITY_TYPE_MAGMA_CUBE: Monster = new cMagmacube(Size); break;
|
||||
case E_ENTITY_TYPE_MOOSHROOM: Monster = new cMooshroom(); break;
|
||||
case E_ENTITY_TYPE_OCELOT: Monster = new cOcelot(); break;
|
||||
case E_ENTITY_TYPE_PIG: Monster = new cPig(); break;
|
||||
case E_ENTITY_TYPE_SHEEP: Monster = new cSheep(); break;
|
||||
case E_ENTITY_TYPE_SILVERFISH: Monster = new cSilverfish(); break;
|
||||
case E_ENTITY_TYPE_SKELETON: Monster = new cSkeleton(); break;
|
||||
case E_ENTITY_TYPE_SLIME: Monster = new cSlime(Size); break;
|
||||
case E_ENTITY_TYPE_SPIDER: Monster = new cSpider(); break;
|
||||
case E_ENTITY_TYPE_SQUID: Monster = new cSquid(); break;
|
||||
case E_ENTITY_TYPE_VILLAGER: Monster = new cVillager(); break;
|
||||
case E_ENTITY_TYPE_WITCH: Monster = new cWitch(); break;
|
||||
case E_ENTITY_TYPE_WOLF: Monster = new cWolf(); break;
|
||||
case E_ENTITY_TYPE_ZOMBIE: Monster = new cZombie(); break;
|
||||
case E_ENTITY_TYPE_ZOMBIE_PIGMAN: Monster = new cZombiepigman(); break;
|
||||
|
||||
default:
|
||||
{
|
||||
|
@ -133,7 +133,7 @@ public:
|
||||
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastMetadata (const cPawn & a_Pawn, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastMetadata (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastSpawn (cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastCollectPickup (const cPickup & a_Pickup, const cPlayer & a_Player, const cClientHandle * a_Exclude = NULL);
|
||||
void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user