This commit is contained in:
Vladislav Khorev 2026-04-24 18:40:51 +03:00
parent b4b41e8620
commit 2bb7da2e37
8 changed files with 227397 additions and 37 deletions

BIN
resources/w/gg/new/gg_die001.anim (Stored with Git LFS) Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
resources/w/gg/new/gg_die_idle001.anim (Stored with Git LFS) Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,10 @@
namespace ZL {
const float ATTACK_COOLDOWN_TIME = 3.0f;
const float ATTACK_COOLDOWN_TIME = 2.3f;
extern float x;
extern float y;
const float ATTACK_RANGE = 1.25f;
void Character::loadAnimation(AnimationState state, const std::string& filename, const std::string& zipFile) {
auto& data = animations[state];
@ -131,7 +132,7 @@ void Character::update(int64_t deltaMs) {
battle_state = 0;
}
else if (distToGhost < 10.0f && distToGhost >= 1.f) {
else if (distToGhost < 10.0f && distToGhost >= ATTACK_RANGE) {
setTarget(attackTarget->position);
battle_state = 0;
}
@ -203,6 +204,17 @@ void Character::update(int64_t deltaMs) {
}
}
if (hp <= 0)
{
if (currentState != AnimationState::ACTION_TO_DEATH && currentState != AnimationState::DEATH_IDLE)
{
currentState = AnimationState::ACTION_TO_DEATH;
resetAnim = true;
}
}
else
{
if (battle_state == 1)
{
targetFacingAngle = atan2(lookTarget.x() - position.x(), -(lookTarget.z() - position.z()));
@ -223,11 +235,14 @@ void Character::update(int64_t deltaMs) {
}
if (attack == 1 && currentState == AnimationState::ACTION_IDLE)
{
if (attackTarget != nullptr && attackTarget->hp > 0)
{
currentState = AnimationState::ACTION_ATTACK;
resetAnim = true;
}
}
}
else
{
if (currentState == AnimationState::STAND_TO_ACTION
@ -238,6 +253,7 @@ void Character::update(int64_t deltaMs) {
resetAnim = true;
}
}
}
// Rotate toward target facing angle at constant angular speed
float angleDiff = targetFacingAngle - facingAngle;
@ -262,9 +278,14 @@ void Character::update(int64_t deltaMs) {
resetAnim = false;
anim.currentFrame = 0;
}
//19
int prevFrame = anim.currentFrame;
anim.currentFrame += static_cast<float>(deltaMs) / 24.f;
//std::cout << "Current animation frame: " << anim.currentFrame << " / " << anim.totalFrames << " -- " << anim.lastFrame << std::endl;
/*
if (npcId == "ghost_01x")
{
std::cout << "Current animation frame: " << anim.currentFrame << " / " << anim.totalFrames << " -- " << anim.lastFrame << std::endl;
}*/
if (static_cast<int>(anim.currentFrame) >= 20 && currentState == AnimationState::STAND_TO_ACTION)
{
@ -283,6 +304,27 @@ void Character::update(int64_t deltaMs) {
showWeapon = false;
}
if (isPlayer)
{
if (prevFrame == 18 && static_cast<int>(anim.currentFrame) != 18 && (currentState == AnimationState::ACTION_ATTACK || currentState == AnimationState::ACTION_ATTACK_2))
{
if (attackTarget != nullptr)
{
attackTarget->applyDamage(10.f);
}
}
}
else
{
if (prevFrame == 49 && static_cast<int>(anim.currentFrame) != 49 && (currentState == AnimationState::ACTION_ATTACK || currentState == AnimationState::ACTION_ATTACK_2))
{
if (attackTarget != nullptr)
{
attackTarget->applyDamage(10.f);
}
}
}
int frms = anim.model.animations[0].keyFrames[anim.model.animations[0].keyFrames.size() - 1].frame;
if (static_cast<int>(anim.currentFrame) >= frms) {
anim.currentFrame = anim.model.startingFrame;
@ -290,20 +332,26 @@ void Character::update(int64_t deltaMs) {
if (currentState == AnimationState::STAND_TO_ACTION)
{
currentState = AnimationState::ACTION_IDLE;
resetAnim = true;
//resetAnim = true;
}
if (currentState == AnimationState::ACTION_TO_STAND)
{
currentState = AnimationState::STAND;
resetAnim = true;
//resetAnim = true;
}
if (currentState == AnimationState::ACTION_ATTACK)
{
currentState = AnimationState::ACTION_IDLE;
resetAnim = true;
//resetAnim = true;
attack = 0;
}
if (currentState == AnimationState::ACTION_TO_DEATH)
{
currentState = AnimationState::DEATH_IDLE;
//resetAnim = true;
}
}
@ -317,6 +365,10 @@ void Character::update(int64_t deltaMs) {
}
void Character::draw(Renderer& renderer) {
if (!isPlayer && hp <= 0)
{
return;
}
if (useGpuSkinning) {
drawGpuSkinning(renderer);
return;
@ -482,6 +534,10 @@ void Character::drawAttachedWeapon(Renderer& renderer)
// ==================== Shadow depth pass ====================
void Character::drawShadowDepth(Renderer& renderer) {
if (!isPlayer && hp <= 0)
{
return;
}
if (useGpuSkinning) {
drawShadowDepthGpuSkinning(renderer);
} else {
@ -568,6 +624,10 @@ void Character::drawShadowDepthGpuSkinning(Renderer& renderer) {
// ==================== Main pass with shadows ====================
void Character::drawWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera) {
if (!isPlayer && hp <= 0)
{
return;
}
if (useGpuSkinning) {
drawGpuSkinningWithShadow(renderer, lightFromCamera, shadowMapTex, lightDirCamera);
} else {
@ -695,4 +755,10 @@ void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matri
CheckGlError(__FILE__, __LINE__);
}
void Character::applyDamage(float damageAmount)
{
hp = hp - damageAmount;
if (hp < 0) hp = 0;
}
} // namespace ZL

View File

@ -20,7 +20,9 @@ enum class AnimationState {
ACTION_ATTACK = 3,
ACTION_ATTACK_2 = 4,
ACTION_IDLE = 5,
ACTION_TO_STAND = 6
ACTION_TO_STAND = 6,
ACTION_TO_DEATH = 7,
DEATH_IDLE = 8,
};
class Character {
@ -48,6 +50,9 @@ public:
void drawShadowDepth(Renderer& renderer);
void drawWithShadow(Renderer& renderer, const Eigen::Matrix4f& lightFromCamera, GLuint shadowMapTex, const Eigen::Vector3f& lightDirCamera);
void applyDamage(float damageAmount);
// Public: read by Game for camera tracking and ray-cast origin
Eigen::Vector3f position = Eigen::Vector3f(0.f, 0.f, 0.f);
float facingAngle = 0.0f;
@ -64,6 +69,7 @@ public:
std::string npcId;
std::string npcName;
bool giftReceived = false;
float hp = 100.f;
int battle_state = 0;

View File

@ -516,6 +516,7 @@ namespace ZL
case SDLK_o:
y = y + 0.002;
currentLocation->player->hp = 5;
break;
case SDLK_k:

View File

@ -63,6 +63,9 @@ namespace ZL
player->loadBinaryAnimation(AnimationState::ACTION_ATTACK_2, "resources/w/gg/gg_action_stab001.anim", CONST_ZIP_FILE);
player->loadBinaryAnimation(AnimationState::ACTION_IDLE, "resources/w/gg/gg_action_idle002.anim", CONST_ZIP_FILE);
player->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/gg/new/gg_action_to_stand001.anim", CONST_ZIP_FILE);
player->loadBinaryAnimation(AnimationState::ACTION_TO_DEATH, "resources/w/gg/new/gg_die001.anim", CONST_ZIP_FILE);
player->loadBinaryAnimation(AnimationState::DEATH_IDLE, "resources/w/gg/new/gg_die_idle001.anim", CONST_ZIP_FILE);
player->weaponTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/white.png", CONST_ZIP_FILE));
@ -106,10 +109,15 @@ namespace ZL
npc02->loadBinaryAnimation(AnimationState::ACTION_ATTACK, "resources/w/float_attack003.anim", CONST_ZIP_FILE);
npc02->loadBinaryAnimation(AnimationState::STAND_TO_ACTION, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
npc02->loadBinaryAnimation(AnimationState::ACTION_TO_STAND, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
npc02->loadBinaryAnimation(AnimationState::ACTION_TO_DEATH, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
npc02->loadBinaryAnimation(AnimationState::DEATH_IDLE, "resources/w/default_float001_cut.anim", CONST_ZIP_FILE);
npc02->npcId = "ghost_01x";
npc02->setTexture(ghostTexture);
npc02->walkSpeed = 1.5f;
npc02->rotationSpeed = 8.0f;
npc02->modelScale = 0.01f;
npc02->hp = 30;
//npc02->modelScale = 0.1f;
npc02->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));