Merge commit '7db4e20fd7ee7cf1c25d5c2c5e9e1b1cf97d4c97' into pullstream

This commit is contained in:
Rebekah 2024-02-14 06:36:55 -05:00
commit 90a8d9f6c0
Signed by: oneechanhax
GPG Key ID: 183EB7902964DAE5
23 changed files with 208 additions and 20 deletions

2
.gitignore vendored
View File

@ -46,6 +46,8 @@ GPUCache
*.cbp *.cbp
## KDevelop ## KDevelop
*.kdev* *.kdev*
## Vim
.cache/
# world inside source # world inside source
ChunkWorx.ini ChunkWorx.ini

View File

@ -17849,6 +17849,10 @@ end
{ {
Notes = "A mask that indicates the bits of the metadata that specify the facing of redstone repeaters.", Notes = "A mask that indicates the bits of the metadata that specify the facing of redstone repeaters.",
}, },
E_META_SPAWN_EGG_ENDERMITE =
{
Notes = "",
},
E_META_SPAWN_EGG_WITHER_SKELETON = E_META_SPAWN_EGG_WITHER_SKELETON =
{ {
Notes = "" Notes = ""

View File

@ -48,6 +48,13 @@ AttackRate=1.0
MaxHealth=200 MaxHealth=200
SightDistance=25.0 SightDistance=25.0
[Endermite]
AttackDamage=2.0
AttackRange=0.75
AttackRate=1.0
MaxHealth=8
SightDistance=16.0
[Enderman] [Enderman]
AttackDamage=4.0 AttackDamage=4.0
AttackRange=1.0 AttackRange=1.0

View File

@ -1146,6 +1146,7 @@ enum ENUM_ITEM_META : short
E_META_SPAWN_EGG_WITHER = 64, E_META_SPAWN_EGG_WITHER = 64,
E_META_SPAWN_EGG_BAT = 65, E_META_SPAWN_EGG_BAT = 65,
E_META_SPAWN_EGG_WITCH = 66, E_META_SPAWN_EGG_WITCH = 66,
E_META_SPAWN_EGG_ENDERMITE = 67,
E_META_SPAWN_EGG_GUARDIAN = 68, E_META_SPAWN_EGG_GUARDIAN = 68,
E_META_SPAWN_EGG_PIG = 90, E_META_SPAWN_EGG_PIG = 90,
E_META_SPAWN_EGG_SHEEP = 91, E_META_SPAWN_EGG_SHEEP = 91,

View File

@ -510,6 +510,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
case mtSpider: case mtSpider:
case mtCaveSpider: case mtCaveSpider:
case mtSilverfish: case mtSilverfish:
case mtEndermite:
{ {
MagicalCriticalHit = true; MagicalCriticalHit = true;
a_TDI.FinalDamage += 2.5f * BaneOfArthropodsLevel; a_TDI.FinalDamage += 2.5f * BaneOfArthropodsLevel;

View File

@ -17,6 +17,8 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "FastRandom.h"
#include "Mobs/MonsterTypes.h"
#include "ThrownEnderPearlEntity.h" #include "ThrownEnderPearlEntity.h"
#include "Player.h" #include "Player.h"
@ -72,11 +74,25 @@ void cThrownEnderPearlEntity::TeleportCreator(Vector3d a_HitPos)
return; return;
} }
GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, [=](cPlayer & a_Entity) GetWorld()->FindAndDoWithPlayer(m_CreatorData.m_Name, [=](cPlayer & a_Entity)
{ {
auto & Random = GetRandomProvider();
// 5% chance to spawn an endermite
if (Random.RandBool(0.05))
{
Vector3d PlayerPosition = a_Entity.GetPosition();
m_World->SpawnMob(PlayerPosition.x, PlayerPosition.y, PlayerPosition.z, mtEndermite);
}
// Teleport the creator here, make them take 5 damage: // Teleport the creator here, make them take 5 damage:
a_Entity.TeleportToCoords(a_HitPos.x, a_HitPos.y + 0.2, a_HitPos.z); a_Entity.TeleportToCoords(a_HitPos.x, a_HitPos.y + 0.2, a_HitPos.z);
a_Entity.TakeDamage(dtEnderPearl, this, 5, 0); a_Entity.TakeDamage(dtEnderPearl, this, 5, 0);
return false; return false;
}); });
} }

View File

