Add in Hawk attack sequence. Add wing flap sound effects. Fix bug with charging towards ground attack not quite reaching ground level. Release Build 9256.

This commit is contained in:
sigonasr2 2024-05-10 02:53:35 -05:00
parent bd14a21793
commit f9ad9c4390
14 changed files with 81 additions and 13 deletions

View File

@ -41,6 +41,7 @@ All rights reserved.
#include "MonsterStrategyHelpers.h"
#include "BulletTypes.h"
#include "util.h"
#include "SoundEffect.h"
INCLUDE_game
@ -54,24 +55,59 @@ void Monster::STRATEGY::HAWK(Monster&m,float fElapsedTime,std::string strategy){
enum PhaseName{
INITIALIZE,
FLYING,
PREPARE_CHARGE,
CHARGE
};
#pragma region Flying Hover Effect
m.SetZ(std::max(m.F(A::FLYING_HEIGHT)+ConfigFloat("Flight Oscillation Amount")*sin((PI*m.TimeSpentAlive())/1.5f),0.f));
#pragma endregion
switch(m.phase){
case INITIALIZE:{
m.SetZ(ConfigFloat("Flight Height")-ConfigFloat("Flight Height Variance")+util::random_range(0,ConfigFloat("Flight Height Variance")*2));
m.F(A::TARGET_FLYING_HEIGHT)=m.F(A::FLYING_HEIGHT)=ConfigFloat("Flight Height")-ConfigFloat("Flight Height Variance")+util::random_range(0,ConfigFloat("Flight Height Variance")*2);
m.B(A::RANDOM_DIRECTION)=int(util::random_range(0,2));
m.phase=FLYING;
m.AddBuff(BuffType::SELF_INFLICTED_SLOWDOWN,INFINITE,util::random_range(0,ConfigFloat("Flight Speed Variance")/100));
m.F(A::ATTACK_COOLDOWN)=util::random_range(1.f,ConfigFloat("Flight Charge Cooldown"));
}break;
case FLYING:{
float dirToPlayer{util::pointTo(game->GetPlayer()->GetPos(),m.GetPos()).polar().y};
dirToPlayer+=m.B(A::RANDOM_DIRECTION)?0.25*PI:-0.25*PI;
m.target=game->GetPlayer()->GetPos()+vf2d{ConfigFloat("Flight Distance"),dirToPlayer}.cart();
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
m.F(A::ATTACK_COOLDOWN)-=fElapsedTime;
if(m.F(A::FLYING_HEIGHT)<m.F(A::TARGET_FLYING_HEIGHT))m.F(A::FLYING_HEIGHT)=std::min(m.F(A::TARGET_FLYING_HEIGHT),m.F(A::FLYING_HEIGHT)+ConfigFloat("Attack Z Speed")*fElapsedTime);
if(m.F(A::ATTACK_COOLDOWN)<=0){
m.F(A::CASTING_TIMER)=ConfigFloat("Attack Wait Time");
m.phase=PREPARE_CHARGE;
}else{
float dirToPlayer{util::pointTo(game->GetPlayer()->GetPos(),m.GetPos()).polar().y};
dirToPlayer+=m.B(A::RANDOM_DIRECTION)?0.25*PI:-0.25*PI;
m.target=game->GetPlayer()->GetPos()+vf2d{ConfigFloat("Flight Distance"),dirToPlayer}.cart();
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
}
}break;
case PREPARE_CHARGE:{
m.F(A::CASTING_TIMER)-=fElapsedTime;
m.UpdateFacingDirection(game->GetPlayer()->GetPos());
m.PerformAnimation("ATTACK");
if(m.F(A::CASTING_TIMER)<=0){
m.phase=CHARGE;
m.PerformAnimation("ATTACKING");
m.target=geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).rpoint(ConfigFloat("Flight Distance")*2.f);
m.UpdateFacingDirection(m.target);
}
}break;
case CHARGE:{
m.B(A::IGNORE_DEFAULT_ANIMATIONS)=true;
if(m.F(A::FLYING_HEIGHT)>-ConfigFloat("Flight Oscillation Amount"))m.F(A::FLYING_HEIGHT)=std::max(-ConfigFloat("Flight Oscillation Amount"),m.F(A::FLYING_HEIGHT)-ConfigFloat("Attack Z Speed")*fElapsedTime);
m.targetAcquireTimer=1.f;
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
float distToTarget=geom2d::line<float>(m.GetPos(),m.target).length();
if(distToTarget<12.f){
m.F(A::TARGET_FLYING_HEIGHT)=ConfigFloat("Flight Height")-ConfigFloat("Flight Height Variance")+util::random_range(0,ConfigFloat("Flight Height Variance")*2);
m.phase=FLYING;
m.F(A::ATTACK_COOLDOWN)=ConfigFloat("Flight Charge Cooldown");
m.PerformJumpAnimation();
}
m.B(A::IGNORE_DEFAULT_ANIMATIONS)=false;
}break;
}
}

View File

