diff --git a/Adventures in Lestoria/Monster.h b/Adventures in Lestoria/Monster.h index 0f3d6b3b..8b9cfcf7 100644 --- a/Adventures in Lestoria/Monster.h +++ b/Adventures in Lestoria/Monster.h @@ -226,7 +226,7 @@ private: float knockUpZAmt=0.f; //Spawns the drops a monster would drop as if they were defeated. Returns what items were dropped and their amounts. std::mapSpawnDrops(); - float prevFacingDirectionAngle=0.f; //Keeps track of the angle of the previous target to ensure four-way sprite facing changes don't happen too early or spastically. + float prevFacingDirectionAngle=PI; //Keeps track of the angle of the previous target to ensure four-way sprite facing changes don't happen too early or spastically. 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::vectordeathData; //Data that contains further actions and information when this monster dies. Mostly used to spawn sub-monsters from a defeated monster. vf2d mountedSprOffset{}; diff --git a/Adventures in Lestoria/MonsterData.cpp b/Adventures in Lestoria/MonsterData.cpp index d73f3886..eb633c19 100644 --- a/Adventures in Lestoria/MonsterData.cpp +++ b/Adventures in Lestoria/MonsterData.cpp @@ -160,6 +160,12 @@ void MonsterData::InitializeMonsterData(){ DATA["Monsters"][MonsterName]["CollisionDmg"].GetInt() ); + if(DATA["Monsters"][MonsterName].HasProperty("Mounted Animation"))monster.mountedAnimName=DATA["Monsters"][MonsterName]["Mounted Animation"].GetString(); + if(DATA["Monsters"][MonsterName].HasProperty("Mounted Animation Offset")){ + if(DATA["Monsters"][MonsterName]["Mounted Animation Offset"].GetValueCount()==2)monster.mountedAnimationOffset={DATA["Monsters"][MonsterName]["Mounted Animation Offset"].GetReal(0),DATA["Monsters"][MonsterName]["Mounted Animation Offset"].GetReal(1)}; + else ERR(std::format("WARNING! Monster {} containing a mounted animation offset has {} for reading in a vector, when vectors are supposed to only have two values! Please check the \"Mounted Animation Offset\" configuration value for {}",MonsterName,DATA["Monsters"][MonsterName]["Mounted Animation Offset"].GetValueCount(),MonsterName)); + } + if(hasFourWaySpriteSheet)monster.SetUsesFourWaySprites(); for(size_t animationRow=0;const std::string&animationName:animations){ @@ -380,3 +386,16 @@ const std::string MonsterData::GetDefaultShootAnimation()const{ const std::string MonsterData::GetDefaultDeathAnimation()const{ return GetDeathAnimation(Direction::SOUTH); } + +const bool MonsterData::HasMountedAnimation()const{ + return mountedAnimName.has_value(); +} +const std::optionalMonsterData::GetMountedAnimation()const{ + if(!HasMountedAnimation())ERR("WARNING! Trying to get a mounted animation for a monster that doesn't have a mounted animation to begin with!"); + return mountedAnimName.value(); +} + +const vf2d&MonsterData::GetMountedAnimationOffset()const{ + if(!HasMountedAnimation())ERR("WARNING! Trying to get a mounted animation offset for a monster that doesn't have a mounted animation to begin with!"); + return mountedAnimationOffset; +} \ No newline at end of file diff --git a/Adventures in Lestoria/MonsterData.h b/Adventures in Lestoria/MonsterData.h index 9a8280d6..1752f486 100644 --- a/Adventures in Lestoria/MonsterData.h +++ b/Adventures in Lestoria/MonsterData.h @@ -59,26 +59,6 @@ struct MonsterDropData{ }; struct MonsterData{ -private: - std::string name; - int hp; - int atk; - uint32_t xp; - float moveSpd;//1.0=100% - float size; - std::unordered_setanimations; - std::string idleAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_IDLE, but IDLE) - std::string jumpAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_JUMP, but JUMP) - std::string shootAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_SHOOT, but SHOOT) - std::string deathAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_DEATH, but DEATH) - std::string strategy; - int collisionDmg; - EventName hurtSound=""; - EventName deathSound=""; - EventName walkSound=""; - std::vector dropData; - bool isNPC=false; - bool fourWayDirectionalSprites=false; //When this flag is set, a monster has 4-way animations instead of the default 1-direction animation. public: MonsterData(); MonsterData(std::string name,int hp,int atk,const uint32_t xp,std::vectordrops,float moveSpd=1.0f,float size=1.0f,std::string strategy="Run Towards",int collisionDmg=0); @@ -111,4 +91,29 @@ public: static std::mapimgs; const bool HasFourWaySprites()const; void SetUsesFourWaySprites(); + const bool HasMountedAnimation()const; + const std::optionalGetMountedAnimation()const; + const vf2d&GetMountedAnimationOffset()const; +private: + std::string name; + int hp; + int atk; + uint32_t xp; + float moveSpd;//1.0=100% + float size; + std::unordered_setanimations; + std::string idleAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_IDLE, but IDLE) + std::string jumpAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_JUMP, but JUMP) + std::string shootAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_SHOOT, but SHOOT) + std::string deathAnimation="WARRIOR_IDLE_S"; //Represents the basic animation name, not the full animation name that ANIMATION_DATA indexes into!! (Ex. Not GREEN_SLIME_DEATH, but DEATH) + std::string strategy; + int collisionDmg; + EventName hurtSound=""; + EventName deathSound=""; + EventName walkSound=""; + std::vector dropData; + bool isNPC=false; + bool fourWayDirectionalSprites=false; //When this flag is set, a monster has 4-way animations instead of the default 1-direction animation. + std::optionalmountedAnimName; + vf2d mountedAnimationOffset{}; }; \ No newline at end of file diff --git a/Adventures in Lestoria/SpawnEncounterLabel.h b/Adventures in Lestoria/SpawnEncounterLabel.h index a8852c08..a339f238 100644 --- a/Adventures in Lestoria/SpawnEncounterLabel.h +++ b/Adventures in Lestoria/SpawnEncounterLabel.h @@ -49,26 +49,42 @@ class SpawnEncounterLabel:public MenuLabel{ std::string monsterName; Animate2D::Animationanim; Animate2D::AnimationState state; + std::optional>mounted_anim; + std::optionalmounted_state; public: inline SpawnEncounterLabel(geom2d::rectrect,std::string label,std::string monsterName) :MenuLabel(rect,label),monsterName(monsterName){ anim.AddState("IDLE",ANIMATION_DATA.at(std::format("{}_{}",monsterName,MONSTER_DATA.at(monsterName).GetDefaultIdleAnimation()))); anim.ChangeState(state,"IDLE"); anim.UpdateState(state,util::random(1)); + if(MONSTER_DATA.at(monsterName).HasMountedAnimation()){ + mounted_state=Animate2D::AnimationState{}; + mounted_anim=Animate2D::Animation{}; + + std::string mountedAnimName=std::format("{}",MONSTER_DATA.at(monsterName).GetMountedAnimation().value()); + + if(MONSTER_DATA.at(monsterName).HasFourWaySprites())mountedAnimName=std::format("{}_{}",MONSTER_DATA.at(monsterName).GetMountedAnimation().value(),int(Direction::SOUTH)); + + mounted_anim.value().AddState(mountedAnimName,ANIMATION_DATA.at(mountedAnimName)); + mounted_anim.value().ChangeState(mounted_state.value(),mountedAnimName); + } } - inline ~SpawnEncounterLabel(){ - - } + inline ~SpawnEncounterLabel()=default; protected: virtual void inline Update(AiL*game)override{ MenuComponent::Update(game); anim.UpdateState(state,game->GetElapsedTime()); + if(mounted_anim.has_value())mounted_anim.value().UpdateState(mounted_state.value(),game->GetElapsedTime()); } virtual void inline DrawDecal(ViewPort&window,bool focused)override{ const geom2d::rect&imgRect=anim.GetFrame(state).GetSourceRect(); vf2d imgSize=vf2d{rect.size.y,rect.size.y}; vf2d imgScale=imgSize/vf2d{imgRect.size}; window.DrawPartialDecal(rect.pos,imgSize,anim.GetFrame(state).GetSourceImage()->Decal(),imgRect.pos,imgRect.size); + if(mounted_anim.has_value()){ + const geom2d::rect&mountedImgRect=mounted_anim.value().GetFrame(mounted_state.value()).GetSourceRect(); + window.DrawPartialDecal(rect.pos+MONSTER_DATA.at(monsterName).GetMountedAnimationOffset()*imgScale,imgSize,mounted_anim.value().GetFrame(mounted_state.value()).GetSourceImage()->Decal(),mountedImgRect.pos,mountedImgRect.size); + } float verticalAlignYOffset=(rect.size.y-8)/2; vf2d monsterNameTextSize=game->GetTextSizeProp(monsterName); float textXSpaceAvailable=rect.size.x-imgSize.x-4-16/*12 for the scrollbar*/; diff --git a/Adventures in Lestoria/Version.h b/Adventures in Lestoria/Version.h index d3e55391..9406fb91 100644 --- a/Adventures in Lestoria/Version.h +++ b/Adventures in Lestoria/Version.h @@ -39,7 +39,7 @@ All rights reserved. #define VERSION_MAJOR 1 #define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_BUILD 9207 +#define VERSION_BUILD 9220 #define stringify(a) stringify_(a) #define stringify_(a) #a diff --git a/Adventures in Lestoria/assets/config/Monsters.txt b/Adventures in Lestoria/assets/config/Monsters.txt index 7f8b2671..9885f157 100644 --- a/Adventures in Lestoria/assets/config/Monsters.txt +++ b/Adventures in Lestoria/assets/config/Monsters.txt @@ -659,6 +659,10 @@ Monsters # Setting this to true means every four rows indicates one animation, the ordering of the directions is: NORTH, EAST, SOUTH, WEST 4-Way Spritesheet = True + + # For monsters that have a mounted portion, this will specify the animation to use. + Mounted Animation = GOBLIN_BOW_MOUNTED + Mounted Animation Offset = 0,-10 Animations { diff --git a/x64/Release/Adventures in Lestoria.exe b/x64/Release/Adventures in Lestoria.exe index aa506a9a..0067ae6b 100644 Binary files a/x64/Release/Adventures in Lestoria.exe and b/x64/Release/Adventures in Lestoria.exe differ