@ -88,6 +88,7 @@ public:
case E_META_SPAWN_EGG_COW: return mtCow; case E_META_SPAWN_EGG_COW: return mtCow;
case E_META_SPAWN_EGG_CREEPER: return mtCreeper; case E_META_SPAWN_EGG_CREEPER: return mtCreeper;
case E_META_SPAWN_EGG_ENDERMAN: return mtEnderman; case E_META_SPAWN_EGG_ENDERMAN: return mtEnderman;
case E_META_SPAWN_EGG_ENDERMITE: return mtEndermite;
case E_META_SPAWN_EGG_GHAST: return mtGhast; case E_META_SPAWN_EGG_GHAST: return mtGhast;
case E_META_SPAWN_EGG_GUARDIAN: return mtGuardian; case E_META_SPAWN_EGG_GUARDIAN: return mtGuardian;
case E_META_SPAWN_EGG_HORSE: return mtHorse; case E_META_SPAWN_EGG_HORSE: return mtHorse;

View File

@ -19,6 +19,9 @@
#pragma once #pragma once
#include "ItemHandler.h"
#include "Entities/ProjectileEntity.h"

View File

@ -19,9 +19,9 @@
#include "AggressiveMonster.h" #include "AggressiveMonster.h"
#include "../World.h" #include "LineBlockTracer.h"
#include "../Entities/Player.h" #include "World.h"
#include "../LineBlockTracer.h" #include "Entities/Player.h"
@ -62,6 +62,61 @@ void cAggressiveMonster::EventSeePlayer(cPlayer * a_Player, cChunk & a_Chunk)
cMonster * cAggressiveMonster::GetMonsterOfTypeInSight(eMonsterType a_MobType, unsigned int a_SightDistance)
{
cMonster * FoundTarget = nullptr;
auto MinimumDistance = static_cast<double>(a_SightDistance * a_SightDistance);
class cCallback : public cBlockTracer::cCallbacks
{
public:
bool OnNextBlock(Vector3i a_BlockPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, eBlockFace a_EntryFace) override
{
return a_BlockType != E_BLOCK_AIR;
}
};
auto Callbacks = cCallback();
auto Tracer = cLineBlockTracer(*GetWorld(), Callbacks);
cEntityCallback Callback = [&](cEntity & a_Entity)
{
if (!a_Entity.IsMob())
{
return false;
}
auto & Other = dynamic_cast<cMonster &>(a_Entity);
if (Other.GetMobType() != a_MobType)
{
return false;
}
Vector3d MyHeadPosition = GetPosition().addedY(GetHeight());
Vector3d TargetPosition = Other.GetPosition().addedY(Other.GetHeight());
double TargetDistance = (MyHeadPosition - TargetPosition).SqrLength();
if (
(MinimumDistance > TargetDistance) &&
(TargetDistance < (a_SightDistance * a_SightDistance))
)
{
FoundTarget = & Other;
return true;
}
return false;
};
cBoundingBox CheckZone(GetPosition().addedXZ(-a_SightDistance, -a_SightDistance), GetPosition().addedXZ(a_SightDistance, a_SightDistance));
m_World->ForEachEntityInBox(CheckZone, Callback);
return FoundTarget;
}
void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{ {
Super::Tick(a_Dt, a_Chunk); Super::Tick(a_Dt, a_Chunk);

View File

@ -46,12 +46,18 @@ public:
virtual void EventSeePlayer(cPlayer * a_Player, cChunk & a_Chunk) override; virtual void EventSeePlayer(cPlayer * a_Player, cChunk & a_Chunk) override;
/**
* Check if a monster of certain type is in sight
*
* @param a_mobtype the mob type to find
* @param SightDistance max distance to check
*
* @return pointer to the mob found
*/
cMonster * GetMonsterOfTypeInSight(eMonsterType a_mobtype, unsigned int SightDistance=16);
/** Try to perform attack /** Try to perform attack
returns true if attack was deemed successful (hit player, fired projectile, creeper exploded, etc.) even if it didn't actually do damage returns true if attack was deemed successful (hit player, fired projectile, creeper exploded, etc.) even if it didn't actually do damage
return false if e.g. the mob is still in cooldown from a previous attack */ return false if e.g. the mob is still in cooldown from a previous attack */
virtual bool Attack(std::chrono::milliseconds a_Dt); virtual bool Attack(std::chrono::milliseconds a_Dt);
} ; } ;

