mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 02:12:45 +01:00
Melee against on-ground target uses alternate anim
This commit is contained in:
parent
c307a1c5e3
commit
f894718183
@ -688,31 +688,37 @@ bool Activities::UseItem::update(CharacterObject *character,
|
||||
character->playCycle(shootcycle);
|
||||
}
|
||||
} else if (weapon->fireType == WeaponData::MELEE) {
|
||||
/// @todo second attack animation for on-ground targets
|
||||
const auto attackAnimation = shootcycle;
|
||||
auto currentAnim = character->getCurrentCycle();
|
||||
if (currentAnim == shootcycle || currentAnim == throwcycle) {
|
||||
auto fireTime = weapon->animFirePoint / 100.f;
|
||||
auto loopStart = weapon->animLoopStart / 100.f;
|
||||
auto currentTime = animator->getAnimationTime(AnimIndexAction);
|
||||
|
||||
if (character->getCurrentCycle() != attackAnimation) {
|
||||
character->playCycle(attackAnimation);
|
||||
if (currentTime >= fireTime && !fired) {
|
||||
Weapon::meleeHit(weapon, character);
|
||||
fired = true;
|
||||
}
|
||||
|
||||
if (animator->isCompleted(AnimIndexAction)) {
|
||||
if (character->getCurrentState().primaryActive) {
|
||||
animator->setAnimationTime(AnimIndexAction, loopStart);
|
||||
fired = false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto fireTime = weapon->animFirePoint / 100.f;
|
||||
auto loopStart = weapon->animLoopStart / 100.f;
|
||||
auto currentTime = animator->getAnimationTime(AnimIndexAction);
|
||||
|
||||
if (currentTime >= fireTime && !fired) {
|
||||
Weapon::meleeHit(weapon, character);
|
||||
fired = true;
|
||||
}
|
||||
|
||||
if (animator->isCompleted(AnimIndexAction)) {
|
||||
if (character->getCurrentState().primaryActive) {
|
||||
animator->setAnimationTime(AnimIndexAction, loopStart);
|
||||
fired = false;
|
||||
else {
|
||||
const auto onGround = Weapon::targetOnGround(weapon, character);
|
||||
if (onGround) {
|
||||
character->playCycle(throwcycle);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
character->playCycle(shootcycle);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
RW_ERROR("Unrecognized fireType: " << weapon->fireType);
|
||||
return true;
|
||||
|
@ -5,10 +5,12 @@
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "data/WeaponData.hpp"
|
||||
#include "dynamics/HitTest.hpp"
|
||||
#include "engine/GameWorld.hpp"
|
||||
#include "objects/CharacterObject.hpp"
|
||||
#include "objects/ProjectileObject.hpp"
|
||||
|
||||
|
||||
bool WeaponScan::doesDamage(GameObject* target) const {
|
||||
return target != source;
|
||||
}
|
||||
@ -60,3 +62,20 @@ void Weapon::meleeHit(WeaponData* weapon, CharacterObject* character) {
|
||||
character
|
||||
});
|
||||
}
|
||||
|
||||
bool Weapon::targetOnGround(WeaponData *weapon, CharacterObject *character) {
|
||||
const auto center = character->getPosition() + character->getRotation()
|
||||
* weapon->fireOffset;
|
||||
HitTest test {*character->engine->dynamicsWorld};
|
||||
const auto result = test.sphereTest(center, weapon->meleeRadius);
|
||||
bool ground = false;
|
||||
for (const auto& r : result) {
|
||||
if (r.object == character) {
|
||||
continue;
|
||||
}
|
||||
if (r.object->type() == GameObject::Character) {
|
||||
ground |= static_cast<CharacterObject *>(r.object)->isKnockedDown();
|
||||
}
|
||||
}
|
||||
return ground;
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ namespace Weapon {
|
||||
void fireProjectile(WeaponData* weapon, CharacterObject* character, float force);
|
||||
void fireHitscan(WeaponData *weapon, CharacterObject* character);
|
||||
void meleeHit(WeaponData *weapon, CharacterObject* character);
|
||||
bool targetOnGround(WeaponData *weapon, CharacterObject* character);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "loaders/LoaderIFP.hpp"
|
||||
#include "objects/VehicleObject.hpp"
|
||||
|
||||
|
||||
#ifndef BT_BULLET_VERSION
|
||||
#error Unable to find BT_BULLET_VERSION
|
||||
#endif
|
||||
@ -468,6 +469,12 @@ void CharacterObject::SetDead() {
|
||||
currentState.isDead = true;
|
||||
}
|
||||
|
||||
bool CharacterObject::isKnockedDown() const {
|
||||
/// @todo husho says: State in [knocked down, getting up, dying, dead]
|
||||
auto a = animator->getAnimation(AnimIndexMovement);
|
||||
return a == animations->animation(AnimCycle::KnockOutShotFront0);
|
||||
}
|
||||
|
||||
bool CharacterObject::enterVehicle(VehicleObject* vehicle, size_t seat) {
|
||||
if (vehicle) {
|
||||
// Check that the seat is free
|
||||
|
@ -141,6 +141,8 @@ public:
|
||||
void Die();
|
||||
void SetDead();
|
||||
|
||||
bool isKnockedDown() const;
|
||||
|
||||
bool takeDamage(const DamageInfo& damage) override;
|
||||
|
||||
bool enterVehicle(VehicleObject* vehicle, size_t seat);
|
||||
|
Loading…
Reference in New Issue
Block a user