Merge devel into master (#78)

* * Turn survival back on for now.

* * Add TP command.

* * Fix fall damage reset.

* * Mob hitting works.

I've disabled entity shading though. Will get back to it at some point, promise!

* * Knockback

* * Mobs now rotate when they die.

* * Fire fix
This commit is contained in:
iProgramInCpp
2023-09-17 12:47:09 +03:00
committed by GitHub
parent e9b00e6ba1
commit 350100ac48
15 changed files with 225 additions and 8 deletions

View File

@@ -602,6 +602,9 @@ void Entity::reset()
field_5C = m_yaw;
field_60 = m_pitch;
m_bRemoved = false;
m_distanceFallen = 0.0f;
field_D5 = false;
field_C0 = 0;
}
void Entity::interpolateTurn(float yaw, float pitch)

View File

@@ -67,6 +67,13 @@ Mob::Mob(Level* pLevel) : Entity(pLevel)
field_E0 = Mth::random() * 12398.0f;
m_yaw = float(Mth::random() * M_PI);
field_A8 = 0.5f;
// @TEST TEST TEST
field_C8 = RENDER_HUMANOID;
field_F0 = true;
// @TEST TEST TEST
}
Mob::~Mob()
@@ -332,6 +339,26 @@ bool Mob::hurt(Entity *pAttacker, int damage)
actuallyHurt(damage);
field_108 = 10;
field_104 = 10;
// not in 0.1
markHurt();
if (pAttacker)
{
float xd = pAttacker->m_pos.x - m_pos.x;
float zd = pAttacker->m_pos.z - m_pos.z;
while (zd * zd + xd * xd < 0.0001f)
{
xd = 0.01f * (Mth::random() - Mth::random());
zd = 0.01f * (Mth::random() - Mth::random());
}
float ang = atan2f(zd, xd);
v020_field_104 = ang * (180.0f / float(M_PI)) - m_yaw;
knockback(pAttacker, damage, xd, zd);
}
}
else
{
@@ -758,7 +785,69 @@ void Mob::jumpFromGround()
void Mob::updateAi()
{
// TODO
field_AFC++;
Entity* nearestPlayer = m_pLevel->getNearestPlayer(this, -1.0f);
// if we need to remove ourselves when far away, and there's a player around
// (if there's no players, we're on a headless server)
if (removeWhenFarAway() && nearestPlayer)
{
float distSqr = nearestPlayer->distanceToSqr_inline(m_pos.x, m_pos.y, m_pos.z);
if (distSqr > 16384.0f)
remove();
if (field_AFC > 600)
{
if (m_random.nextInt(800) == 0)
{
if (distSqr >= 1024.0f)
remove();
else
field_AFC = 0;
}
}
}
field_B00 = 0.0f;
field_B04 = 0.0f;
if (m_random.nextFloat() < 0.02f)
{
Entity* nearestPlayer = m_pLevel->getNearestPlayer(this, 8.0f);
if (nearestPlayer)
{
m_pEntLookedAt = nearestPlayer;
field_120 = m_random.nextInt(20) + 10;
}
}
if (m_pEntLookedAt)
{
lookAt(m_pEntLookedAt, 10.0f, getMaxHeadXRot());
// gaze timer
field_120--;
// if the entity was removed, or we're too far away, or our gaze timer is up
if (field_120 < 0 || m_pEntLookedAt->m_bRemoved || m_pEntLookedAt->distanceToSqr(this) > 64.0f)
// stop staring
m_pEntLookedAt = nullptr;
}
else
{
if (m_random.nextFloat() < 0.05f)
field_B08 = (m_random.nextFloat() - 0.5f) * 20.0f;
m_yaw += field_B08;
m_pitch = field_B10;
}
if (isInWater() || isInLava())
{
field_B0C = m_random.nextInt() < 0.8f;
}
}
int Mob::getMaxHeadXRot()

View File

@@ -107,7 +107,7 @@ public:
float field_B04;
float field_B08;
char field_B0C;
int field_B10;
float field_B10;
float field_B14;
std::string m_texture;
std::string m_class;
@@ -129,4 +129,6 @@ public:
float field_B80;
int field_B84;
Entity* m_pEntLookedAt;
float v020_field_104;
};

View File

@@ -39,6 +39,10 @@ Player::Player(Level* pLevel) : Mob(pLevel)
field_C4 = 20;
field_B5C = 180.0f;
// @TEST TEST TEST
field_F0 = false;
// @TEST TEST TEST
}
Player::~Player()
@@ -225,7 +229,9 @@ void Player::animateRespawn(Player*, Level*)
void Player::attack(Entity* pEnt)
{
int atkDmg = m_pInventory->getAttackDamage(pEnt);
if (atkDmg > 0)
pEnt->hurt(this, atkDmg);
}
bool Player::canDestroy(Tile* pTile)

View File

@@ -94,6 +94,7 @@ void Inventory::prepareSurvivalInventory()
addTestItem(Item::camera->m_itemID, 64);
addTestItem(Tile::ladder->m_ID, 64);
addTestItem(Tile::obsidian->m_ID, 64);
addTestItem(Tile::fire->m_ID, 64);
for (int i = 0; i < C_MAX_HOTBAR_ITEMS; i++)
m_hotbar[i] = i;
@@ -217,7 +218,11 @@ ItemInstance* Inventory::getQuickSlotItem(int slotNo)
if (slotNo < 0 || slotNo >= C_MAX_HOTBAR_ITEMS)
return nullptr;
return getItem(m_hotbar[slotNo]);
ItemInstance* pInst = getItem(m_hotbar[slotNo]);
if (pInst->m_itemID == 0)
return nullptr;
return pInst;
}
ItemInstance* Inventory::getSelectedItem()
@@ -293,3 +298,12 @@ void Inventory::selectItemById(int itemID)
LOG_W("selectItemById: %d doesn't exist", itemID);
}
int Inventory::getAttackDamage(Entity* pEnt)
{
ItemInstance* pInst = getSelected();
if (!pInst)
return 1;
return pInst->getAttackDamage(pEnt);
}

View File

@@ -4,6 +4,7 @@
#include "world/item/ItemInstance.hpp"
#include "world/entity/Player.hpp"
class Entity;
class Player; // in case we're included from Player.hpp
#define C_MAX_HOTBAR_ITEMS (9)
@@ -37,11 +38,18 @@ public:
void setQuickSlotIndexByItemId(int slotNo, int itemID);
void selectItemById(int itemID);
int getAttackDamage(Entity*);
int getSelectedSlotNo() const
{
return m_SelectedHotbarSlot;
}
// v0.2.0 name alias
ItemInstance* getSelected() {
return getSelectedItem();
}
public:
int m_SelectedHotbarSlot;
private:

View File

@@ -176,6 +176,11 @@ bool ItemInstance::matches(ItemInstance* a1, ItemInstance* a2)
return a1->matches(a2);
}
int ItemInstance::getAttackDamage(Entity *pEnt)
{
return getItem()->getAttackDamage(pEnt);
}
void ItemInstance::mineBlock(int x, int y, int z, int d)
{
return getItem()->mineBlock(this, x, y, z, d);

View File

@@ -14,6 +14,7 @@
class Item; // in case we're included from Item.hpp
class Tile;
class Level;
class Entity;
class Mob;
class Player;
@@ -61,6 +62,9 @@ public:
static bool matches(ItemInstance*, ItemInstance*);
// v0.2.0
int getAttackDamage(Entity *pEnt);
public:
int m_auxValue;
int m_amount;