@ -267,6 +267,7 @@ bool Monster::Update(float fElapsedTime){
lastHitPlayer=std::max(0.f,lastHitPlayer-fElapsedTime);
lastPathfindingCooldown=std::max(0.f,lastPathfindingCooldown-fElapsedTime);
lastFacingDirectionChange+=fElapsedTime;
timeSpentAlive+=fElapsedTime;
if(size!=targetSize){
if(size>targetSize){
@ -391,11 +392,14 @@ void Monster::UpdateFacingDirection(vf2d facingTargetPoint){
}
}
void Monster::Draw()const{
Pixel blendCol=GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE;
if(GetZ()>0){
vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24);
game->view.DrawDecal(GetPos()-vf2d{3,3}*shadowScale/2+vf2d{0,6*GetSizeMult()},GFX["circle.png"].Decal(),shadowScale,BLACK);
blendCol.a=160;
}
Pixel blendCol=GetBuffs(BuffType::SLOWDOWN).size()>0?Pixel{uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(255*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration))),uint8_t(128+127*abs(sin(1.4*GetBuffs(BuffType::SLOWDOWN)[0].duration)))}:WHITE;
game->view.DrawPartialRotatedDecal(GetPos()-vf2d{0,GetZ()},GetFrame().GetSourceImage()->Decal(),spriteRot,GetFrame().GetSourceRect().size/2,GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*(!HasFourWaySprites()&&GetFacingDirection()==Direction::EAST?-1:1),GetSizeMult()),blendCol);
if(overlaySprite.length()!=0){
@ -991,4 +995,8 @@ void Monster::ProximityKnockback(const vf2d centerPoint,const float knockbackFac
const bool Monster::IgnoresTerrainCollision()const{
return MONSTER_DATA.at(GetName()).IgnoresTerrainCollision();
}
const float Monster::TimeSpentAlive()const{
return timeSpentAlive;
}

View File

@ -163,6 +163,7 @@ public:
const bool HasFourWaySprites()const;
const bool HasMountedMonster()const;
const bool IgnoresTerrainCollision()const;
const float TimeSpentAlive()const;
private:
std::string name;
vf2d pos;
@ -232,6 +233,7 @@ private:
float lastFacingDirectionChange=0.f; //How much time has passed since the last facing direction change. Used to ensure another facing direction change doesn't happen too quickly. Probably allowing one every quarter second is good enough.
std::vector<DeathSpawnInfo>deathData; //Data that contains further actions and information when this monster dies. Mostly used to spawn sub-monsters from a defeated monster.
vf2d mountedSprOffset{};
float timeSpentAlive{0.f};
private:
struct STRATEGY{
static std::string ERR;

View File

@ -114,4 +114,6 @@ enum class Attribute{
PERCEPTION_LEVEL,
INITIALIZED_MOUNTED_MONSTER,
IGNORE_DEFAULT_ANIMATIONS, //If set to true, movement scripts like move towards and run away will not play their animations and leave it up to the monster strategy itself. This can be useful for overrides when trying to play other attack animations etc.
FLYING_HEIGHT,
TARGET_FLYING_HEIGHT,
};

View File

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 0
#define VERSION_BUILD 9252
#define VERSION_BUILD 9261
#define stringify(a) stringify_(a)
#define stringify_(a) #a

View File

@ -698,14 +698,24 @@ MonsterStrategy
}
Hawk
{
Wing Flap Frequency = 0.8s
# Amount of Z (in pixels) the Hawk flies at.
Flight Height = 48
Flight Height = 48px
# Amount of Z (in pixels) higher or lower the Hawk chooses to fly at.
Flight Height Variance = 8
Flight Height Variance = 8px
# 0-X% application of a slowdown debuff to vary the speeds of each Hawk.
Flight Speed Variance = 20%
# How far from the player the Hawk circles around.
Flight Distance = 240
Flight Distance = 240px
Flight Oscillation Amount = 1.5px
# Dropdown/Rising speed in pixels per second while attacking.
Attack Z Speed = 160px/s
Flight Charge Cooldown = 8s
Attack Wait Time = 1s
}
Stone Elemental
{

View File

@ -720,15 +720,16 @@ Monsters
# The First Four animations must represent a standing, walking, attack, and death animation. Their names are up to the creator.
IDLE = 1, 0.6, Repeat
JUMP = 4, 0.2, Repeat
ATTACK = 2, 0.2, OneShot
ATTACKING = 2, 0.2, OneShot
DEATH = 3, 0.15, OneShot
ATTACK = 4, 0.1, Repeat
}
Ignore Collisions = True
Hurt Sound = Monster Hurt
Death Sound = Slime Dead
Walk Sound = Slime Walk
Walk Sound = Wing Flap
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
# DROP[0] = Ring of the Bear,100%,1,1

View File

@ -285,6 +285,15 @@ Events
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = warrior_sonicslash.ogg, 70%
}
Wing Flap
{
CombatSound = True
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = wing_flap1.ogg, 100%
File[1] = wing_flap2.ogg, 100%
File[2] = wing_flap3.ogg, 100%
File[3] = wing_flap4.ogg, 100%
}
Wisp Hit
{
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.