Skip to content

Commit

Permalink
refactor: access actor handles using WeakEntityRef
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-vincent committed Feb 23, 2025
1 parent d86e3e8 commit e115658
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 110 deletions.
79 changes: 44 additions & 35 deletions src/endstone/core/actor/actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Server &EndstoneActor::getServer() const

std::string EndstoneActor::getName() const
{
return CommandUtils::getActorName(actor_);
return CommandUtils::getActorName(getActor());
}

bool EndstoneActor::isPermissionSet(std::string name) const
Expand Down Expand Up @@ -102,29 +102,29 @@ void EndstoneActor::setOp(bool value)

std::string EndstoneActor::getType() const
{
return actor_.getActorIdentifier().getCanonicalName();
return getActor().getActorIdentifier().getCanonicalName();
}

std::uint64_t EndstoneActor::getRuntimeId() const
{
return actor_.getRuntimeID().raw_id;
return getActor().getRuntimeID().raw_id;
}

Location EndstoneActor::getLocation() const
{
auto position = actor_.getPosition();
position.y -= actor_.getPersistentComponent<OffsetsComponent>()->height_offset;
const auto &rotation = actor_.getRotation();
auto position = getActor().getPosition();
position.y -= getActor().getPersistentComponent<OffsetsComponent>()->height_offset;
const auto &rotation = getActor().getRotation();

return {&getDimension(), position.x, position.y, position.z, rotation.x, rotation.y};
}

Vector<float> EndstoneActor::getVelocity() const
{
if (actor_.hasCategory(ActorCategory::Mob) || actor_.hasCategory(ActorCategory::Ridable)) {
auto *actor = actor_.getVehicle();
if (getActor().hasCategory(ActorCategory::Mob) || getActor().hasCategory(ActorCategory::Ridable)) {
auto *actor = getActor().getVehicle();
if (!actor) {
actor = &actor_;
actor = &getActor();
}
auto *component = actor->tryGetComponent<PostTickPositionDeltaComponent>();
if (component) {
Expand All @@ -133,23 +133,23 @@ Vector<float> EndstoneActor::getVelocity() const
}
}

const auto &delta = actor_.getPosDelta();
const auto &delta = getActor().getPosDelta();
return {delta.x, delta.y, delta.z};
}

bool EndstoneActor::isOnGround() const
{
return actor_.isOnGround();
return getActor().isOnGround();
}

bool EndstoneActor::isInWater() const
{
return actor_.isInWater();
return getActor().isInWater();
}

bool EndstoneActor::isInLava() const
{
return actor_.isInLava();
return getActor().isInLava();
}

Level &EndstoneActor::getLevel() const
Expand All @@ -159,12 +159,12 @@ Level &EndstoneActor::getLevel() const

Dimension &EndstoneActor::getDimension() const
{
return *getLevel().getDimension(actor_.getDimension().getName());
return *getLevel().getDimension(getActor().getDimension().getName());
}

void EndstoneActor::setRotation(float yaw, float pitch)
{
actor_.setRotationWrapped({pitch, yaw});
getActor().setRotationWrapped({pitch, yaw});
}

void EndstoneActor::teleport(Location location)
Expand All @@ -177,14 +177,14 @@ void EndstoneActor::teleport(Location location)
auto rotation = RotationCommandUtils::RotationData{RelativeFloat{location.getPitch(), 0},
RelativeFloat{location.getYaw(), 0}, std::nullopt};

auto target = TeleportCommand::computeTarget(actor_, // victim
auto target = TeleportCommand::computeTarget(getActor(), // victim
{location.getX(), location.getY(), location.getZ()}, // destination
nullptr, // facing
destination_dimension, // dimension
rotation, // rotation
CommandVersion::CurrentVersion);

TeleportCommand::applyTarget(actor_, std::move(target), /*keep_velocity*/ false);
TeleportCommand::applyTarget(getActor(), std::move(target), /*keep_velocity*/ false);
}

void EndstoneActor::teleport(Actor &target)
Expand All @@ -194,22 +194,31 @@ void EndstoneActor::teleport(Actor &target)

std::int64_t EndstoneActor::getId() const
{
return actor_.getOrCreateUniqueID().raw_id;
return getActor().getOrCreateUniqueID().raw_id;
}

void EndstoneActor::remove()
{
actor_.remove();
getActor().remove();
}

bool EndstoneActor::isDead() const
{
return !actor_.isAlive();
return !getActor().isAlive();
}

bool EndstoneActor::isValid() const
{
const auto *handle = actor_.tryUnwrap<::Actor>();
if (!handle) {
return false;
}
return handle->isAlive();
}

int EndstoneActor::getHealth() const
{
return actor_.getHealth();
return getActor().getHealth();
}

Result<void> EndstoneActor::setHealth(int health) const
Expand All @@ -218,70 +227,70 @@ Result<void> EndstoneActor::setHealth(int health) const
return nonstd::make_unexpected(
make_error("Health value ({}) must be between 0 and {}.", health, getMaxHealth()));
}
auto mutable_attr = actor_.getMutableAttribute("minecraft:health");
auto mutable_attr = getActor().getMutableAttribute("minecraft:health");
mutable_attr.instance->setCurrentValue(static_cast<float>(health), mutable_attr.context);
return {};
}