View File

@ -9,6 +9,7 @@ target_sources(
Cow.cpp Cow.cpp
Creeper.cpp Creeper.cpp
EnderDragon.cpp EnderDragon.cpp
Endermite.cpp
Enderman.cpp Enderman.cpp
Ghast.cpp Ghast.cpp
Giant.cpp Giant.cpp
@ -49,6 +50,7 @@ target_sources(
Cow.h Cow.h
Creeper.h Creeper.h
EnderDragon.h EnderDragon.h
Endermite.h
Enderman.h Enderman.h
Ghast.h Ghast.h
Giant.h Giant.h

View File

@ -165,6 +165,29 @@ void cEnderman::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
return; return;
} }
if (m_EMState != CHASING)
{
cMonster * EndermiteFound = GetMonsterOfTypeInSight(mtEndermite, 64);
if (EndermiteFound != nullptr)
{
SetTarget(EndermiteFound);
m_EMState = CHASING;
m_bIsScreaming = true;
}
}
else
{
const auto Target = GetTarget();
if (Target != nullptr)
{
if (!Target->IsTicking())
{
m_EMState = IDLE;
m_bIsScreaming = false;
}
}
}
PREPARE_REL_AND_CHUNK(GetPosition().Floor(), a_Chunk); PREPARE_REL_AND_CHUNK(GetPosition().Floor(), a_Chunk);
if (!RelSuccess) if (!RelSuccess)
{ {

41
src/Mobs/Endermite.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "Globals.h"
#include "Endermite.h"
#include "../World.h"
#include "../Chunk.h"
#include "../Blocks/BlockHandler.h"
#include "../Blocks/BlockInfested.h"
cEndermite::cEndermite() :
Super("Endermite", mtEndermite, "entity.endermite.hurt", "entity.endermite.death", "entity.endermite.ambient", 0.4f, 0.3f),
m_Timer(0),
m_Lifetime(2 * 1000 * 60) // 2 minutes (2 * 1000 (mili to sec) * 60 (sec to min) * 2 because tick = 0.5 sec)
{
}
void cEndermite::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
Super::Tick(a_Dt, a_Chunk);
// Not destroying the endermite if a name is set
if (m_CustomName.empty())
{
m_Timer += a_Dt;
// Destroy the endermite after 2 minutes
if (m_Timer > m_Lifetime)
{
Destroy();
}
}
}

24
src/Mobs/Endermite.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include "AggressiveMonster.h"
class cEndermite:
public cAggressiveMonster
{
using Super = cAggressiveMonster;
// Endermite should despawn in two minutes
std::chrono::milliseconds m_Timer;
std::chrono::milliseconds m_Lifetime;
public:
cEndermite();
CLASS_PROTODEF(cEndermite)
void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
} ;

View File

@ -21,6 +21,7 @@
#include "Cow.h" #include "Cow.h"
#include "Creeper.h" #include "Creeper.h"
#include "Enderman.h" #include "Enderman.h"
#include "Endermite.h"
#include "EnderDragon.h" #include "EnderDragon.h"
#include "Ghast.h" #include "Ghast.h"
#include "Giant.h" #include "Giant.h"

View File

@ -61,6 +61,7 @@ static const struct
{mtCow, "cow", "Cow", "cow"}, {mtCow, "cow", "Cow", "cow"},
{mtCreeper, "creeper", "Creeper", "creeper"}, {mtCreeper, "creeper", "Creeper", "creeper"},
{mtEnderman, "enderman", "Enderman", "enderman"}, {mtEnderman, "enderman", "Enderman", "enderman"},
{mtEndermite, "endermite", "Endermite", "endermite"},
{mtEnderDragon, "enderdragon", "EnderDragon", "ender_dragon"}, {mtEnderDragon, "enderdragon", "EnderDragon", "ender_dragon"},
{mtGhast, "ghast", "Ghast", "ghast"}, {mtGhast, "ghast", "Ghast", "ghast"},
{mtGiant, "giant", "Giant", "giant"}, {mtGiant, "giant", "Giant", "giant"},
@ -669,6 +670,11 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI)
Reward = GetRandomProvider().RandInt(6, 8); Reward = GetRandomProvider().RandInt(6, 8);
break; break;
} }
case mtEndermite:
{
Reward = 3;
break;
}
case mtBlaze: case mtBlaze:
{ {
Reward = 10; Reward = 10;
@ -1302,6 +1308,7 @@ std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType)
case mtCow: return std::make_unique<cCow>(); case mtCow: return std::make_unique<cCow>();
case mtCreeper: return std::make_unique<cCreeper>(); case mtCreeper: return std::make_unique<cCreeper>();
case mtEnderDragon: return std::make_unique<cEnderDragon>(); case mtEnderDragon: return std::make_unique<cEnderDragon>();
case mtEndermite: return std::make_unique<cEndermite>();
case mtEnderman: return std::make_unique<cEnderman>(); case mtEnderman: return std::make_unique<cEnderman>();
case mtGhast: return std::make_unique<cGhast>(); case mtGhast: return std::make_unique<cGhast>();
case mtGiant: return std::make_unique<cGiant>(); case mtGiant: return std::make_unique<cGiant>();

View File

@ -953,8 +953,6 @@ void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
} }
case mtCat: case mtCat:
case mtEndermite:
case mtPolarBear: case mtPolarBear:
case mtShulker: case mtShulker:
@ -971,6 +969,7 @@ void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
case mtCaveSpider: case mtCaveSpider:
case mtEnderDragon: case mtEnderDragon:
case mtEndermite:
case mtGiant: case mtGiant:
case mtIronGolem: case mtIronGolem:
case mtMooshroom: case mtMooshroom:

