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

summaryrefslogtreecommitdiff
path: root/source/game/items/StarObjectItem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/game/items/StarObjectItem.cpp')
-rw-r--r--source/game/items/StarObjectItem.cpp107
1 files changed, 107 insertions, 0 deletions
diff --git a/source/game/items/StarObjectItem.cpp b/source/game/items/StarObjectItem.cpp
new file mode 100644
index 0000000..bd4749b
--- /dev/null
+++ b/source/game/items/StarObjectItem.cpp
@@ -0,0 +1,107 @@
+#include "StarObjectItem.hpp"
+#include "StarRoot.hpp"
+#include "StarObject.hpp"
+#include "StarLogging.hpp"
+#include "StarObjectDatabase.hpp"
+#include "StarWorld.hpp"
+#include "StarJsonExtra.hpp"
+
+namespace Star {
+
+ObjectItem::ObjectItem(Json const& config, String const& directory, Json const& objectParameters)
+ : Item(config, directory, objectParameters), FireableItem(config), BeamItem(config) {
+ setTwoHanded(config.getBool("twoHanded", true));
+
+ // Make sure that all script objects that have retainObjectParametersInItem
+ // start with a blank scriptStorage entry to help them stack properly.
+ if (instanceValue("retainObjectParametersInItem", false).toBool() && instanceValue("scriptStorage").isNull())
+ setInstanceValue("scriptStorage", JsonObject());
+ m_shifting = false;
+}
+
+ItemPtr ObjectItem::clone() const {
+ return make_shared<ObjectItem>(*this);
+}
+
+void ObjectItem::init(ToolUserEntity* owner, ToolHand hand) {
+ FireableItem::init(owner, hand);
+ BeamItem::init(owner, hand);
+}
+
+void ObjectItem::update(FireMode fireMode, bool shifting, HashSet<MoveControlType> const& moves) {
+ FireableItem::update(fireMode, shifting, moves);
+ BeamItem::update(fireMode, shifting, moves);
+ setEnd(BeamItem::EndType::Object);
+ m_shifting = shifting;
+}
+
+List<Drawable> ObjectItem::nonRotatedDrawables() const {
+ return beamDrawables(canPlace(m_shifting));
+}
+
+float ObjectItem::cooldownTime() const {
+ // TODO: Hardcoded
+ return 0.25f;
+}
+
+void ObjectItem::fire(FireMode mode, bool shifting, bool edgeTriggered) {
+ if (!ready())
+ return;
+
+ if (placeInWorld(mode, shifting))
+ FireableItem::fire(mode, shifting, edgeTriggered);
+}
+
+String ObjectItem::objectName() const {
+ return instanceValue("objectName", "<objectName missing>").toString();
+}
+
+Json ObjectItem::objectParameters() const {
+ Json objectParameters = parameters().opt().value(JsonObject{});
+ if (!initialized())
+ return objectParameters;
+ return objectParameters.set("owner", jsonFromMaybe(owner()->uniqueId()));
+}
+
+bool ObjectItem::placeInWorld(FireMode, bool shifting) {
+ if (!initialized())
+ throw ItemException("ObjectItem not init'd properly, or user not recognized as Tool User.");
+
+ if (!ready())
+ return false;
+
+ if (!canPlace(shifting))
+ return false;
+
+ auto pos = Vec2I(owner()->aimPosition().floor());
+ auto objectDatabase = Root::singleton().objectDatabase();
+ try {
+ if (auto object = objectDatabase->createForPlacement(world(), objectName(), pos, owner()->walkingDirection(), objectParameters())) {
+ if (consume(1)) {
+ world()->addEntity(object);
+ return true;
+ }
+ }
+ } catch (StarException const& e) {
+ Logger::error("Failed to instantiate object for placement. %s %s : %s",
+ objectName(),
+ objectParameters().repr(0, true),
+ outputException(e, true));
+ return true;
+ }
+
+ return false;
+}
+
+bool ObjectItem::canPlace(bool) const {
+ if (initialized()) {
+ if (owner()->isAdmin() || owner()->inToolRange()) {
+ auto pos = Vec2I(owner()->aimPosition().floor());
+ auto objectDatabase = Root::singleton().objectDatabase();
+ return objectDatabase->canPlaceObject(world(), pos, objectName());
+ }
+ }
+ return false;
+}
+
+}