dc77061840
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
97 lines
3.3 KiB
C++
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;
|
|
}
|
|
|
|
}
|