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

summaryrefslogtreecommitdiff
path: root/source/game/StarObjectDatabase.hpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/game/StarObjectDatabase.hpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/StarObjectDatabase.hpp')
-rw-r--r--source/game/StarObjectDatabase.hpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/source/game/StarObjectDatabase.hpp b/source/game/StarObjectDatabase.hpp
new file mode 100644
index 0000000..5f3f675
--- /dev/null
+++ b/source/game/StarObjectDatabase.hpp
@@ -0,0 +1,224 @@
+#ifndef STAR_OBJECT_DATABASE_HPP
+#define STAR_OBJECT_DATABASE_HPP
+
+#include "StarPeriodicFunction.hpp"
+#include "StarTtlCache.hpp"
+#include "StarGameTypes.hpp"
+#include "StarItemDescriptor.hpp"
+#include "StarParticle.hpp"
+#include "StarSet.hpp"
+#include "StarTileDamage.hpp"
+#include "StarDamageTypes.hpp"
+#include "StarStatusTypes.hpp"
+#include "StarEntityRendering.hpp"
+#include "StarTileEntity.hpp"
+
+namespace Star {
+
+STAR_CLASS(World);
+STAR_CLASS(Image);
+STAR_CLASS(ItemDatabase);
+STAR_CLASS(RecipeDatabase);
+STAR_CLASS(Object);
+STAR_STRUCT(ObjectOrientation);
+STAR_STRUCT(ObjectConfig);
+STAR_CLASS(ObjectDatabase);
+
+STAR_EXCEPTION(ObjectException, StarException);
+
+struct ObjectOrientation {
+ struct Anchor {
+ TileLayer layer;
+ Vec2I position;
+ bool tilled;
+ bool soil;
+ Maybe<MaterialId> material;
+ };
+
+ struct ParticleEmissionEntry {
+ float particleEmissionRate;
+ float particleEmissionRateVariance;
+ // Particle positions are considered relative to image pixels, and are
+ // flipped with image flipping
+ Particle particle;
+ Particle particleVariance;
+ bool placeInSpaces;
+ };
+
+ // The JSON values that were used to configure this orientation.
+ Json config;
+
+ EntityRenderLayer renderLayer;
+ List<Drawable> imageLayers;
+ bool flipImages;
+
+ // Offset of image from (0, 0) object position, in tile coordinates
+ Vec2F imagePosition;
+
+ // If an object has frames > 1, then the image name will have the marker
+ // "{frame}" replaced with an integer in [0, frames)
+ unsigned frames;
+ float animationCycle;
+
+ // Spaces the object occupies. By default, this is simply the single space
+ // at the object position, but can be specified in config as either a list of
+ // Vec2I, or by setting a threshold value using "spaceScanning", which will
+ // scan the image (frame 1) for non-transparent pixels.
+ List<Vec2I> spaces;
+ RectI boundBox;
+
+ // Allow an orientation to override the metaboundbox in case you don't want to
+ // specify spaces
+ Maybe<RectF> metaBoundBox;
+
+ // Anchors of the object to place it in the world
+ // For background tiles set in order for the object to
+ // remain placed. Must be within 1 space of the bounding box of spaces.
+ // For foreground tiles this cannot logically contain any position
+ // also in spaces, as objects cannot overlap with foreground tiles.
+ List<Anchor> anchors;
+
+ // if true, only one anchor needs to be valid for the orientation to be valid,
+ // otherwise all anchors must be valid
+ bool anchorAny;
+
+ Maybe<Direction> directionAffinity;
+
+ // Optional list of material spaces
+ List<MaterialSpace> materialSpaces;
+
+ // optionally override the default spaces used for interaction
+ Maybe<List<Vec2I>> interactiveSpaces;
+
+ Vec2F lightPosition;
+ float beamAngle;
+
+ List<ParticleEmissionEntry> particleEmitters;
+
+ Maybe<PolyF> statusEffectArea;
+ Json touchDamageConfig;
+
+ static ParticleEmissionEntry parseParticleEmitter(String const& path, Json const& config);
+ bool placementValid(World const* world, Vec2I const& position) const;
+ bool anchorsValid(World const* world, Vec2I const& position) const;
+};
+
+// TODO: This is used very strangely and inconsistently. We go to all the trouble of populating
+// this ObjectConfig structure from the JSON, but then keep around the JSON anyway. In some
+// places we access the objectConfig, but in many more we use the object's configValue method
+// to access the raw config JSON which means it's inconsistent which parameters can be overridden
+// by instance values at various levels. This whole system needs reevaluation.
+struct ObjectConfig {
+ // Returns the index of the best valid orientation. If no orientations are
+ // valid, returns NPos
+ size_t findValidOrientation(World const* world, Vec2I const& position, Maybe<Direction> directionAffinity = Maybe<Direction>()) const;
+
+ String path;
+ // The JSON values that were used to configure this Object
+ Json config;
+
+ String name;
+ String type;
+ String race;
+ String category;
+ StringList colonyTags;
+ StringList scripts;
+ StringList animationScripts;
+
+ unsigned price;
+ bool printable;
+ bool scannable;
+
+ bool interactive;
+
+ StringMap<Color> lightColors;
+ bool pointLight;
+ float pointBeam;
+ float beamAmbience;
+ Maybe<PeriodicFunction<float>> lightFlickering;
+
+ String soundEffect;
+ float soundEffectRangeMultiplier;
+
+ List<PersistentStatusEffect> statusEffects;
+ Json touchDamageConfig;
+
+ bool hasObjectItem;
+ bool retainObjectParametersInItem;
+
+ bool smashable;
+ bool smashOnBreak;
+ bool unbreakable;
+ String smashDropPool;
+ List<List<ItemDescriptor>> smashDropOptions;
+ StringList smashSoundOptions;
+ JsonArray smashParticles;
+
+ String breakDropPool;
+ List<List<ItemDescriptor>> breakDropOptions;
+
+ TileDamageParameters tileDamageParameters;
+ float damageShakeMagnitude;
+ String damageMaterialKind;
+
+ EntityDamageTeam damageTeam;
+
+ Maybe<float> minimumLiquidLevel;
+ Maybe<float> maximumLiquidLevel;
+ float liquidCheckInterval;
+
+ float health;
+
+ Json animationConfig;
+
+ List<ObjectOrientationPtr> orientations;
+
+ // If true, the object will root - it will prevent the blocks it is
+ // anchored to from being destroyed directly, and damage from those
+ // blocks will be redirected to the object
+ bool rooting;
+
+ bool biomePlaced;
+};
+
+class ObjectDatabase {
+public:
+ static List<Vec2I> scanImageSpaces(ImageConstPtr const& image, Vec2F const& position, float fillLimit, bool flip = false);
+ static Json parseTouchDamage(String const& path, Json const& touchDamage);
+ static List<ObjectOrientationPtr> parseOrientations(String const& path, Json const& configList);
+
+ ObjectDatabase();
+
+ void cleanup();
+
+ StringList allObjects() const;
+ bool isObject(String const& name) const;
+
+ ObjectConfigPtr getConfig(String const& objectName) const;
+ List<ObjectOrientationPtr> const& getOrientations(String const& objectName) const;
+
+ ObjectPtr createObject(String const& objectName, Json const& objectParameters = JsonObject()) const;
+ ObjectPtr diskLoadObject(Json const& diskStore) const;
+ ObjectPtr netLoadObject(ByteArray const& netStore) const;
+
+ bool canPlaceObject(World const* world, Vec2I const& position, String const& objectName) const;
+ // If the object is placeable in the given position, creates the given object
+ // and sets its position and direction and returns it, otherwise returns
+ // null.
+ ObjectPtr createForPlacement(World const* world, String const& objectName, Vec2I const& position,
+ Direction direction, Json const& parameters = JsonObject()) const;
+
+ List<Drawable> cursorHintDrawables(World const* world, String const& objectName, Vec2I const& position,
+ Direction direction, Json parameters = {}) const;
+
+private:
+ static ObjectConfigPtr readConfig(String const& path);
+
+ StringMap<String> m_paths;
+ mutable Mutex m_cacheMutex;
+ mutable HashTtlCache<String, ObjectConfigPtr> m_configCache;
+};
+
+}
+
+#endif