New attack system tomorrow, bed tonight
This commit is contained in:
@ -9,6 +9,7 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
EntityHealth.cpp
|
||||
EntityAIWalk.cpp
|
||||
EntityMove.cpp
|
||||
EntitySwordAttack.cpp
|
||||
EntityAttackBase.cpp
|
||||
EntityFaction.cpp
|
||||
EntitySwordAttack.cpp
|
||||
)
|
80
src/dawnrose/scene/components/entity/EntityAttackBase.cpp
Normal file
80
src/dawnrose/scene/components/entity/EntityAttackBase.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "EntityAttackBase.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
EntityAttackBase::EntityAttackBase(SceneItem* item) :
|
||||
SceneItemComponent(item),
|
||||
interrupted(false),
|
||||
state(ENTITY_ATTACK_STATE_NOTHING)
|
||||
{
|
||||
}
|
||||
|
||||
void EntityAttackBase::interrupt() {
|
||||
if(!this->isInterruptable()) return;
|
||||
interrupted = true;
|
||||
onAttackInterrupted.invoke();
|
||||
this->attackTime = -1;
|
||||
}
|
||||
|
||||
void EntityAttackBase::attack() {
|
||||
if(!this->canAttack()) return;
|
||||
if(this->isAttacking()) return;
|
||||
interrupted = false;
|
||||
attackTime = 0;
|
||||
state = ENTITY_ATTACK_STATE_RAMP_UP;
|
||||
onAttackRampUpStart.invoke();
|
||||
}
|
||||
|
||||
bool_t EntityAttackBase::isAttacking() {
|
||||
return attackTime >= 0;
|
||||
}
|
||||
|
||||
void EntityAttackBase::onStart() {
|
||||
useEvent([&](float_t delta) {
|
||||
if(!this->isAttacking()) return;
|
||||
this->attackTime += delta;
|
||||
|
||||
switch(state) {
|
||||
case ENTITY_ATTACK_STATE_RAMP_UP: {
|
||||
if(this->attackTime >= this->getAttackRampUpDuration()) {
|
||||
state = ENTITY_ATTACK_STATE_ACTIVE;
|
||||
onAttackRampUpEnd.invoke();
|
||||
onAttackActiveStart.invoke();
|
||||
}
|
||||
} break;
|
||||
|
||||
case ENTITY_ATTACK_STATE_ACTIVE: {
|
||||
if(this->attackTime >= this->getAttackRampUpDuration() + this->getAttackActiveDuration()) {
|
||||
state = ENTITY_ATTACK_STATE_RAMP_DOWN;
|
||||
onAttackActiveEnd.invoke();
|
||||
onAttackRampDownStart.invoke();
|
||||
}
|
||||
} break;
|
||||
|
||||
case ENTITY_ATTACK_STATE_RAMP_DOWN: {
|
||||
if(this->attackTime >= this->getAttackRampUpDuration() + this->getAttackActiveDuration() + this->getAttackRampDownDuration()) {
|
||||
state = ENTITY_ATTACK_STATE_COOLDOWN;
|
||||
onAttackRampDownEnd.invoke();
|
||||
onAttackCooldownStart.invoke();
|
||||
}
|
||||
} break;
|
||||
|
||||
case ENTITY_ATTACK_STATE_COOLDOWN: {
|
||||
if(this->attackTime >= this->getAttackRampUpDuration() + this->getAttackActiveDuration() + this->getAttackRampDownDuration() + this->getAttackCooldownDuration()) {
|
||||
state = ENTITY_ATTACK_STATE_NOTHING;
|
||||
onAttackCooldownEnd.invoke();
|
||||
this->attackTime = -1;
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
assertUnreachable();
|
||||
break;
|
||||
}
|
||||
}, getScene()->eventSceneUpdate);
|
||||
}
|
@ -8,12 +8,21 @@
|
||||
#include "scene/components/entity/EntityFaction.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum EntityAttackState {
|
||||
ENTITY_ATTACK_STATE_RAMP_UP,
|
||||
ENTITY_ATTACK_STATE_ACTIVE,
|
||||
ENTITY_ATTACK_STATE_RAMP_DOWN,
|
||||
ENTITY_ATTACK_STATE_COOLDOWN,
|
||||
ENTITY_ATTACK_STATE_NOTHING
|
||||
};
|
||||
|
||||
class EntityAttackBase : public SceneItemComponent {
|
||||
protected:
|
||||
float_t attackTime = -1;
|
||||
|
||||
public:
|
||||
StateProperty<bool_t> interrupted;
|
||||
StateProperty<enum EntityAttackState> state;
|
||||
StateEvent<> onAttackRampUpStart;
|
||||
StateEvent<> onAttackRampUpEnd;
|
||||
StateEvent<> onAttackActiveStart;
|
||||
@ -24,20 +33,79 @@ namespace Dawn {
|
||||
StateEvent<> onAttackCooldownEnd;
|
||||
StateEvent<> onAttackInterrupted;
|
||||
|
||||
EntitySwordAttack(SceneItem* item);
|
||||
|
||||
EntityAttackBase(SceneItem* item);
|
||||
void onStart() override;
|
||||
|
||||
/**
|
||||
* Returns the duration of the attack ramp up. The ramp up is how long it
|
||||
* takes before the attack starts doing damage. For example, this would be
|
||||
* in a sword attack, how long it takes the player to cock their arm back
|
||||
* before swinging.
|
||||
*
|
||||
* @return The duration of the attack ramp up.
|
||||
*/
|
||||
virtual float_t getAttackRampUpDuration() = 0;
|
||||
|
||||
/**
|
||||
* Returns the duration of the attack active. The active is how long the
|
||||
* attack is doing damage. For example, with a sword this would be the
|
||||
* time that the swing itself is occuring.
|
||||
*
|
||||
* @return The duration of the attack active.
|
||||
*/
|
||||
virtual float_t getAttackActiveDuration() = 0;
|
||||
|
||||
/**
|
||||
* Returns the duration of the attack ramp down. The ramp down is how long
|
||||
* it takes after the attack is done doing damage, but before the cooldown
|
||||
* begins. Example, if swing a heavy sword, this is how long after the
|
||||
* sword hits the ground but before the player has picked the sword back
|
||||
* up.
|
||||
*
|
||||
* @return The duration of the ramp down.
|
||||
*/
|
||||
virtual float_t getAttackRampDownDuration() = 0;
|
||||
|
||||
/**
|
||||
* Returns the duration of the attack cooldown. The cooldown is how long
|
||||
* it takes before the attack can be used again. For example, if someone
|
||||
* shoots a gun, this would be how long it takes to cycle a bullet in a
|
||||
* rifle.
|
||||
*
|
||||
* @return The duration of the attack cooldown.
|
||||
*/
|
||||
virtual float_t getAttackCooldownDuration() = 0;
|
||||
|
||||
/**
|
||||
* Decide whether this attack can be interrupted or not. If this returns
|
||||
* false, then the attack cannot be interrupted.
|
||||
*
|
||||
* @return True if the attack can be interrupted, false otherwise.
|
||||
*/
|
||||
virtual bool_t isInterruptable() = 0;
|
||||
|
||||
virtual void attack() = 0;
|
||||
|
||||
/**
|
||||
* Returns true if this attack can be performed, false otherwise.
|
||||
*
|
||||
* @return True if this attack can be performed, false otherwise.
|
||||
*/
|
||||
virtual bool_t canAttack() = 0;
|
||||
|
||||
/**
|
||||
* Requests this attack to be performed.
|
||||
*/
|
||||
void attack();
|
||||
|
||||
/**
|
||||
* Interrupts the current attack.
|
||||
*/
|
||||
void interrupt();
|
||||
|
||||
/**
|
||||
* Returns true if the entity is currently attacking, false otherwise.
|
||||
*
|
||||
* @return True if the entity is currently attacking, false otherwise.
|
||||
*/
|
||||
bool_t isAttacking();
|
||||
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
@ -1,12 +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/entity/EntityFaction.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
|
||||
}
|
@ -4,35 +4,63 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "EntitySwordAttack.hpp"
|
||||
#include "prefabs/SwordHitbox.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
EntitySwordAttack::EntitySwordAttack(SceneItem* item) :
|
||||
SceneItemComponent(item)
|
||||
{
|
||||
|
||||
EntitySwordAttack::EntitySwordAttack(SceneItem* item) : EntityAttackBase(item) {
|
||||
}
|
||||
|
||||
void EntitySwordAttack::onStart() {
|
||||
attackHitbox = SwordHitbox::create(getScene());
|
||||
attackHitbox->transform.setLocalPosition(glm::vec3(999999999, 0, 0));
|
||||
attackHitbox->transform.setParent(this->transform);
|
||||
EntityAttackBase::onStart();
|
||||
|
||||
useEvent([&](float_t delta) {
|
||||
if(swingTime != -1) swingTime -= delta;
|
||||
}, getScene()->eventSceneUpdate);
|
||||
useEvent([&]{
|
||||
}, this->onAttackRampUpStart);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackRampUpEnd);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackActiveStart);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackActiveEnd);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackRampDownStart);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackRampDownEnd);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackCooldownStart);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackCooldownEnd);
|
||||
|
||||
useEvent([&]{
|
||||
}, this->onAttackInterrupted);
|
||||
}
|
||||
|
||||
void EntitySwordAttack::attack() {
|
||||
// auto entityFaction = this->item->getComponent<EntityFaction>();
|
||||
// auto hazard = attackHitbox->getComponent<HurtHazard>();
|
||||
// this->attackTime = swingTime;
|
||||
// if(hazard != nullptr && entityFaction != nullptr) {
|
||||
// hazard->faction = entityFaction->faction;
|
||||
// }
|
||||
float_t EntitySwordAttack::getAttackRampUpDuration() {
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
bool_t EntitySwordAttack::isAttacking() {
|
||||
// return this->attackTime > 0.0f;
|
||||
float_t EntitySwordAttack::getAttackActiveDuration() {
|
||||
return 0.2f;
|
||||
}
|
||||
|
||||
float_t EntitySwordAttack::getAttackRampDownDuration() {
|
||||
return 0.1f;
|
||||
}
|
||||
|
||||
float_t EntitySwordAttack::getAttackCooldownDuration() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool_t EntitySwordAttack::isInterruptable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool_t EntitySwordAttack::canAttack() {
|
||||
return true;
|
||||
}
|
26
src/dawnrose/scene/components/entity/EntitySwordAttack.hpp
Normal file
26
src/dawnrose/scene/components/entity/EntitySwordAttack.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "EntityAttackBase.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class EntitySwordAttack : public EntityAttackBase {
|
||||
protected:
|
||||
float_t attackTime = -1;
|
||||
|
||||
public:
|
||||
EntitySwordAttack(SceneItem* item);
|
||||
|
||||
void onStart() override;
|
||||
|
||||
float_t getAttackRampUpDuration() override;
|
||||
float_t getAttackActiveDuration() override;
|
||||
float_t getAttackRampDownDuration() override;
|
||||
float_t getAttackCooldownDuration() override;
|
||||
bool_t isInterruptable() override;
|
||||
bool_t canAttack() override;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user