Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/items/StarMaterialItem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/game/items/StarMaterialItem.cpp')
-rw-r--r--source/game/items/StarMaterialItem.cpp62
1 files changed, 56 insertions, 6 deletions
diff --git a/source/game/items/StarMaterialItem.cpp b/source/game/items/StarMaterialItem.cpp
index f2f15da..2740eb7 100644
--- a/source/game/items/StarMaterialItem.cpp
+++ b/source/game/items/StarMaterialItem.cpp
@@ -8,6 +8,7 @@
#include "StarWorldClient.hpp"
#include "StarWorldTemplate.hpp"
#include "StarInput.hpp"
+#include "StarTileDrawer.hpp"
namespace Star {
@@ -17,6 +18,7 @@ MaterialItem::MaterialItem(Json const& config, String const& directory, Json con
: Item(config, directory, settings), FireableItem(config), BeamItem(config) {
m_material = config.getInt("materialId");
m_materialHueShift = materialHueFromDegrees(instanceValue("materialHueShift", 0).toFloat());
+ auto materialDatabase = Root::singleton().materialDatabase();
if (materialHueShift() != MaterialHue()) {
auto drawables = iconDrawables();
@@ -36,7 +38,6 @@ MaterialItem::MaterialItem(Json const& config, String const& directory, Json con
m_blockRadius = instanceValue("blockRadius", defaultParameters.getFloat("blockRadius")).toFloat();
m_altBlockRadius = instanceValue("altBlockRadius", defaultParameters.getFloat("altBlockRadius")).toFloat();
- auto materialDatabase = Root::singleton().materialDatabase();
auto multiplace = instanceValue("allowMultiplace", BlockCollisionSet.contains(materialDatabase->materialCollisionKind(m_material)));
if (multiplace.isType(Json::Type::Bool))
m_multiplace = multiplace.toBool();
@@ -96,16 +97,16 @@ void MaterialItem::update(float dt, FireMode fireMode, bool shifting, HashSet<Mo
owner()->addSound("/sfx/tools/cyclematcollision.ogg", 1.0f, Random::randf(0.9f, 1.1f));
}
- if (auto presses = input.bindDown("opensb", "materialRadiusGrow")) {
+ if (auto presses = input.bindDown("opensb", "buildingRadiusGrow")) {
m_blockRadius = min(BlockRadiusLimit, int(m_blockRadius + *presses));
setInstanceValue("blockRadius", m_blockRadius);
- owner()->addSound("/sfx/tools/matradiusgrow.wav", 1.0f, 1.0f + m_blockRadius / BlockRadiusLimit);
+ owner()->addSound("/sfx/tools/buildradiusgrow.wav", 1.0f, 1.0f + m_blockRadius / BlockRadiusLimit);
}
- if (auto presses = input.bindDown("opensb", "materialRadiusShrink")) {
+ if (auto presses = input.bindDown("opensb", "buildingRadiusShrink")) {
m_blockRadius = max(1, int(m_blockRadius - *presses));
setInstanceValue("blockRadius", m_blockRadius);
- owner()->addSound("/sfx/tools/matradiusshrink.wav", 1.0f, 1.0f + m_blockRadius / BlockRadiusLimit);
+ owner()->addSound("/sfx/tools/buildradiusshrink.wav", 1.0f, 1.0f + m_blockRadius / BlockRadiusLimit);
}
}
else {
@@ -148,6 +149,14 @@ void MaterialItem::render(RenderCallback* renderCallback, EntityRenderLayer rend
}
}
+List<Drawable> MaterialItem::preview(PlayerPtr const&) const {
+ return generatedPreview();
+}
+
+List<Drawable> MaterialItem::dropDrawables() const {
+ return generatedPreview();
+}
+
List<Drawable> MaterialItem::nonRotatedDrawables() const {
return beamDrawables(canPlace(m_shifting));
}
@@ -218,6 +227,47 @@ MaterialId MaterialItem::materialId() const {
return m_material;
}
+List<Drawable> const& MaterialItem::generatedPreview(Vec2I position) const {
+ if (!m_generatedPreviewCache) {
+ if (TileDrawer* tileDrawer = TileDrawer::singletonPtr()) {
+ auto locker = tileDrawer->lockRenderData();
+ WorldRenderData& renderData = tileDrawer->renderData();
+ renderData.geometry = WorldGeometry(3, 3);
+ renderData.tiles.resize({ 3, 3 });
+ renderData.tiles.fill(TileDrawer::DefaultRenderTile);
+ renderData.tileMinPosition = { 0, 0 };
+ RenderTile& tile = renderData.tiles.at({ 1, 1 });
+ tile.foreground = m_material;
+ tile.foregroundHueShift = m_materialHueShift;
+ tile.foregroundColorVariant = 0;
+
+ List<Drawable> drawables;
+ TileDrawer::Drawables tileDrawables;
+ bool isBlock = BlockCollisionSet.contains(Root::singleton().materialDatabase()->materialCollisionKind(m_material));
+ TileDrawer::TerrainLayer layer = isBlock ? TileDrawer::TerrainLayer::Foreground : TileDrawer::TerrainLayer::Midground;
+ for (int x = 0; x != 3; ++x) {
+ for (int y = 0; y != 3; ++y)
+ tileDrawer->produceTerrainDrawables(tileDrawables, layer, { x, y }, renderData, 1.0f / TilePixels, position - Vec2I(1, 1));
+ }
+
+ locker.unlock();
+ for (auto& index : tileDrawables.keys())
+ drawables.appendAll(tileDrawables.take(index));
+
+ auto boundBox = Drawable::boundBoxAll(drawables, true);
+ if (!boundBox.isEmpty()) {
+ for (auto& drawable : drawables)
+ drawable.translate(-boundBox.center());
+ }
+
+ m_generatedPreviewCache.emplace(move(drawables));
+ }
+ else
+ m_generatedPreviewCache.emplace(iconDrawables());
+ }
+ return *m_generatedPreviewCache;
+}
+
float MaterialItem::calcRadius(bool shifting) const {
if (!multiplaceEnabled())
return 1;
@@ -270,7 +320,7 @@ TileCollisionOverride& MaterialItem::collisionOverride() {
return m_collisionOverride;
}
-List<PreviewTile> MaterialItem::preview(bool shifting) const {
+List<PreviewTile> MaterialItem::previewTiles(bool shifting) const {
List<PreviewTile> result;
if (initialized()) {
Color lightColor = Color::rgba(owner()->favoriteColor());