osb/source/game/interfaces/StarTileEntity.hpp
Kae dc77061840 hopefully fix
in OpenStarbound, players can place blocks with their own collision type. this can cause objects to override the collision type if the object has material spaces and a previous attempt at accounting for this led to that bug: giving object collision its own field in the server tile should fix this
2024-03-09 12:18:22 +11:00

97 lines
3.3 KiB
C++

#pragma once
#include "StarEntity.hpp"
#include "StarTileDamage.hpp"
#include "StarInteractiveEntity.hpp"
#include "StarCollisionBlock.hpp"
namespace Star {
STAR_CLASS(TileEntity);
struct MaterialSpace {
MaterialSpace();
MaterialSpace(Vec2I space, MaterialId material);
bool operator==(MaterialSpace const& rhs) const;
Vec2I space;
MaterialId material;
};
DataStream& operator<<(DataStream& ds, MaterialSpace const& materialSpace);
DataStream& operator>>(DataStream& ds, MaterialSpace& materialSpace);
// Entities that derive from TileEntity are those that can be placed in the
// tile grid, and occupy tile spaces, possibly affecting collision.
class TileEntity : public virtual InteractiveEntity {
public:
TileEntity();
// position() here is simply the tilePosition (but Vec2F)
virtual Vec2F position() const override;
// The base tile position of this object.
virtual Vec2I tilePosition() const = 0;
virtual void setTilePosition(Vec2I const& pos) = 0;
// TileEntities occupy the given spaces in tile space. This is relative to
// the current base position, and may include negative positions. A 1x1
// object would occupy just (0, 0).
virtual List<Vec2I> spaces() const;
// Blocks that should be marked as "root", so that they are non-destroyable
// until this entity is destroyable. Should be outside of spaces(), and
// after placement should remain static for the lifetime of the entity.
virtual List<Vec2I> roots() const;
// TileEntities may register some of their occupied spaces with metamaterials
// to generate collidable regions
virtual List<MaterialSpace> materialSpaces() const;
// Returns whether the entity was destroyed
virtual bool damageTiles(List<Vec2I> const& positions, Vec2F const& sourcePosition, TileDamage const& tileDamage);
// Forces the tile entity to do an immediate check if it has been invalidly
// placed in some way. The tile entity may do this check on its own, but
// less often.
virtual bool checkBroken() = 0;
// If the entity accepts interaction through right clicking, by default,
// returns false.
virtual bool isInteractive() const override;
// By default, does nothing. Will be called only on the server.
virtual InteractAction interact(InteractRequest const& request) override;
// Specific subset spaces that are interactive, by default, just returns
// spaces()
virtual List<Vec2I> interactiveSpaces() const;
virtual List<QuestArcDescriptor> offeredQuests() const override;
virtual StringSet turnInQuests() const override;
virtual Vec2F questIndicatorPosition() const override;
protected:
// Checks whether any of a given spaces list (relative to current tile
// position) is occupied by a real material. (Does not include tile
// entities).
bool anySpacesOccupied(List<Vec2I> const& relativeSpaces) const;
// Checks that *all* spaces are occupied by a real material.
bool allSpacesOccupied(List<Vec2I> const& relativeSpaces) const;
float spacesLiquidFillLevel(List<Vec2I> const& relativeSpaces) const;
};
inline MaterialSpace::MaterialSpace()
: material(NullMaterialId) {}
inline MaterialSpace::MaterialSpace(Vec2I space, MaterialId material)
: space(space), material(material) {}
inline bool MaterialSpace::operator==(MaterialSpace const& rhs) const {
return space == rhs.space
&& material == rhs.material;
}
}