diff --git a/assets/games/rose/prefabs/Crab.xml b/assets/games/rose/prefabs/Crab.xml
index ea4724a8..ebea037b 100644
--- a/assets/games/rose/prefabs/Crab.xml
+++ b/assets/games/rose/prefabs/Crab.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/assets/games/rose/prefabs/Urchin.xml b/assets/games/rose/prefabs/Urchin.xml
index a91a0715..2d5f764d 100644
--- a/assets/games/rose/prefabs/Urchin.xml
+++ b/assets/games/rose/prefabs/Urchin.xml
@@ -6,6 +6,9 @@
+
+
+
diff --git a/src/dawnrose/scene/components/entity/CMakeLists.txt b/src/dawnrose/scene/components/entity/CMakeLists.txt
index dd1d9a13..a5d527e8 100644
--- a/src/dawnrose/scene/components/entity/CMakeLists.txt
+++ b/src/dawnrose/scene/components/entity/CMakeLists.txt
@@ -6,9 +6,8 @@
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
- EntityChargePlayer.cpp
EntityHealth.cpp
- EntityRandomWalk.cpp
+ EntityAIWalk.cpp
EntityMove.cpp
EntitySwordAttack.cpp
EntityFaction.cpp
diff --git a/src/dawnrose/scene/components/entity/EntityAIWalk.cpp b/src/dawnrose/scene/components/entity/EntityAIWalk.cpp
new file mode 100644
index 00000000..2c90af8d
--- /dev/null
+++ b/src/dawnrose/scene/components/entity/EntityAIWalk.cpp
@@ -0,0 +1,88 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "EntityAIWalk.hpp"
+
+using namespace Dawn;
+
+EntityAIWalk::EntityAIWalk(SceneItem* item) : SceneItemComponent(item) {
+
+}
+
+std::vector EntityAIWalk::getDependencies() {
+ return {
+ (this->entityMove = item->getComponent())
+ };
+}
+
+void EntityAIWalk::onStart() {
+ assertNotNull(this->entityMove);
+
+ useEvent([&](float_t delta) {
+ switch(this->mode) {
+ case ENTITY_AI_WALK_MODE_FOLLOW_TARGET:
+ this->updateFollowTarget(delta);
+ break;
+ case ENTITY_AI_WALK_MODE_WANDER:
+ this->updateWander(delta);
+ break;
+ case ENTITY_AI_WALK_MODE_STAY:
+ this->entityMove->direction = glm::vec2(0, 0);
+ break;
+ }
+ }, getScene()->eventSceneUpdate);
+}
+
+void EntityAIWalk::updateWander(float_t delta) {
+ // If we are stunned, give up wandering
+ auto health = item->getComponent();
+ if(health != nullptr && health->isStunned()) {
+ wanderTimeToNextDecision = 0;
+ return;
+ }
+
+ // Do we need to make a new decision?
+ if(wanderTimeToNextDecision <= 0) {
+ wanderTimeToNextDecision = randRange(wanderTimeRandomRange.x, wanderTimeRandomRange.y);
+
+ // Do we want to move?
+ if(randRange(0.0f, 1.0f) < wanderDoNotMoveChance) {
+ this->entityMove->direction = glm::vec2(0, 0);
+ return;
+ }
+
+ wanderDestination = glm::vec2(
+ randRange(-wanderDistanceRandomRange.x, wanderDistanceRandomRange.x),
+ randRange(-wanderDistanceRandomRange.y, wanderDistanceRandomRange.y)
+ );
+
+ if(wanderSingleAxisOnly) {
+ if(mathAbs(wanderDestination.x) > mathAbs(wanderDestination.y)) {
+ wanderDestination.x = mathRound(wanderDestination.x);
+ wanderDestination.y = 0;
+ } else {
+ wanderDestination.x = 0;
+ wanderDestination.y = mathRound(wanderDestination.y);
+ }
+ }
+
+ wanderDestination += physics3Dto2D(transform->getLocalPosition());
+ } else {
+ wanderTimeToNextDecision -= delta;
+ }
+
+ // Get the direction to move in
+ glm::vec2 diff = wanderDestination - physics3Dto2D(transform->getLocalPosition());
+
+ // Stop moving if we're close enough
+ if(glm::length(diff) < 0.1f) {
+ wanderTimeToNextDecision = 0;
+ }
+ entityMove->direction = diff;
+}
+
+void EntityAIWalk::updateFollowTarget(float_t delta) {
+
+}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntityAIWalk.hpp b/src/dawnrose/scene/components/entity/EntityAIWalk.hpp
new file mode 100644
index 00000000..f1861ea6
--- /dev/null
+++ b/src/dawnrose/scene/components/entity/EntityAIWalk.hpp
@@ -0,0 +1,54 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/random.hpp"
+#include "EntityMove.hpp"
+#include "EntityHealth.hpp"
+
+namespace Dawn {
+ enum EntityAIWalkMode {
+ ENTITY_AI_WALK_MODE_FOLLOW_TARGET,
+ ENTITY_AI_WALK_MODE_WANDER,
+ ENTITY_AI_WALK_MODE_STAY
+ };
+
+ class EntityAIWalk : public SceneItemComponent {
+ private:
+ EntityMove *entityMove = nullptr;
+
+ void updateWander(float_t delta);
+ void updateFollowTarget(float_t delta);
+
+ public:
+ // Common
+ // @optional
+ enum EntityAIWalkMode mode = ENTITY_AI_WALK_MODE_STAY;
+
+ // Wander Settings
+ // @optional
+ float_t wanderTimeToNextDecision = 0;
+ // @optional
+ glm::vec2 wanderDestination = glm::vec2(0, 0);
+ // @optional
+ glm::vec2 wanderTimeRandomRange = glm::vec2(0.5f, 2.0f);
+ // @optional
+ glm::vec2 wanderDistanceRandomRange = glm::vec2(12.0f, 12.0f);
+ // @optional
+ bool_t wanderSingleAxisOnly = true;
+ // @optional
+ float_t wanderDoNotMoveChance = 0.2f;
+
+ // Follow Target Settings
+ // @optional
+ glm::vec2 followTarget = glm::vec2(0, 0);
+ // @optional
+ float_t followNearDistance = 2.0f;
+
+ EntityAIWalk(SceneItem* item);
+ std::vector getDependencies() override;
+ void onStart() override;
+ };
+}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntityChargePlayer.cpp b/src/dawnrose/scene/components/entity/EntityChargePlayer.cpp
deleted file mode 100644
index 4870305d..00000000
--- a/src/dawnrose/scene/components/entity/EntityChargePlayer.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "EntityChargePlayer.hpp"
-
-using namespace Dawn;
-
-EntityChargePlayer::EntityChargePlayer(SceneItem* item) : SceneItemComponent(item) {
-
-}
-
-std::vector EntityChargePlayer::getDependencies() {
- return {
- (characterController = item->getComponent()),
- (this->entityMove = item->getComponent())
- };
-}
-
-void EntityChargePlayer::onStart() {
- assertNotNull(characterController);
- assertNotNull(this->entityMove);
-
- useEvent([&](float_t delta) {
- // Get the direction to move in
- PlayerController * player = getScene()->findComponent();
- if(player == nullptr) return;
-
- // Get the direction to move in
- glm::vec2 diff = glm::vec2(
- player->transform->getLocalPosition().x,
- player->transform->getLocalPosition().z
- ) - glm::vec2(
- transform->getLocalPosition().x,
- transform->getLocalPosition().z
- );
-
- if(glm::distance(glm::vec2(), diff) <= 2.0f) {
- this->entityMove->direction = glm::vec2(0, 0);
- } else {
- this->entityMove->direction = diff;
- }
- }, getScene()->eventSceneUpdate);
-}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntityChargePlayer.hpp b/src/dawnrose/scene/components/entity/EntityChargePlayer.hpp
deleted file mode 100644
index fb5a1f1c..00000000
--- a/src/dawnrose/scene/components/entity/EntityChargePlayer.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "scene/SceneItemComponent.hpp"
-#include "scene/components/physics/2d/CharacterController2D.hpp"
-#include "scene/components/PlayerController.hpp"
-#include "scene/components/entity/EntityMove.hpp"
-
-namespace Dawn {
- class EntityChargePlayer : public SceneItemComponent {
- protected:
- CharacterController2D *characterController = nullptr;
- EntityMove *entityMove = nullptr;
-
- public:
- EntityChargePlayer(SceneItem* item);
- std::vector getDependencies() override;
- void onStart() override;
- };
-}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntityHealth.cpp b/src/dawnrose/scene/components/entity/EntityHealth.cpp
index 79a78339..690b221e 100644
--- a/src/dawnrose/scene/components/entity/EntityHealth.cpp
+++ b/src/dawnrose/scene/components/entity/EntityHealth.cpp
@@ -22,34 +22,6 @@ void EntityHealth::onStart() {
this->stunTime -= delta;
}
}, getScene()->eventSceneUpdate);
-
-
- // Hurt Hazard Processing
- // if(this->characterController != nullptr) {
- // useEvent([&](struct CharacterController2DCollisionEventInfo info) {
- // if(this->isInvincible()) return;
-
- // auto hurtHazard = info.collider->item->getComponent();
- // if(hurtHazard == nullptr) return;
- // if(
- // entityFaction != nullptr &&
- // hurtHazard->faction == this->entityFaction->faction
- // ) return;
-
- // glm::vec2 back = glm::vec2(
- // info.collider->transform->getLocalPosition().x,
- // info.collider->transform->getLocalPosition().z
- // ) - glm::vec2(
- // this->transform->getLocalPosition().x,
- // this->transform->getLocalPosition().z
- // );
-
- // this->characterController->velocity = back * -hitKnockback;
- // this->damage({
- // .amount = hurtHazard->damage
- // });
- // }, this->characterController->eventCollision);
- // }
}
bool_t EntityHealth::isInvincible() {
diff --git a/src/dawnrose/scene/components/entity/EntityMove.cpp b/src/dawnrose/scene/components/entity/EntityMove.cpp
index 9b412e3e..11fb5208 100644
--- a/src/dawnrose/scene/components/entity/EntityMove.cpp
+++ b/src/dawnrose/scene/components/entity/EntityMove.cpp
@@ -33,7 +33,7 @@ void EntityMove::onStart() {
// Move
float_t angle = atan2(direction.y, direction.x);
- glm::vec2 movement(cos(angle), sin(angle));
+ glm::vec2 movement(cosf(angle), sinf(angle));
transform->setLocalRotation(glm::quat(glm::vec3(0, -angle + 1.5708f, 0)));
characterController->velocity += movement * delta * moveSpeed;
}, getScene()->eventSceneUpdate);
diff --git a/src/dawnrose/scene/components/entity/EntityRandomWalk.cpp b/src/dawnrose/scene/components/entity/EntityRandomWalk.cpp
deleted file mode 100644
index 940df824..00000000
--- a/src/dawnrose/scene/components/entity/EntityRandomWalk.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "EntityRandomWalk.hpp"
-
-using namespace Dawn;
-
-EntityRandomWalk::EntityRandomWalk(SceneItem* item) : SceneItemComponent(item) {
-
-}
-
-std::vector EntityRandomWalk::getDependencies() {
- return {
- (characterController = item->getComponent()),
- (this->entityMove = item->getComponent())
- };
-}
-
-void EntityRandomWalk::onStart() {
- assertNotNull(characterController);
-
- useEvent([&](float_t delta) {
- // Do we need to pick a new destination
- if(timeLeftUntilNextDecision <= 0.0f) {
- // Pick a new destination to walk to.
- destination = randRange(-walkRange, walkRange);
- destination.x = mathAbs(destination.y) > mathAbs(destination.x) ? 0 : destination.x;
- destination.y = destination.x == 0 ? destination.y : 0;
- destination += glm::vec2(transform->getLocalPosition().x, transform->getLocalPosition().z);
- timeLeftUntilNextDecision = 4.0f;
- } else {
- timeLeftUntilNextDecision -= delta;
- }
-
- // Get the direction to move in
- glm::vec2 diff = destination - glm::vec2(
- transform->getLocalPosition().x,
- transform->getLocalPosition().z
- );
- if(glm::distance(glm::vec2(), diff) <= 1.0f) {
- this->entityMove->direction = glm::vec2(0, 0);
- } else {
- this->entityMove->direction = diff;
- }
- }, getScene()->eventSceneUpdate);
-}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntityRandomWalk.hpp b/src/dawnrose/scene/components/entity/EntityRandomWalk.hpp
deleted file mode 100644
index ba673a56..00000000
--- a/src/dawnrose/scene/components/entity/EntityRandomWalk.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-//
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "util/random.hpp"
-#include "scene/components/physics/2d/CharacterController2D.hpp"
-#include "scene/components/entity/EntityMove.hpp"
-
-namespace Dawn {
- class EntityRandomWalk : public SceneItemComponent {
- protected:
- CharacterController2D *characterController = nullptr;
- EntityMove *entityMove = nullptr;
-
- public:
- // @optional
- float_t timeLeftUntilNextDecision = 0.0f;
- // @optional
- glm::vec2 destination = glm::vec2(0, 0);
- // @optional
- glm::vec2 walkRange = glm::vec2(12.0f, 12.0f);
-
- EntityRandomWalk(SceneItem* item);
- std::vector getDependencies() override;
- void onStart() override;
- };
-}
\ No newline at end of file
diff --git a/src/dawntools/prefabtool/Parsers.hpp b/src/dawntools/prefabtool/Parsers.hpp
index 62715d45..f7c3e378 100644
--- a/src/dawntools/prefabtool/Parsers.hpp
+++ b/src/dawntools/prefabtool/Parsers.hpp
@@ -38,6 +38,14 @@ namespace Dawn {
return v;
}
+ static inline std::string boolParser(std::string v, std::string *error) {
+ v = stringTrim(v);
+ if(v == "true") return "true";
+ if(v == "false") return "false";
+ *error = "Invalid bool value: " + v;
+ return std::string("");
+ }
+
static inline std::string vec2Parser(std::string v, std::string *error) {
// Split string by comma into two strings that we pass into float
auto split = stringSplit(v, ",");
diff --git a/src/dawntools/prefabtool/PrefabComponentParser.cpp b/src/dawntools/prefabtool/PrefabComponentParser.cpp
index 42824dd1..f16ff8c2 100644
--- a/src/dawntools/prefabtool/PrefabComponentParser.cpp
+++ b/src/dawntools/prefabtool/PrefabComponentParser.cpp
@@ -58,6 +58,8 @@ int32_t PrefabComponentParser::onParse(
parser = vec3Parser;
} else if(type == "int32_t" || type == "int") {
parser = intParser;
+ } else if(type == "bool_t") {
+ parser = boolParser;
} else if(type.starts_with("enum")) {
parser = rawParser;
} else if(type.find("*") == (type.size() - 1)) {