diff --git a/assets/games/rose/prefabs/Player.xml b/assets/games/rose/prefabs/Player.xml
index b481160d..a82e13b2 100644
--- a/assets/games/rose/prefabs/Player.xml
+++ b/assets/games/rose/prefabs/Player.xml
@@ -6,6 +6,8 @@
+
+
diff --git a/assets/games/rose/prefabs/SwordHitbox.xml b/assets/games/rose/prefabs/SwordHitbox.xml
new file mode 100644
index 00000000..f236f4dd
--- /dev/null
+++ b/assets/games/rose/prefabs/SwordHitbox.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/games/rose/prefabs/Urchin.xml b/assets/games/rose/prefabs/Urchin.xml
index 8615562f..0b8e0dfb 100644
--- a/assets/games/rose/prefabs/Urchin.xml
+++ b/assets/games/rose/prefabs/Urchin.xml
@@ -6,6 +6,5 @@
-
-
+
\ No newline at end of file
diff --git a/src/dawnrose/CMakeLists.txt b/src/dawnrose/CMakeLists.txt
index 32584930..39725090 100644
--- a/src/dawnrose/CMakeLists.txt
+++ b/src/dawnrose/CMakeLists.txt
@@ -21,4 +21,5 @@ add_subdirectory(scene)
set(ROSE_ASSETS_DIR ${DAWN_ASSETS_DIR}/games/rose)
tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Player.xml)
tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Urchin.xml)
-tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Crab.xml)
\ No newline at end of file
+tool_prefab(${ROSE_ASSETS_DIR}/prefabs/Crab.xml)
+tool_prefab(${ROSE_ASSETS_DIR}/prefabs/SwordHitbox.xml)
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/HurtHazard.hpp b/src/dawnrose/scene/components/HurtHazard.hpp
index c779d8b0..6c1f7aa0 100644
--- a/src/dawnrose/scene/components/HurtHazard.hpp
+++ b/src/dawnrose/scene/components/HurtHazard.hpp
@@ -5,11 +5,13 @@
#pragma once
#include "scene/SceneItemComponent.hpp"
+#include "scene/components/entity/EntityFaction.hpp"
namespace Dawn {
class HurtHazard : public SceneItemComponent {
public:
int32_t damage = 1;
+ enum Faction faction = FACTION_NONE;
HurtHazard(SceneItem* item);
};
diff --git a/src/dawnrose/scene/components/PlayerController.cpp b/src/dawnrose/scene/components/PlayerController.cpp
index a1fb4d05..a9c138ab 100644
--- a/src/dawnrose/scene/components/PlayerController.cpp
+++ b/src/dawnrose/scene/components/PlayerController.cpp
@@ -14,16 +14,13 @@ PlayerController::PlayerController(SceneItem *item) : SceneItemComponent(item) {
std::vector PlayerController::getDependencies() {
return {
- (this->characterController = item->getComponent()),
- (this->entityHealth = item->getComponent()),
- (this->entityMove = item->getComponent())
+ (this->entityMove = item->getComponent()),
+ (this->entitySwordAttack = item->getComponent())
};
}
void PlayerController::onStart() {
- assertNotNull(this->characterController);
assertNotNull(this->entityMove);
- assertNotNull(this->entityHealth);
useEvent([&](float_t delta){
// Movement
@@ -31,27 +28,9 @@ void PlayerController::onStart() {
INPUT_BIND_NEGATIVE_X, INPUT_BIND_POSITIVE_X,
INPUT_BIND_NEGATIVE_Y, INPUT_BIND_POSITIVE_Y
);
+
+ if(this->entitySwordAttack != nullptr && getGame()->inputManager.isPressed(INPUT_BIND_ACCEPT)) {
+ this->entitySwordAttack->attack();
+ }
}, getScene()->eventSceneUpdate);
-
- // Hurt Hazard Processing
- useEvent([&](struct CharacterController2DCollisionEventInfo info) {
- if(entityHealth->isInvincible()) return;
-
- auto hurtHazard = info.collider->item->getComponent();
- if(hurtHazard == nullptr) 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->entityHealth->damage({
- .amount = hurtHazard->damage
- });
- }, this->characterController->eventCollision);
-
}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/PlayerController.hpp b/src/dawnrose/scene/components/PlayerController.hpp
index ab7aff6c..29fe79c5 100644
--- a/src/dawnrose/scene/components/PlayerController.hpp
+++ b/src/dawnrose/scene/components/PlayerController.hpp
@@ -4,22 +4,16 @@
// https://opensource.org/licenses/MIT
#pragma once
-#include "scene/components/physics/2d/CharacterController2D.hpp"
-#include "scene/components/HurtHazard.hpp"
-#include "scene/components/entity/EntityHealth.hpp"
#include "scene/components/entity/EntityMove.hpp"
+#include "scene/components/entity/EntitySwordAttack.hpp"
namespace Dawn {
class PlayerController : public SceneItemComponent {
protected:
- CharacterController2D *characterController;
- EntityHealth *entityHealth;
- EntityMove *entityMove;
+ EntityMove *entityMove = nullptr;
+ EntitySwordAttack *entitySwordAttack = nullptr;
public:
- // @optional
- float_t hitKnockback = 20.0f;
-
PlayerController(SceneItem *item);
std::vector getDependencies() override;
void onStart() override;
diff --git a/src/dawnrose/scene/components/entity/CMakeLists.txt b/src/dawnrose/scene/components/entity/CMakeLists.txt
index 8c97609a..dd1d9a13 100644
--- a/src/dawnrose/scene/components/entity/CMakeLists.txt
+++ b/src/dawnrose/scene/components/entity/CMakeLists.txt
@@ -10,4 +10,6 @@ target_sources(${DAWN_TARGET_NAME}
EntityHealth.cpp
EntityRandomWalk.cpp
EntityMove.cpp
+ EntitySwordAttack.cpp
+ EntityFaction.cpp
)
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntityChargePlayer.cpp b/src/dawnrose/scene/components/entity/EntityChargePlayer.cpp
index 050b0436..4870305d 100644
--- a/src/dawnrose/scene/components/entity/EntityChargePlayer.cpp
+++ b/src/dawnrose/scene/components/entity/EntityChargePlayer.cpp
@@ -13,12 +13,14 @@ EntityChargePlayer::EntityChargePlayer(SceneItem* item) : SceneItemComponent(ite
std::vector EntityChargePlayer::getDependencies() {
return {
- (characterController = item->getComponent())
+ (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
@@ -26,7 +28,7 @@ void EntityChargePlayer::onStart() {
if(player == nullptr) return;
// Get the direction to move in
- glm::vec2 pos = glm::vec2(
+ glm::vec2 diff = glm::vec2(
player->transform->getLocalPosition().x,
player->transform->getLocalPosition().z
) - glm::vec2(
@@ -34,14 +36,10 @@ void EntityChargePlayer::onStart() {
transform->getLocalPosition().z
);
- // Conver to an angle and then convert back into a 2D vector. This mimics a
- // user essentially "moving the analogue stick in this direction"
-
- if(mathAbs(pos.x) > 1.0f || mathAbs(pos.y) > 1.0f) {
- float_t angle = atan2(pos.y, pos.x);
- glm::vec2 movement(cos(angle), sin(angle));
- transform->setLocalRotation(glm::quat(glm::vec3(0, -angle + 1.5708f, 0)));
- characterController->velocity += movement * delta * moveSpeed;
+ 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
index c89c9bfe..fb5a1f1c 100644
--- a/src/dawnrose/scene/components/entity/EntityChargePlayer.hpp
+++ b/src/dawnrose/scene/components/entity/EntityChargePlayer.hpp
@@ -7,16 +7,15 @@
#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:
- // @optional
- float_t moveSpeed = 30.0f;
-
EntityChargePlayer(SceneItem* item);
std::vector getDependencies() override;
void onStart() override;
diff --git a/src/dawnrose/scene/components/entity/EntityFaction.cpp b/src/dawnrose/scene/components/entity/EntityFaction.cpp
new file mode 100644
index 00000000..64b799e3
--- /dev/null
+++ b/src/dawnrose/scene/components/entity/EntityFaction.cpp
@@ -0,0 +1,12 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "EntityFaction.hpp"
+
+using namespace Dawn;
+
+EntityFaction::EntityFaction(SceneItem* item) : SceneItemComponent(item) {
+
+}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntityFaction.hpp b/src/dawnrose/scene/components/entity/EntityFaction.hpp
new file mode 100644
index 00000000..31d0b80d
--- /dev/null
+++ b/src/dawnrose/scene/components/entity/EntityFaction.hpp
@@ -0,0 +1,23 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "scene/SceneItemComponent.hpp"
+
+namespace Dawn {
+ enum Faction {
+ FACTION_NONE,
+ FACTION_ENEMY,
+ FACTION_PLAYER
+ };
+
+ class EntityFaction : public SceneItemComponent {
+ public:
+ // @optional
+ enum Faction faction = FACTION_NONE;
+
+ EntityFaction(SceneItem* item);
+ };
+}
\ 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 66e90fff..9c96b8cf 100644
--- a/src/dawnrose/scene/components/entity/EntityHealth.cpp
+++ b/src/dawnrose/scene/components/entity/EntityHealth.cpp
@@ -11,7 +11,15 @@ EntityHealth::EntityHealth(SceneItem* item) : SceneItemComponent(item) {
}
+std::vector EntityHealth::getDependencies() {
+ return {
+ this->characterController = this->item->getComponent(),
+ this->entityFaction = this->item->getComponent()
+ };
+}
+
void EntityHealth::onStart() {
+ // Update
useEvent([&](float_t delta){
if(this->invincibleTime > 0.0f) {
this->invincibleTime -= delta;
@@ -21,6 +29,32 @@ void EntityHealth::onStart() {
this->stunTime -= delta;
}
}, getScene()->eventSceneUpdate);
+
+
+ // Hurt Hazard Processing
+ 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/EntityHealth.hpp b/src/dawnrose/scene/components/entity/EntityHealth.hpp
index ec8e0a29..419a57b6 100644
--- a/src/dawnrose/scene/components/entity/EntityHealth.hpp
+++ b/src/dawnrose/scene/components/entity/EntityHealth.hpp
@@ -5,6 +5,9 @@
#pragma once
#include "scene/SceneItemComponent.hpp"
+#include "scene/components/entity/EntityFaction.hpp"
+#include "scene/components/physics/2d/CharacterController2D.hpp"
+#include "scene/components/HurtHazard.hpp"
namespace Dawn {
struct DamageInformation {
@@ -14,6 +17,10 @@ namespace Dawn {
};
class EntityHealth : public SceneItemComponent {
+ protected:
+ EntityFaction *entityFaction = nullptr;
+ CharacterController2D *characterController = nullptr;
+
public:
// @optional
int32_t health = 10;
@@ -23,8 +30,11 @@ namespace Dawn {
float_t invincibleTime = 0.0f;
// @optional
float_t stunTime = 0.0f;
+ // @optional
+ float_t hitKnockback = 20.0f;
EntityHealth(SceneItem* item);
+ std::vector getDependencies() override;
void onStart() override;
/**
diff --git a/src/dawnrose/scene/components/entity/EntityMove.cpp b/src/dawnrose/scene/components/entity/EntityMove.cpp
index 129a1f22..9b412e3e 100644
--- a/src/dawnrose/scene/components/entity/EntityMove.cpp
+++ b/src/dawnrose/scene/components/entity/EntityMove.cpp
@@ -14,7 +14,8 @@ EntityMove::EntityMove(SceneItem* item) : SceneItemComponent(item) {
std::vector EntityMove::getDependencies() {
return {
(characterController = item->getComponent()),
- (this->entityHealth = item->getComponent())
+ (this->entityHealth = item->getComponent()),
+ (this->entitySwordAttack = item->getComponent())
};
}
@@ -23,8 +24,9 @@ void EntityMove::onStart() {
assertNotNull(this->entityHealth);
useEvent([&](float_t delta) {
- // Don't move if stunned.
+ // Don't move if stunned or attacking.
if(entityHealth->isStunned()) return;
+ if(entitySwordAttack != nullptr && entitySwordAttack->isAttacking()) return;
// Don't move if no move.
if(direction.x == 0 && direction.y == 0) return;
diff --git a/src/dawnrose/scene/components/entity/EntityMove.hpp b/src/dawnrose/scene/components/entity/EntityMove.hpp
index 9b754841..097e6661 100644
--- a/src/dawnrose/scene/components/entity/EntityMove.hpp
+++ b/src/dawnrose/scene/components/entity/EntityMove.hpp
@@ -7,12 +7,14 @@
#include "scene/SceneItemComponent.hpp"
#include "scene/components/physics/2d/CharacterController2D.hpp"
#include "scene/components/entity/EntityHealth.hpp"
+#include "scene/components/entity/EntitySwordAttack.hpp"
namespace Dawn {
class EntityMove : public SceneItemComponent {
protected:
CharacterController2D *characterController = nullptr;
EntityHealth *entityHealth = nullptr;
+ EntitySwordAttack *entitySwordAttack = nullptr;
public:
// @optional
diff --git a/src/dawnrose/scene/components/entity/EntitySwordAttack.cpp b/src/dawnrose/scene/components/entity/EntitySwordAttack.cpp
new file mode 100644
index 00000000..24561661
--- /dev/null
+++ b/src/dawnrose/scene/components/entity/EntitySwordAttack.cpp
@@ -0,0 +1,49 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "EntitySwordAttack.hpp"
+#include "prefabs/SwordHitbox.hpp"
+
+using namespace Dawn;
+
+EntitySwordAttack::EntitySwordAttack(SceneItem* item) :
+ SceneItemComponent(item),
+ attackTime(0.0f)
+{
+
+}
+
+void EntitySwordAttack::onStart() {
+ attackHitbox = SwordHitbox::create(getScene());
+ attackHitbox->transform.setLocalPosition(glm::vec3(999999999, 0, 0));
+ attackHitbox->transform.setParent(this->transform);
+
+ useEvent([&](float_t delta) {
+ if(this->attackTime > 0.0f) {
+ this->attackTime = this->attackTime - delta;
+ }
+ }, getScene()->eventSceneUpdate);
+
+ useEffect([&]{
+ if(attackTime <= 0) {
+ attackHitbox->transform.setLocalPosition(glm::vec3(999999999, 0, 0));
+ } else {
+ attackHitbox->transform.setLocalPosition(this->attackOffset);
+ }
+ }, attackTime);
+}
+
+void EntitySwordAttack::attack() {
+ auto entityFaction = this->item->getComponent();
+ auto hazard = attackHitbox->getComponent();
+ this->attackTime = swingTime;
+ if(hazard != nullptr && entityFaction != nullptr) {
+ hazard->faction = entityFaction->faction;
+ }
+}
+
+bool_t EntitySwordAttack::isAttacking() {
+ return this->attackTime > 0.0f;
+}
\ No newline at end of file
diff --git a/src/dawnrose/scene/components/entity/EntitySwordAttack.hpp b/src/dawnrose/scene/components/entity/EntitySwordAttack.hpp
new file mode 100644
index 00000000..24882d2e
--- /dev/null
+++ b/src/dawnrose/scene/components/entity/EntitySwordAttack.hpp
@@ -0,0 +1,30 @@
+// 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/entity/EntityFaction.hpp"
+
+namespace Dawn {
+ class EntitySwordAttack : public SceneItemComponent {
+ protected:
+ SceneItem *attackHitbox = nullptr;
+
+ public:
+ // @optional
+ StateProperty attackTime;
+
+ // @optional
+ glm::vec3 attackOffset = glm::vec3(0, 0, 1);
+
+ // @optional
+ float_t swingTime = 0.5f;
+
+ EntitySwordAttack(SceneItem* item);
+ void onStart() override;
+ void attack();
+ bool_t isAttacking();
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/prefabtool/PrefabComponentParser.cpp b/src/dawntools/prefabtool/PrefabComponentParser.cpp
index 10e5cb1d..ef626dfc 100644
--- a/src/dawntools/prefabtool/PrefabComponentParser.cpp
+++ b/src/dawntools/prefabtool/PrefabComponentParser.cpp
@@ -59,6 +59,8 @@ int32_t PrefabComponentParser::onParse(
parser = vec3Parser;
} else if(type == "int32_t" || type == "int") {
parser = intParser;
+ } else if(type.starts_with("enum")) {
+ parser = rawParser;
} else if(type.find("*") == (type.size() - 1)) {
type = type.substr(0, type.size() - 1);
parser = rawParser;
@@ -66,7 +68,7 @@ int32_t PrefabComponentParser::onParse(
name = name.substr(1, name.size());
parser = rawParser;
} else {
- *error = "Unkown parser for type: " + type + "::" + name;
+ *error = "Unknown parser for type: " + type + "::" + name;
return 1;
}