Add a distinct sound effect when Hidden Dagger hits a target. Deadly Dash's sound effect updated with a harder hitting sound. Add iframes at the end of Deadly Dash's attack. Footstep playing code now moved into its own function. Appropriate footstep sound plays while Roll is performed. Release Build 10116.

mac-build
sigonasr2 7 months ago
parent 00bb4fd22a
commit bc27f18178
  1. 39
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 3
      Adventures in Lestoria/AdventuresInLestoria.h
  3. 7
      Adventures in Lestoria/Bullet.cpp
  4. 3
      Adventures in Lestoria/Bullet.h
  5. 31
      Adventures in Lestoria/Player.cpp
  6. 6
      Adventures in Lestoria/Thief.cpp
  7. 2
      Adventures in Lestoria/Version.h
  8. 6
      Adventures in Lestoria/assets/config/audio/events.txt
  9. BIN
      Adventures in Lestoria/assets/sounds/dagger_hit.ogg
  10. BIN
      Adventures in Lestoria/assets/sounds/deadlydash.ogg
  11. BIN
      x64/Release/Adventures in Lestoria.exe

@ -586,22 +586,7 @@ void AiL::HandleUserInput(float fElapsedTime){
player->footstepTimer+=GetElapsedTime()*animationSpd; player->footstepTimer+=GetElapsedTime()*animationSpd;
if(player->footstepTimer>"Player.Footstep Timer"_F){ if(player->footstepTimer>"Player.Footstep Timer"_F){
player->footstepTimer-="Player.Footstep Timer"_F; player->footstepTimer-="Player.Footstep Timer"_F;
PlayFootstepSound();
bool inWater=true;
for(const LayerTag&layer:GetCurrentMap().LayerData){
int tileID=layer.tiles[player->GetY()/24][player->GetX()/24]-1;
if(tileID!=-1&&!IsReflectiveTile(GetTileSheet(GetCurrentLevel(),tileID),tileID)){
inWater=false;
break;
}
}
if(inWater){
SoundEffect::PlaySFX("Footstep - Wet",SoundEffect::CENTERED);
}else{
SoundEffect::PlaySFX("Footstep",SoundEffect::CENTERED);
}
} }
#pragma endregion #pragma endregion
}else{ //This means we are holding down movement keys but we aren't actually moving anywhere, so don't. }else{ //This means we are holding down movement keys but we aren't actually moving anywhere, so don't.
@ -4433,4 +4418,26 @@ void AiL::UsingSteamAPI(const bool usingSteam){
void AiL::InitializePlayer(){ void AiL::InitializePlayer(){
player=std::make_unique<Warrior>(); player=std::make_unique<Warrior>();
}
void AiL::SetWorldZoom(float newZoomScale){
targetZoom=newZoomScale;
}
void AiL::PlayFootstepSound(){
bool inWater=true;
for(const LayerTag&layer:GetCurrentMap().LayerData){
int tileID=layer.tiles[player->GetY()/24][player->GetX()/24]-1;
if(tileID!=-1&&!IsReflectiveTile(GetTileSheet(GetCurrentLevel(),tileID),tileID)){
inWater=false;
break;
}
}
if(inWater){
SoundEffect::PlaySFX("Footstep - Wet",SoundEffect::CENTERED);
}else{
SoundEffect::PlaySFX("Footstep",SoundEffect::CENTERED);
}
} }

@ -377,6 +377,9 @@ public:
const HurtList HurtMonsterType(vf2d pos,float radius,int damage,bool upperLevel,float z,const std::string_view monsterName)const; const HurtList HurtMonsterType(vf2d pos,float radius,int damage,bool upperLevel,float z,const std::string_view monsterName)const;
void InitializeGameConfigurations(); void InitializeGameConfigurations();
void InitializePlayer(); void InitializePlayer();
void SetWorldZoom(float newZoomScale);
//Plays the correct footstep sound based on player's current tile.
void PlayFootstepSound();
struct TileGroupData{ struct TileGroupData{
vi2d tilePos; vi2d tilePos;

@ -40,6 +40,7 @@ All rights reserved.
#include "DEFINES.h" #include "DEFINES.h"
#include "safemap.h" #include "safemap.h"
#include "util.h" #include "util.h"
#include "SoundEffect.h"
INCLUDE_ANIMATION_DATA INCLUDE_ANIMATION_DATA
INCLUDE_game INCLUDE_game
@ -50,8 +51,8 @@ INCLUDE_WINDOW_SIZE
Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale,float image_angle) Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col,vf2d scale,float image_angle)
:pos(pos),vel(vel),radius(radius),damage(damage),col(col),friendly(friendly),upperLevel(upperLevel),scale(scale),image_angle(image_angle){}; :pos(pos),vel(vel),radius(radius),damage(damage),col(col),friendly(friendly),upperLevel(upperLevel),scale(scale),image_angle(image_angle){};
Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,std::string animation,bool upperLevel,bool hitsMultiple,float lifetime,bool rotatesWithAngle,bool friendly,Pixel col,vf2d scale,float image_angle) Bullet::Bullet(vf2d pos,vf2d vel,float radius,int damage,std::string animation,bool upperLevel,bool hitsMultiple,float lifetime,bool rotatesWithAngle,bool friendly,Pixel col,vf2d scale,float image_angle,std::string_view hitSound)
:pos(pos),vel(vel),radius(radius),damage(damage),col(col),animated(true),rotates(rotatesWithAngle),lifetime(lifetime),hitsMultiple(hitsMultiple),friendly(friendly),upperLevel(upperLevel),scale(scale),image_angle(image_angle){ :pos(pos),vel(vel),radius(radius),damage(damage),col(col),animated(true),rotates(rotatesWithAngle),lifetime(lifetime),hitsMultiple(hitsMultiple),friendly(friendly),upperLevel(upperLevel),scale(scale),image_angle(image_angle),hitSound(std::string(hitSound)){
this->animation.AddState(animation,ANIMATION_DATA.at(animation)); this->animation.AddState(animation,ANIMATION_DATA.at(animation));
this->animation.ChangeState(internal_animState,animation); this->animation.ChangeState(internal_animState,animation);
}; };
@ -189,11 +190,13 @@ void Bullet::Draw(const Pixel blendCol)const{
BulletDestroyState Bullet::_PlayerHit(Player*player){ BulletDestroyState Bullet::_PlayerHit(Player*player){
const BulletDestroyState destroyBullet=PlayerHit(player); const BulletDestroyState destroyBullet=PlayerHit(player);
if(iframeTimerOnHit>0.f)player->ApplyIframes(iframeTimerOnHit); if(iframeTimerOnHit>0.f)player->ApplyIframes(iframeTimerOnHit);
if(hitSound)SoundEffect::PlaySFX(hitSound.value(),pos);
return destroyBullet; return destroyBullet;
} }
BulletDestroyState Bullet::_MonsterHit(Monster&monster){ BulletDestroyState Bullet::_MonsterHit(Monster&monster){
const BulletDestroyState destroyBullet=MonsterHit(monster); const BulletDestroyState destroyBullet=MonsterHit(monster);
if(iframeTimerOnHit>0.f)monster.ApplyIframes(iframeTimerOnHit); if(iframeTimerOnHit>0.f)monster.ApplyIframes(iframeTimerOnHit);
if(hitSound)SoundEffect::PlaySFX(hitSound.value(),pos);
return destroyBullet; return destroyBullet;
} }
BulletDestroyState Bullet::PlayerHit(Player*player){ BulletDestroyState Bullet::PlayerHit(Player*player){

@ -88,6 +88,7 @@ private:
bool deactivated{false}; bool deactivated{false};
double aliveTime{}; double aliveTime{};
float onContactFadeoutTime{}; //What fadeouttime will be set to when the bullet hits a monster. float onContactFadeoutTime{}; //What fadeouttime will be set to when the bullet hits a monster.
std::optional<std::string>hitSound;
protected: protected:
float drawOffsetY{}; float drawOffsetY{};
BulletDestroyState _PlayerHit(Player*player); //Return true to destroy the bullet on hit, return false otherwise. THE BULLET HIT HAS ALREADY OCCURRED. BulletDestroyState _PlayerHit(Player*player); //Return true to destroy the bullet on hit, return false otherwise. THE BULLET HIT HAS ALREADY OCCURRED.
@ -102,7 +103,7 @@ public:
virtual ~Bullet()=default; virtual ~Bullet()=default;
Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f); Bullet(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f);
//Initializes a bullet with an animation. //Initializes a bullet with an animation.
Bullet(vf2d pos,vf2d vel,float radius,int damage,std::string animation,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool rotatesWithAngle=false,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f); Bullet(vf2d pos,vf2d vel,float radius,int damage,std::string animation,bool upperLevel,bool hitsMultiple=false,float lifetime=INFINITE,bool rotatesWithAngle=false,bool friendly=false,Pixel col=WHITE,vf2d scale={1,1},float image_angle=0.f,std::string_view hitSound="");
public: public:
void SimulateUpdate(const float fElapsedTime); void SimulateUpdate(const float fElapsedTime);

@ -478,19 +478,21 @@ void Player::Update(float fElapsedTime){
animation.UpdateState(internal_animState,fElapsedTime); animation.UpdateState(internal_animState,fElapsedTime);
}break; }break;
case State::ROLL:{ case State::ROLL:{
rolling_timer-=fElapsedTime; footstepTimer-=fElapsedTime;
if(facingDirection==RIGHT)spin_angle+=util::degToRad("Thief.Right Click Ability.Roll Rotation Speed"_F)*fElapsedTime; if(facingDirection==RIGHT)spin_angle+=util::degToRad("Thief.Right Click Ability.Roll Rotation Speed"_F)*fElapsedTime;
else spin_angle-=util::degToRad("Thief.Right Click Ability.Roll Rotation Speed"_F)*fElapsedTime; else spin_angle-=util::degToRad("Thief.Right Click Ability.Roll Rotation Speed"_F)*fElapsedTime;
ySquishFactor=0.5f*sin((PI*fElapsedTime)/"Thief.Right Click Ability.Bounce Period Time"_F)+0.5f; ySquishFactor=0.5f*sin((PI*fElapsedTime)/"Thief.Right Click Ability.Bounce Period Time"_F)+0.5f;
if(rolling_timer<=0.f){ if(rolling_timer<=0.f){
spin_angle=0.f;
ySquishFactor=1.f;
SetState(State::NORMAL); SetState(State::NORMAL);
} }
if(footstepTimer<=0.f){
game->PlayFootstepSound();
footstepTimer=0.05f;
}
}break; }break;
case State::DEADLYDASH:{ case State::DEADLYDASH:{
deadlyDashWaitTimer-=fElapsedTime; deadlyDashWaitTimer-=fElapsedTime;
deadlyDashAfterDashTimer-=fElapsedTime; deadlyDashAdditiveBlendingToggleTimer-=fElapsedTime;
if(deadlyDashWaitTimer<=0.f){ if(deadlyDashWaitTimer<=0.f){
deadlyDashWaitTimer=INFINITY; deadlyDashWaitTimer=INFINITY;
}else }else
@ -499,21 +501,34 @@ void Player::Update(float fElapsedTime){
SetAdditiveBlending(!IsUsingAdditiveBlending()); SetAdditiveBlending(!IsUsingAdditiveBlending());
} }
if(deadlyDashAfterDashTimer<=0.f){ if(deadlyDashAfterDashTimer<=0.f){
deadlyDashAfterDashTimer=INFINITY;
SoundEffect::PlaySFX("Deadly Dash",GetPos()); SoundEffect::PlaySFX("Deadly Dash",GetPos());
SetPos(deadlyDashEndingPos); SetPos(deadlyDashEndingPos);
SetState(State::NORMAL); SetState(State::NORMAL);
SetAdditiveBlending(false); SetAdditiveBlending(false);
game->SetupWorldShake(0.3f);
} }
}break; }break;
default:{ default:{
spin_angle=0.f;
ySquishFactor=1.f;
SetAdditiveBlending(false);
//Update animations normally. //Update animations normally.
animation.UpdateState(internal_animState,fElapsedTime); animation.UpdateState(internal_animState,fElapsedTime);
} }
} }
#pragma region Reset certain state variables after timers expire.
if(deadlyDashAfterDashTimer<=0.f){
deadlyDashAfterDashTimer=INFINITY;
SetAdditiveBlending(false);
game->SetWorldZoom(1.f);
}
if(rolling_timer<=0.f){
rolling_timer=INFINITY;
spin_angle=0.f;
ySquishFactor=1.f;
}
rolling_timer-=fElapsedTime;
deadlyDashAfterDashTimer-=fElapsedTime;
#pragma endregion
float cooldownMultiplier; float cooldownMultiplier;
if(game->GetPlayer()->GetCooldownReductionPct()>=1.0f){ if(game->GetPlayer()->GetCooldownReductionPct()>=1.0f){
cooldownMultiplier=999999; cooldownMultiplier=999999;

@ -111,6 +111,7 @@ void Thief::InitializeClassAbilities(){
float velocity=(0.5f*-p->friction*"Thief.Right Click Ability.Roll Time"_F*"Thief.Right Click Ability.Roll Time"_F-std::clamp(mouseDir.length(),24.f,24.f*"Thief.Right Click Ability.Max Roll Range"_F/100))/-"Thief.Right Click Ability.Roll Time"_F; //Derived from kinetic motion formula. float velocity=(0.5f*-p->friction*"Thief.Right Click Ability.Roll Time"_F*"Thief.Right Click Ability.Roll Time"_F-std::clamp(mouseDir.length(),24.f,24.f*"Thief.Right Click Ability.Max Roll Range"_F/100))/-"Thief.Right Click Ability.Roll Time"_F; //Derived from kinetic motion formula.
p->SetVelocity(mouseDir.vector().norm()*velocity); p->SetVelocity(mouseDir.vector().norm()*velocity);
p->ApplyIframes("Thief.Right Click Ability.Iframe Time"_F); p->ApplyIframes("Thief.Right Click Ability.Iframe Time"_F);
p->footstepTimer=0.f;
return true; return true;
}; };
#pragma endregion #pragma endregion
@ -129,7 +130,7 @@ void Thief::InitializeClassAbilities(){
const float daggerLifetime{"Thief.Ability 1.Dagger Range"_F/"Thief.Ability 1.Dagger Speed"_F}; const float daggerLifetime{"Thief.Ability 1.Dagger Range"_F/"Thief.Ability 1.Dagger Speed"_F};
CreateBullet(Bullet)(p->GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor}.cart(),"Thief.Ability 1.Dagger Radius"_F,p->GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",p->OnUpperLevel(),false,daggerLifetime,true,true)EndBullet; CreateBullet(Bullet)(p->GetPos(),vf2d{"Thief.Ability 1.Dagger Speed"_F,angleToCursor}.cart(),"Thief.Ability 1.Dagger Radius"_F,p->GetAttack()*"Thief.Ability 1.Damage"_I,"dagger.png",p->OnUpperLevel(),false,daggerLifetime,true,true,WHITE,{1.f,1.f},0.f,"Dagger Hit")EndBullet;
p->SetAnimationBasedOnTargetingDirection("IDLE",angleToCursor); p->SetAnimationBasedOnTargetingDirection("IDLE",angleToCursor);
p->SetState(State::RETREAT); p->SetState(State::RETREAT);
SoundEffect::PlaySFX("Thief.Ability 1.Sound"_S,SoundEffect::CENTERED); SoundEffect::PlaySFX("Thief.Ability 1.Sound"_S,SoundEffect::CENTERED);
@ -140,7 +141,7 @@ void Thief::InitializeClassAbilities(){
Thief::ability2.action= Thief::ability2.action=
[](Player*p,vf2d pos={}){ [](Player*p,vf2d pos={}){
game->AddEffect(std::make_unique<ShineEffect>(p->GetPos()+vf2d{4.f,4.f},0.5f,0.5f,"shine.png",1.5f,vf2d{},WHITE,util::random(2*PI),PI/2,true)); game->AddEffect(std::make_unique<ShineEffect>(p->GetPos()+vf2d{4.f,4.f},0.5f,0.5f,"shine.png",1.5f,vf2d{},WHITE,util::random(2*PI),PI/2,true));
p->ApplyIframes("Thief.Ability 2.Initial Wait"_F+"Thief.Ability 2.Ending Wait"_F); p->ApplyIframes("Thief.Ability 2.Initial Wait"_F+"Thief.Ability 2.Ending Wait"_F+0.2f);
geom2d::line mouseDir{p->GetPos(),p->GetWorldAimingLocation()}; geom2d::line mouseDir{p->GetPos(),p->GetWorldAimingLocation()};
p->SetAnimationBasedOnTargetingDirection("DEADLYDASH",mouseDir.vector().polar().y); p->SetAnimationBasedOnTargetingDirection("DEADLYDASH",mouseDir.vector().polar().y);
SoundEffect::PlaySFX("Charge Up",p->GetPos()); SoundEffect::PlaySFX("Charge Up",p->GetPos());
@ -152,6 +153,7 @@ void Thief::InitializeClassAbilities(){
p->SetState(State::DEADLYDASH); p->SetState(State::DEADLYDASH);
p->deadlyDashWaitTimer="Thief.Ability 2.Initial Wait"_F; p->deadlyDashWaitTimer="Thief.Ability 2.Initial Wait"_F;
p->deadlyDashAfterDashTimer=p->deadlyDashWaitTimer+"Thief.Ability 2.Ending Wait"_F; p->deadlyDashAfterDashTimer=p->deadlyDashWaitTimer+"Thief.Ability 2.Ending Wait"_F;
game->SetWorldZoom(1.1f);
return true; return true;
}; };
#pragma endregion #pragma endregion

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1 #define VERSION_MAJOR 1
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 3 #define VERSION_PATCH 3
#define VERSION_BUILD 10109 #define VERSION_BUILD 10116
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -55,6 +55,12 @@ Events
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%) # Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = craft_equip.ogg, 70% File[0] = craft_equip.ogg, 70%
} }
Dagger Hit
{
CombatSound = True
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
File[0] = dagger_hit.ogg, 80%, 50%, 100%
}
Deadly Dash Deadly Dash
{ {
CombatSound = True CombatSound = True

Loading…
Cancel
Save