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.

mac-build
sigonasr2 7 months ago
parent bd14a21793
commit f9ad9c4390
  1. 48
      Adventures in Lestoria/Hawk.cpp
  2. 10
      Adventures in Lestoria/Monster.cpp
  3. 2
      Adventures in Lestoria/Monster.h
  4. 2
      Adventures in Lestoria/MonsterAttribute.h
  5. 2
      Adventures in Lestoria/Version.h
  6. 16
      Adventures in Lestoria/assets/config/MonsterStrategies.txt
  7. 5
      Adventures in Lestoria/assets/config/Monsters.txt
  8. 9
      Adventures in Lestoria/assets/config/audio/events.txt
  9. BIN
      Adventures in Lestoria/assets/sounds/wing_flap.ogg
  10. BIN
      Adventures in Lestoria/assets/sounds/wing_flap1.ogg
  11. BIN
      Adventures in Lestoria/assets/sounds/wing_flap2.ogg
  12. BIN
      Adventures in Lestoria/assets/sounds/wing_flap3.ogg
  13. BIN
      Adventures in Lestoria/assets/sounds/wing_flap4.ogg
  14. BIN
      x64/Release/Adventures in Lestoria.exe

@ -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;
}
}

@ -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;
}

@ -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;

@ -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,
};

@ -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

@ -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
{

@ -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

@ -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%)

Loading…
Cancel
Save