bring player inspection back!
This commit is contained in:
parent
17daee680a
commit
ad58a960e4
@ -1,4 +1,5 @@
|
||||
#include "StarPlayer.hpp"
|
||||
#include "StarEncode.hpp"
|
||||
#include "StarJsonExtra.hpp"
|
||||
#include "StarRoot.hpp"
|
||||
#include "StarSongbook.hpp"
|
||||
@ -102,10 +103,6 @@ Player::Player(PlayerConfigPtr config, Uuid uuid) {
|
||||
m_techs = make_shared<PlayerTech>();
|
||||
m_log = make_shared<PlayerLog>();
|
||||
|
||||
m_description = strf("This {} seems to have nothing to say for {}self.",
|
||||
m_identity.gender == Gender::Male ? "guy" : "gal",
|
||||
m_identity.gender == Gender::Male ? "him" : "her");
|
||||
|
||||
setModeType(PlayerMode::Casual);
|
||||
|
||||
m_useDown = false;
|
||||
@ -1524,6 +1521,10 @@ String Player::description() const {
|
||||
return m_description;
|
||||
}
|
||||
|
||||
void Player::setDescription(String const& description) {
|
||||
m_description = description;
|
||||
}
|
||||
|
||||
Direction Player::walkingDirection() const {
|
||||
return m_movementController->movingDirection();
|
||||
}
|
||||
@ -2107,6 +2108,19 @@ List<ChatAction> Player::pullPendingChatActions() {
|
||||
return take(m_pendingChatActions);
|
||||
}
|
||||
|
||||
Maybe<String> Player::inspectionLogName() const {
|
||||
auto identifier = uniqueId();
|
||||
if (String* str = identifier.ptr()) {
|
||||
auto hash = XXH3_128bits(str->utf8Ptr(), str->utf8Size());
|
||||
return String("Player #") + hexEncode((const char*)&hash, sizeof(hash));
|
||||
}
|
||||
return identifier;
|
||||
}
|
||||
|
||||
Maybe<String> Player::inspectionDescription(String const& species) const {
|
||||
return m_description;
|
||||
}
|
||||
|
||||
float Player::beamGunRadius() const {
|
||||
return m_tools->beamGunRadius();
|
||||
}
|
||||
@ -2228,6 +2242,10 @@ void Player::finalizeCreation() {
|
||||
m_statusController->resetAllResources();
|
||||
|
||||
m_effectEmitter->reset();
|
||||
|
||||
m_description = strf("This {} seems to have nothing to say for {}self.",
|
||||
m_identity.gender == Gender::Male ? "guy" : "gal",
|
||||
m_identity.gender == Gender::Male ? "him" : "her");
|
||||
}
|
||||
|
||||
bool Player::invisible() const {
|
||||
|
@ -53,6 +53,7 @@ class Player :
|
||||
public virtual ToolUserEntity,
|
||||
public virtual LoungingEntity,
|
||||
public virtual ChattyEntity,
|
||||
public virtual InspectableEntity,
|
||||
public virtual DamageBarEntity,
|
||||
public virtual PortraitEntity,
|
||||
public virtual NametagEntity,
|
||||
@ -172,6 +173,7 @@ public:
|
||||
bool forceNude() const;
|
||||
|
||||
String description() const override;
|
||||
void setDescription(String const& description);
|
||||
|
||||
List<LightSource> lightSources() const override;
|
||||
|
||||
@ -377,6 +379,9 @@ public:
|
||||
|
||||
List<ChatAction> pullPendingChatActions() override;
|
||||
|
||||
Maybe<String> inspectionLogName() const override;
|
||||
Maybe<String> inspectionDescription(String const& species) const override;
|
||||
|
||||
float beamGunRadius() const override;
|
||||
|
||||
bool instrumentPlaying() override;
|
||||
|
@ -1,13 +1,13 @@
|
||||
#ifndef STAR_INSPECTABLE_ENTITY_HPP
|
||||
#define STAR_INSPECTABLE_ENTITY_HPP
|
||||
|
||||
#include "StarTileEntity.hpp"
|
||||
#include "StarEntity.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
STAR_CLASS(InspectableEntity);
|
||||
|
||||
class InspectableEntity : public virtual TileEntity {
|
||||
class InspectableEntity : public virtual Entity {
|
||||
public:
|
||||
// Default implementation returns true
|
||||
virtual bool inspectable() const;
|
||||
|
@ -77,19 +77,23 @@ float InspectionTool::inspectionLevel(InspectableEntityPtr const& inspectable) c
|
||||
if (!initialized() || !inspectable->inspectable())
|
||||
return 0;
|
||||
|
||||
float totalLevel = 0;
|
||||
if (auto tileEntity = as<TileEntity>(inspectable)) {
|
||||
float totalLevel = 0;
|
||||
|
||||
// convert spaces to a set of world positions
|
||||
Set<Vec2I> spaceSet;
|
||||
for (auto space : inspectable->spaces())
|
||||
spaceSet.add(inspectable->tilePosition() + space);
|
||||
// convert spaces to a set of world positions
|
||||
Set<Vec2I> spaceSet;
|
||||
for (auto space : tileEntity->spaces())
|
||||
spaceSet.add(tileEntity->tilePosition() + space);
|
||||
|
||||
for (auto space : spaceSet) {
|
||||
float pointLevel = pointInspectionLevel(centerOfTile(space));
|
||||
if (pointLevel > 0 && hasLineOfSight(space, spaceSet))
|
||||
totalLevel += pointLevel;
|
||||
for (auto space : spaceSet) {
|
||||
float pointLevel = pointInspectionLevel(centerOfTile(space));
|
||||
if (pointLevel > 0 && hasLineOfSight(space, spaceSet))
|
||||
totalLevel += pointLevel;
|
||||
}
|
||||
return clamp(totalLevel / min(spaceSet.size(), m_fullInspectionSpaces), 0.0f, 1.0f);
|
||||
}
|
||||
return clamp(totalLevel / min(spaceSet.size(), m_fullInspectionSpaces), 0.0f, 1.0f);
|
||||
else
|
||||
return pointInspectionLevel(inspectable->position());
|
||||
}
|
||||
|
||||
float InspectionTool::pointInspectionLevel(Vec2F const& position) const {
|
||||
@ -116,13 +120,35 @@ InspectionTool::InspectionResult InspectionTool::inspect(Vec2F const& position)
|
||||
|
||||
// if there's a candidate InspectableEntity at the position, make sure that entity's total inspection level
|
||||
// is above the minimum threshold
|
||||
for (auto entity : world()->atTile<InspectableEntity>(Vec2I::floor(position))) {
|
||||
auto check = [&](InspectableEntityPtr entity) -> Maybe<InspectionTool::InspectionResult> {
|
||||
if (entity->inspectable() && inspectionLevel(entity) >= m_minimumInspectionLevel) {
|
||||
if (m_allowScanning)
|
||||
return {entity->inspectionDescription(species).value(), entity->inspectionLogName(), entity->entityId()};
|
||||
return { { entity->inspectionDescription(species).value(), entity->inspectionLogName(), entity->entityId() } };
|
||||
else
|
||||
return {entity->inspectionDescription(species).value(), {}, {}};
|
||||
return { { entity->inspectionDescription(species).value(), {}, {} } };
|
||||
}
|
||||
return {};
|
||||
};
|
||||
|
||||
|
||||
WorldGeometry geometry = world()->geometry();
|
||||
for (auto& entity : world()->query<InspectableEntity>(RectF::withCenter(position, Vec2F::filled(FLT_EPSILON)), [&](InspectableEntityPtr const& entity) {
|
||||
if (entity->entityType() == EntityType::Object)
|
||||
return false;
|
||||
else if (!geometry.rectContains(entity->metaBoundBox().translated(entity->position()), position))
|
||||
return false;
|
||||
else {
|
||||
auto hitPoly = entity->hitPoly();
|
||||
return hitPoly && geometry.polyContains(*hitPoly, position);
|
||||
}
|
||||
})) {
|
||||
if (auto result = check(entity))
|
||||
return *result;
|
||||
}
|
||||
|
||||
for (auto& entity : world()->atTile<InspectableEntity>(Vec2I::floor(position))) {
|
||||
if (auto result = check(entity))
|
||||
return *result;
|
||||
}
|
||||
|
||||
// check the inspection level at the selected tile
|
||||
|
Loading…
Reference in New Issue
Block a user