int EndstoneActor::getMaxHealth() const
{
return actor_.getMaxHealth();
return getActor().getMaxHealth();
}

std::vector<std::string> EndstoneActor::getScoreboardTags() const
{
return actor_.getTags();
return getActor().getTags();
}

bool EndstoneActor::addScoreboardTag(std::string tag) const
{
return actor_.addTag(tag);
return getActor().addTag(tag);
}

bool EndstoneActor::removeScoreboardTag(std::string tag) const
{
return actor_.removeTag(tag);
return getActor().removeTag(tag);
}

bool EndstoneActor::isNameTagVisible() const
{
return actor_.canShowNameTag();
return getActor().canShowNameTag();
}

void EndstoneActor::setNameTagVisible(bool visible)
{
actor_.setNameTagVisible(visible);
getActor().setNameTagVisible(visible);
}

bool EndstoneActor::isNameTagAlwaysVisible() const
{
return actor_.entity_data.getInt8(static_cast<SynchedActorData::ID>(ActorDataIDs::NAMETAG_ALWAYS_SHOW)) != 0;
return getActor().entity_data.getInt8(static_cast<SynchedActorData::ID>(ActorDataIDs::NAMETAG_ALWAYS_SHOW)) != 0;
}

void EndstoneActor::setNameTagAlwaysVisible(bool visible)
{
actor_.entity_data.set<SynchedActorData::TypeInt8>(
getActor().entity_data.set<SynchedActorData::TypeInt8>(
static_cast<SynchedActorData::ID>(ActorDataIDs::NAMETAG_ALWAYS_SHOW), visible);
}

std::string EndstoneActor::getNameTag() const
{
return actor_.getNameTag();
return getActor().getNameTag();
}

void EndstoneActor::setNameTag(std::string name)
{
actor_.setNameTag(name);
getActor().setNameTag(name);
}

std::string EndstoneActor::getScoreTag() const
{
return actor_.getScoreTag();
return getActor().getScoreTag();
}

void EndstoneActor::setScoreTag(std::string score)
{
actor_.setScoreTag(score);
getActor().setScoreTag(score);
}

PermissibleBase &EndstoneActor::getPermissibleBase()
Expand All @@ -292,7 +301,7 @@ PermissibleBase &EndstoneActor::getPermissibleBase()

::Actor &EndstoneActor::getActor() const
{
return actor_;
return getHandle<::Actor>();
}

std::shared_ptr<EndstoneActor> EndstoneActor::create(EndstoneServer &server, ::Actor &actor)
Expand Down
16 changes: 12 additions & 4 deletions src/endstone/core/actor/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,22 @@ class EndstoneActor : public Actor, public std::enable_shared_from_this<Endstone
[[nodiscard]] std::string getScoreTag() const override;
void setScoreTag(std::string score) override;

::Actor &getActor() const;

static std::shared_ptr<EndstoneActor> create(EndstoneServer &server, ::Actor &actor);

protected:
template <typename T>
T *getHandle() const
T &getHandle() const
{
return actor_.tryUnwrap<T>();
auto *ptr = actor_.tryUnwrap<T>();
if (!ptr) {
throw std::runtime_error("Trying to access an actor that is no longer valid.");
}
return *ptr;
}

static std::shared_ptr<EndstoneActor> create(EndstoneServer &server, ::Actor &actor);

private:
protected:
EndstoneServer &server_;

Expand Down
16 changes: 13 additions & 3 deletions src/endstone/core/actor/mob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

namespace endstone::core {

EndstoneMob::EndstoneMob(EndstoneServer &server, ::Mob &mob) : EndstoneActor(server, mob), mob_(mob) {}
EndstoneMob::EndstoneMob(EndstoneServer &server, ::Mob &mob) : EndstoneActor(server, mob) {}

Mob *EndstoneMob::asMob() const
{
Expand Down Expand Up @@ -149,7 +149,7 @@ Dimension &EndstoneMob::getDimension() const
void EndstoneMob::setRotation(float yaw, float pitch)
{
EndstoneActor::setRotation(yaw, pitch);
mob_.setYBodyRotation(yaw);
getMob().setYBodyRotation(yaw);
}

void EndstoneMob::teleport(Location location)
Expand All @@ -172,6 +172,11 @@ void EndstoneMob::remove()
EndstoneActor::remove();
}

bool EndstoneMob::isValid() const
{
return EndstoneActor::isValid();
}

bool EndstoneMob::isDead() const
{
return EndstoneActor::isDead();
Expand Down Expand Up @@ -249,7 +254,12 @@ void EndstoneMob::setScoreTag(std::string score)

bool EndstoneMob::isGliding() const
{
return mob_.isGliding();
return getMob().isGliding();
}

::Mob &EndstoneMob::getMob() const
{
return getHandle<::Mob>();
}

std::shared_ptr<EndstoneMob> EndstoneMob::create(EndstoneServer &server, ::Mob &mob)
Expand Down
6 changes: 3 additions & 3 deletions src/endstone/core/actor/mob.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class EndstoneMob : public EndstoneActor, public Mob {
void teleport(Actor &target) override;
[[nodiscard]] std::int64_t getId() const override;
void remove() override;
[[nodiscard]] bool isValid() const override;
[[nodiscard]] bool isDead() const override;
[[nodiscard]] int getHealth() const override;
[[nodiscard]] Result<void> setHealth(int health) const override;
Expand All @@ -79,9 +80,8 @@ class EndstoneMob : public EndstoneActor, public Mob {
// Mob
[[nodiscard]] bool isGliding() const override;

static std::shared_ptr<EndstoneMob> create(EndstoneServer &server, ::Mob &mob);
::Mob &getMob() const;

private:
::Mob &mob_;
static std::shared_ptr<EndstoneMob> create(EndstoneServer &server, ::Mob &mob);
};
} // namespace endstone::core
2 changes: 1 addition & 1 deletion src/endstone/core/boss/boss_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ void EndstoneBossBar::send(BossEventUpdateType event_type, Player &player)
{
const auto packet = MinecraftPackets::createPacket(MinecraftPacketIds::BossEvent);
const auto pk = std::static_pointer_cast<BossEventPacket>(packet);
const auto &handle = static_cast<EndstonePlayer &>(player).getHandle();
const auto &handle = static_cast<EndstonePlayer &>(player).getPlayer();
pk->boss_id = handle.getOrCreateUniqueID();
pk->player_id = handle.getOrCreateUniqueID();
pk->event_type = event_type;
Expand Down
4 changes: 2 additions & 2 deletions src/endstone/core/command/command_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ std::unique_ptr<CommandOrigin> CommandWrapper::getCommandOrigin(CommandSender &s
CompoundTag tag;
{
tag.putByte("OriginType", static_cast<std::uint8_t>(CommandOriginType::Player));
tag.putInt64("PlayerId", player->getHandle().getOrCreateUniqueID().raw_id);
tag.putInt64("PlayerId", player->getPlayer().getOrCreateUniqueID().raw_id);
}
return CommandOriginLoader::load(tag, static_cast<ServerLevel &>(player->getHandle().getLevel()));
return CommandOriginLoader::load(tag, static_cast<ServerLevel &>(player->getPlayer().getLevel()));
}

if (const auto *actor = static_cast<EndstoneActor *>(sender.asActor()); actor) {
Expand Down
12 changes: 6 additions & 6 deletions src/endstone/core/event/handlers/block_gameplay_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,22 @@ bool EndstoneBlockGameplayHandler::handleEvent(const PistonActionEvent &event)

bool EndstoneBlockGameplayHandler::handleEvent(const BlockTryPlaceByPlayerEvent &event)
{
const auto *entity = ::Actor::tryGetFromEntity(event.player.unwrap(), false);
if (!entity || !entity->isPlayer()) {
const auto *player = WeakEntityRef(event.player).tryUnwrap<::Player>();
if (!player) {
return true;
}

const auto &server = entt::locator<EndstoneServer>::value();
auto &player = entity->getEndstoneActor<EndstonePlayer>();
auto &dimension = player.getDimension();
auto &block_source = player.getHandle().getDimension().getBlockSourceFromMainChunkSource();
auto &endstone_player = player->getEndstoneActor<EndstonePlayer>();
auto &dimension = endstone_player.getDimension();
auto &block_source = player->getDimension().getBlockSourceFromMainChunkSource();
const auto block_face = static_cast<BlockFace>(event.face);
auto block_placed = std::make_unique<EndstoneBlockState>(dimension, event.pos, event.permutation_to_place);
const auto block_replaced = EndstoneBlock::at(block_source, event.pos);
const auto opposite = EndstoneBlockFace::getOpposite(block_face);
const auto block_against = block_replaced->getRelative(opposite);

BlockPlaceEvent e{std::move(block_placed), block_replaced, block_against, player};
BlockPlaceEvent e{std::move(block_placed), block_replaced, block_against, endstone_player};
server.getPluginManager().callEvent(e);
if (e.isCancelled()) {
return false;
Expand Down
Loading

0 comments on commit e115658

Please sign in to comment.