View File

@ -1246,8 +1246,6 @@ void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
case mtDonkey: case mtDonkey:
case mtMule: case mtMule:
case mtEndermite:
case mtEvoker: case mtEvoker:
case mtLlama: case mtLlama:
@ -1270,6 +1268,7 @@ void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
case mtCaveSpider: case mtCaveSpider:
case mtEnderDragon: case mtEnderDragon:
case mtEndermite:
case mtGiant: case mtGiant:
case mtIronGolem: case mtIronGolem:
case mtMooshroom: case mtMooshroom:

View File

@ -951,8 +951,6 @@ void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
case mtDonkey: case mtDonkey:
case mtMule: case mtMule:
case mtEndermite:
case mtEvoker: case mtEvoker:
case mtHusk: case mtHusk:
@ -981,6 +979,7 @@ void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
break; break;
} }
case mtEndermite:
case mtGiant: case mtGiant:
case mtSilverfish: case mtSilverfish:
case mtSquid: case mtSquid:

View File

@ -1315,8 +1315,6 @@ void cProtocol_1_13::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
case mtDrowned: case mtDrowned:
case mtEndermite:
case mtEvoker: case mtEvoker:
case mtIllusioner: case mtIllusioner:
@ -1364,6 +1362,7 @@ void cProtocol_1_13::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
break; break;
} }
case mtEndermite:
case mtGiant: case mtGiant:
case mtSilverfish: case mtSilverfish:
case mtSquid: case mtSquid:

View File

@ -1618,8 +1618,6 @@ void cProtocol_1_14::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
case mtDrowned: case mtDrowned:
case mtEndermite:
case mtEvoker: case mtEvoker:
case mtIllusioner: case mtIllusioner:
@ -1667,6 +1665,7 @@ void cProtocol_1_14::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
break; break;
} }
case mtEndermite:
case mtGiant: case mtGiant:
case mtSilverfish: case mtSilverfish:
case mtSquid: case mtSquid:

View File

@ -3777,7 +3777,6 @@ void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
case mtCat: case mtCat:
case mtEndermite:
case mtDonkey: case mtDonkey:
case mtMule: case mtMule:
@ -3795,6 +3794,7 @@ void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
case mtIronGolem: case mtIronGolem:
case mtMooshroom: case mtMooshroom:
case mtSilverfish: case mtSilverfish:
case mtEndermite:
case mtSnowGolem: case mtSnowGolem:
case mtSpider: case mtSpider:
case mtSquid: case mtSquid:

View File

@ -2334,8 +2334,6 @@ void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
case mtDonkey: case mtDonkey:
case mtEndermite:
case mtMule: case mtMule:
case mtStray: case mtStray:
@ -2352,6 +2350,7 @@ void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
case mtCaveSpider: case mtCaveSpider:
case mtEnderDragon: case mtEnderDragon:
case mtEndermite:
case mtGiant: case mtGiant:
case mtIronGolem: case mtIronGolem:
case mtMooshroom: case mtMooshroom: