osb/source/game/interfaces/StarWorld.cpp
Kai Blaschke 431a9c00a5
Fixed a huge amount of Clang warnings
On Linux and macOS, using Clang to compile OpenStarbound produces about 400 MB worth of warnings during the build, making the compiler output unreadable and slowing the build down considerably.

99% of the warnings were unqualified uses of std::move and std::forward, which are now all properly qualified.

Fixed a few other minor warnings about non-virtual destructors and some uses of std::move preventing copy elision on temporary objects.

Most remaining warnings are now unused parameters.
2024-02-19 16:55:19 +01:00

154 lines
5.0 KiB
C++

#include "StarWorld.hpp"
#include "StarScriptedEntity.hpp"
namespace Star {
bool World::isServer() const {
return connection() == ServerConnectionId;
}
bool World::isClient() const {
return !isServer();
}
List<EntityPtr> World::entityQuery(RectF const& boundBox, EntityFilter selector) const {
List<EntityPtr> list;
forEachEntity(boundBox, [&](EntityPtr const& entity) {
if (!selector || selector(entity))
list.append(entity);
});
return list;
}
List<EntityPtr> World::entityLineQuery(Vec2F const& begin, Vec2F const& end, EntityFilter selector) const {
List<EntityPtr> list;
forEachEntityLine(begin, end, [&](EntityPtr const& entity) {
if (!selector || selector(entity))
list.append(entity);
});
return list;
}
List<TileEntityPtr> World::entitiesAtTile(Vec2I const& pos, EntityFilter selector) const {
List<TileEntityPtr> list;
forEachEntityAtTile(pos, [&](TileEntityPtr entity) {
if (!selector || selector(entity))
list.append(std::move(entity));
});
return list;
}
List<Vec2I> World::findEmptyTiles(Vec2I pos, unsigned maxDist, size_t maxAmount, bool excludeEphemeral) const {
List<Vec2I> res;
if (!tileIsOccupied(pos, TileLayer::Foreground, excludeEphemeral))
res.append(pos);
if (res.size() >= maxAmount)
return res;
// searches manhattan distance counterclockwise from right
for (int distance = 1; distance <= (int)maxDist; distance++) {
const int totalSpots = 4 * distance;
int xDiff = distance;
int yDiff = 0;
int dx = -1;
int dy = 1;
for (int i = 0; i < totalSpots; i++) {
if (!tileIsOccupied(pos + Vec2I(xDiff, yDiff), TileLayer::Foreground)) {
res.append(pos + Vec2I(xDiff, yDiff));
if (res.size() >= maxAmount) {
return res;
}
}
xDiff += dx;
yDiff += dy;
if (abs(xDiff) == distance)
dx *= -1;
if (abs(yDiff) == distance)
dy *= -1;
}
}
return res;
}
bool World::canModifyTile(Vec2I const& pos, TileModification const& modification, bool allowEntityOverlap) const {
return !validTileModifications({{pos, modification}}, allowEntityOverlap).empty();
}
bool World::modifyTile(Vec2I const& pos, TileModification const& modification, bool allowEntityOverlap) {
return applyTileModifications({{pos, modification}}, allowEntityOverlap).empty();
}
TileDamageResult World::damageTile(Vec2I const& tilePosition, TileLayer layer, Vec2F const& sourcePosition, TileDamage const& tileDamage, Maybe<EntityId> sourceEntity) {
return damageTiles({tilePosition}, layer, sourcePosition, tileDamage, sourceEntity);
}
EntityPtr World::closestEntityInSight(Vec2F const& center, float radius, CollisionSet const& collisionSet, EntityFilter selector) const {
return closestEntity(center, radius, [=](EntityPtr const& entity) {
return selector(entity) && !lineTileCollision(center, entity->position(), collisionSet);
});
}
bool World::pointCollision(Vec2F const& point, CollisionSet const& collisionSet) const {
bool collided = false;
forEachCollisionBlock(RectI::withCenter(Vec2I(point), {3, 3}), [&](CollisionBlock const& block) {
if (collided || !isColliding(block.kind, collisionSet))
return;
if (block.poly.contains(point))
collided = true;
});
return collided;
}
Maybe<pair<Vec2F, Maybe<Vec2F>>> World::lineCollision(Line2F const& line, CollisionSet const& collisionSet) const {
auto geometry = this->geometry();
Maybe<PolyF> intersectPoly;
Maybe<PolyF::LineIntersectResult> closestIntersection;
forEachCollisionBlock(RectI::integral(RectF::boundBoxOf(line.min(), line.max()).padded(1)), [&](CollisionBlock const& block) {
if (block.poly.isNull() || !isColliding(block.kind, collisionSet))
return;
Vec2F nearMin = geometry.nearestTo(block.poly.center(), line.min());
auto intersection = block.poly.lineIntersection(Line2F(nearMin, nearMin + line.diff()));
if (intersection && (!closestIntersection || intersection->along < closestIntersection->along)) {
intersectPoly = block.poly;
closestIntersection = intersection;
}
});
if (closestIntersection) {
auto point = line.eval(closestIntersection->along);
auto normal = closestIntersection->intersectedSide.apply([&](uint64_t side) { return intersectPoly->normal(side); });
return make_pair(point, normal);
}
return {};
}
bool World::polyCollision(PolyF const& poly, CollisionSet const& collisionSet) const {
auto geometry = this->geometry();
Vec2F polyCenter = poly.center();
PolyF translatedPoly;
bool collided = false;
forEachCollisionBlock(RectI::integral(poly.boundBox()).padded(1), [&](CollisionBlock const& block) {
if (collided || !isColliding(block.kind, collisionSet))
return;
Vec2F center = block.poly.center();
Vec2F newCenter = geometry.nearestTo(polyCenter, center);
translatedPoly = block.poly;
translatedPoly.translate(newCenter - center);
if (poly.intersects(translatedPoly))
collided = true;
});
return collided;
}
}