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

summaryrefslogtreecommitdiff
path: root/source/game/interfaces/StarFireableItem.cpp
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/interfaces/StarFireableItem.cpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/interfaces/StarFireableItem.cpp')
-rw-r--r--source/game/interfaces/StarFireableItem.cpp300
1 files changed, 300 insertions, 0 deletions
diff --git a/source/game/interfaces/StarFireableItem.cpp b/source/game/interfaces/StarFireableItem.cpp
new file mode 100644
index 0000000..e39d77e
--- /dev/null
+++ b/source/game/interfaces/StarFireableItem.cpp
@@ -0,0 +1,300 @@
+#include "StarFireableItem.hpp"
+#include "StarJsonExtra.hpp"
+#include "StarWorldLuaBindings.hpp"
+#include "StarConfigLuaBindings.hpp"
+#include "StarItemLuaBindings.hpp"
+#include "StarFireableItemLuaBindings.hpp"
+#include "StarItem.hpp"
+#include "StarWorld.hpp"
+
+namespace Star {
+
+FireableItem::FireableItem()
+ : m_fireTimer(0),
+ m_cooldownTime(10),
+ m_windupTime(0),
+ m_fireWhenReady(false),
+ m_startWhenReady(false),
+ m_cooldown(false),
+ m_alreadyInit(false),
+ m_requireEdgeTrigger(false),
+ m_attemptedFire(false),
+ m_fireOnRelease(false),
+ m_timeFiring(0.0f),
+ m_startTimingFire(false),
+ m_inUse(false),
+ m_walkWhileFiring(false),
+ m_stopWhileFiring(false),
+ m_mode(FireMode::None) {}
+
+FireableItem::FireableItem(Json const& params) : FireableItem() {
+ setParams(params);
+ m_fireableParams = params;
+}
+
+FireableItem::FireableItem(FireableItem const& rhs) : ToolUserItem(rhs), StatusEffectItem(rhs) {
+ m_fireTimer = rhs.m_fireTimer;
+ m_cooldownTime = rhs.m_cooldownTime;
+ m_windupTime = rhs.m_windupTime;
+ m_fireWhenReady = rhs.m_fireWhenReady;
+ m_startWhenReady = rhs.m_startWhenReady;
+ m_cooldown = rhs.m_cooldown;
+ m_alreadyInit = rhs.m_alreadyInit;
+ m_requireEdgeTrigger = rhs.m_requireEdgeTrigger;
+ m_attemptedFire = rhs.m_attemptedFire;
+ m_fireOnRelease = rhs.m_fireOnRelease;
+ m_timeFiring = rhs.m_timeFiring;
+ m_startTimingFire = rhs.m_startTimingFire;
+ m_inUse = rhs.m_inUse;
+ m_walkWhileFiring = rhs.m_walkWhileFiring;
+ m_stopWhileFiring = rhs.m_stopWhileFiring;
+ m_fireableParams = rhs.m_fireableParams;
+ m_handPosition = rhs.m_handPosition;
+ m_mode = rhs.m_mode;
+}
+
+void FireableItem::init(ToolUserEntity* owner, ToolHand hand) {
+ ToolUserItem::init(owner, hand);
+
+ m_fireWhenReady = false;
+ m_startWhenReady = false;
+
+ auto scripts = m_fireableParams.opt("scripts").apply(jsonToStringList);
+ if (entityMode() == EntityMode::Master && scripts) {
+ if (!m_scriptComponent) {
+ m_scriptComponent.emplace();
+ m_scriptComponent->setScripts(*scripts);
+ }
+ m_scriptComponent->addCallbacks(
+ "config", LuaBindings::makeConfigCallbacks(bind(&Item::instanceValue, as<Item>(this), _1, _2)));
+ m_scriptComponent->addCallbacks("fireableItem", LuaBindings::makeFireableItemCallbacks(this));
+ m_scriptComponent->addCallbacks("item", LuaBindings::makeItemCallbacks(as<Item>(this)));
+ m_scriptComponent->init(world());
+ }
+}
+
+void FireableItem::uninit() {
+ if (m_scriptComponent) {
+ m_scriptComponent->uninit();
+ m_scriptComponent->removeCallbacks("config");
+ m_scriptComponent->removeCallbacks("fireableItem");
+ m_scriptComponent->removeCallbacks("item");
+ }
+
+ ToolUserItem::uninit();
+}
+
+void FireableItem::fire(FireMode mode, bool, bool edgeTriggered) {
+ m_attemptedFire = true;
+ if (ready()) {
+ m_inUse = true;
+ m_startTimingFire = true;
+ m_mode = mode;
+ if (!m_requireEdgeTrigger || edgeTriggered) {
+ setFireTimer(windupTime() + cooldownTime());
+ if (!m_fireOnRelease) {
+ m_fireWhenReady = true;
+ m_startWhenReady = true;
+ }
+ }
+ }
+
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("attemptedFire");
+}
+
+void FireableItem::endFire(FireMode mode, bool) {
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("endFire");
+
+ m_attemptedFire = false;
+ if (m_fireOnRelease && m_timeFiring) {
+ m_mode = mode;
+ triggerCooldown();
+ fireTriggered();
+ }
+}
+
+FireMode FireableItem::fireMode() const {
+ return m_mode;
+}
+
+float FireableItem::cooldownTime() const {
+ return m_cooldownTime;
+}
+
+void FireableItem::setCooldownTime(float cooldownTime) {
+ m_cooldownTime = cooldownTime;
+}
+
+float FireableItem::fireTimer() const {
+ return m_fireTimer;
+}
+
+void FireableItem::setFireTimer(float fireTimer) {
+ m_fireTimer = fireTimer;
+}
+
+bool FireableItem::ready() const {
+ return fireTimer() <= 0;
+}
+
+bool FireableItem::firing() const {
+ return m_timeFiring > 0;
+}
+
+bool FireableItem::inUse() const {
+ return m_inUse;
+}
+
+bool FireableItem::walkWhileFiring() const {
+ return m_walkWhileFiring;
+}
+
+bool FireableItem::stopWhileFiring() const {
+ return m_stopWhileFiring;
+}
+
+bool FireableItem::windup() const {
+ if (ready())
+ return false;
+
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("triggerWindup");
+
+ return fireTimer() > cooldownTime();
+}
+
+void FireableItem::update(FireMode fireMode, bool shifting, HashSet<MoveControlType> const&) {
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("update", WorldTimestep, FireModeNames.getRight(fireMode), shifting);
+
+ if (m_attemptedFire) {
+ if (m_startTimingFire) {
+ m_timeFiring += WorldTimestep;
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("continueFire", WorldTimestep);
+ }
+ } else {
+ m_timeFiring = 0.0f;
+ m_startTimingFire = false;
+ }
+ m_attemptedFire = false;
+
+ if (entityMode() == EntityMode::Master) {
+ if (fireTimer() > 0.0f) {
+ setFireTimer(fireTimer() - WorldTimestep);
+ if (fireTimer() < 0.0f) {
+ setFireTimer(0.0f);
+ m_inUse = false;
+ }
+ }
+ if (fireTimer() <= 0) {
+ m_cooldown = false;
+ }
+ if (m_startWhenReady) {
+ m_startWhenReady = false;
+ startTriggered();
+ }
+ if (m_fireWhenReady) {
+ if (fireTimer() <= cooldownTime()) {
+ m_fireWhenReady = false;
+ fireTriggered();
+ }
+ }
+ }
+}
+
+void FireableItem::triggerCooldown() {
+ setFireTimer(cooldownTime());
+ m_cooldown = true;
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("triggerCooldown");
+}
+
+bool FireableItem::coolingDown() const {
+ return m_cooldown;
+}
+
+void FireableItem::setCoolingDown(bool coolingdown) {
+ m_cooldown = coolingdown;
+}
+
+float FireableItem::timeFiring() const {
+ return m_timeFiring;
+}
+
+void FireableItem::setTimeFiring(float timeFiring) {
+ m_timeFiring = timeFiring;
+}
+
+Vec2F FireableItem::handPosition() const {
+ return m_handPosition;
+}
+
+Vec2F FireableItem::firePosition() const {
+ return Vec2F();
+}
+
+Json FireableItem::fireableParam(String const& key) const {
+ return m_fireableParams.get(key);
+}
+
+Json FireableItem::fireableParam(String const& key, Json const& defaultVal) const {
+ return m_fireableParams.get(key, defaultVal);
+}
+
+bool FireableItem::validAimPos(Vec2F const&) {
+ return true;
+}
+
+void FireableItem::setParams(Json const& params) {
+ if (!m_alreadyInit) {
+ // cannot use setWindupTime or setCooldownTime here, because object is not fully constructed
+ m_windupTime = params.getFloat("windupTime", 0.0f);
+ m_cooldownTime = params.getFloat("cooldown", params.getFloat("fireTime", 0.15f) - m_windupTime);
+ if (params.contains("handPosition")) {
+ m_handPosition = jsonToVec2F(params.get("handPosition"));
+ }
+ m_requireEdgeTrigger = params.getBool("edgeTrigger", false);
+ m_fireOnRelease = params.getBool("fireOnRelease", false);
+ m_walkWhileFiring = params.getBool("walkWhileFiring", false);
+ m_stopWhileFiring = params.getBool("stopWhileFiring", false);
+ m_alreadyInit = true;
+ }
+}
+
+void FireableItem::setFireableParam(String const& key, Json const& value) {
+ m_fireableParams = m_fireableParams.set(key, value);
+}
+
+void FireableItem::startTriggered() {
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("startTriggered");
+}
+
+void FireableItem::fireTriggered() {
+ if (m_scriptComponent)
+ m_scriptComponent->invoke("fireTriggered");
+}
+
+Vec2F FireableItem::ownerFirePosition() const {
+ if (!initialized())
+ throw StarException("FireableItem uninitialized in ownerFirePosition");
+
+ return owner()->handPosition(hand(), (this->firePosition() - handPosition()) / TilePixels);
+}
+
+float FireableItem::windupTime() const {
+ return m_windupTime;
+}
+
+void FireableItem::setWindupTime(float time) {
+ m_windupTime = time;
+}
+
+List<PersistentStatusEffect> FireableItem::statusEffects() const {
+ return {};
+}
+
+}