Setup Hawk AI. Fix Hawk Animations. Added a property to ignore tile collisions for monsters. Add in monster artist name in credits. Release Build 9252.

pull/57/head
sigonasr2 7 months ago
parent b2b1fa81cf
commit e9ed495d39
  1. 29
      Adventures in Lestoria/Hawk.cpp
  2. 11
      Adventures in Lestoria/Monster.cpp
  3. 1
      Adventures in Lestoria/Monster.h
  4. 7
      Adventures in Lestoria/MonsterData.cpp
  5. 2
      Adventures in Lestoria/MonsterData.h
  6. 2
      Adventures in Lestoria/Version.h
  7. 12
      Adventures in Lestoria/assets/Campaigns/2_1.tmx
  8. 9
      Adventures in Lestoria/assets/config/MonsterStrategies.txt
  9. 8
      Adventures in Lestoria/assets/config/Monsters.txt
  10. 101
      Adventures in Lestoria/assets/config/credits.txt
  11. BIN
      x64/Release/Adventures in Lestoria.exe

@ -40,13 +40,38 @@ All rights reserved.
#include "Monster.h" #include "Monster.h"
#include "MonsterStrategyHelpers.h" #include "MonsterStrategyHelpers.h"
#include "BulletTypes.h" #include "BulletTypes.h"
#include "util.h"
INCLUDE_ANIMATION_DATA
INCLUDE_BULLET_LIST
INCLUDE_game INCLUDE_game
using A=Attribute; using A=Attribute;
/*
* Attack Strategie: Fly circles at the edge of the Players Screen. every 8 seconds charge on players location to the other corner of the screen.
* */
void Monster::STRATEGY::HAWK(Monster&m,float fElapsedTime,std::string strategy){ void Monster::STRATEGY::HAWK(Monster&m,float fElapsedTime,std::string strategy){
enum PhaseName{
INITIALIZE,
FLYING,
CHARGE
};
switch(m.phase){
case INITIALIZE:{
m.SetZ(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));
}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");
}break;
case CHARGE:{
}break;
}
} }

@ -182,7 +182,7 @@ bool Monster::_SetX(float x,const bool monsterInvoked){
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult())); pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
Moved(); Moved();
return true; return true;
} else { }else{
geom2d::rect<float>collision={collisionRect.pos,collisionRect.size}; geom2d::rect<float>collision={collisionRect.pos,collisionRect.size};
bool insideArenaBounds=true; bool insideArenaBounds=true;
#pragma region Calculate Arena Bounds check for Bosses #pragma region Calculate Arena Bounds check for Bosses
@ -194,7 +194,7 @@ bool Monster::_SetX(float x,const bool monsterInvoked){
} }
#pragma endregion #pragma endregion
#pragma region lambdas #pragma region lambdas
auto NoEnemyCollisionWithTile=[&](){return (isBoss&&insideArenaBounds)||(!isBoss&&!geom2d::overlaps(newPos,collision));}; auto NoEnemyCollisionWithTile=[&](){return IgnoresTerrainCollision()||(isBoss&&insideArenaBounds)||(!isBoss&&!geom2d::overlaps(newPos,collision));};
#pragma endregion #pragma endregion
collision.pos+=tilePos; collision.pos+=tilePos;
if(NoEnemyCollisionWithTile()){ if(NoEnemyCollisionWithTile()){
@ -233,7 +233,7 @@ bool Monster::_SetY(float y,const bool monsterInvoked){
} }
#pragma endregion #pragma endregion
#pragma region lambdas #pragma region lambdas
auto NoEnemyCollisionWithTile=[&](){return (isBoss&&insideArenaBounds)||(!isBoss&&!geom2d::overlaps(newPos,collision));}; auto NoEnemyCollisionWithTile=[&](){return IgnoresTerrainCollision()||(isBoss&&insideArenaBounds)||(!isBoss&&!geom2d::overlaps(newPos,collision));};
#pragma endregion #pragma endregion
collision.pos+=tilePos; collision.pos+=tilePos;
if(NoEnemyCollisionWithTile()){ if(NoEnemyCollisionWithTile()){
@ -986,4 +986,9 @@ void Monster::ProximityKnockback(const vf2d centerPoint,const float knockbackFac
lineToMonster={centerPoint,centerPoint+vf2d{cos(randomDir),sin(randomDir)}*1}; lineToMonster={centerPoint,centerPoint+vf2d{cos(randomDir),sin(randomDir)}*1};
} }
Knockback(lineToMonster.vector().norm()*knockbackFactor); Knockback(lineToMonster.vector().norm()*knockbackFactor);
}
const bool Monster::IgnoresTerrainCollision()const{
return MONSTER_DATA.at(GetName()).IgnoresTerrainCollision();
} }

@ -162,6 +162,7 @@ public:
const Direction GetFacingDirectionToTarget(vf2d target)const; const Direction GetFacingDirectionToTarget(vf2d target)const;
const bool HasFourWaySprites()const; const bool HasFourWaySprites()const;
const bool HasMountedMonster()const; const bool HasMountedMonster()const;
const bool IgnoresTerrainCollision()const;
private: private:
std::string name; std::string name;
vf2d pos; vf2d pos;

@ -159,7 +159,8 @@ void MonsterData::InitializeMonsterData(){
strategyName, strategyName,
DATA["Monsters"][MonsterName]["CollisionDmg"].GetInt() DATA["Monsters"][MonsterName]["CollisionDmg"].GetInt()
); );
if(DATA["Monsters"][MonsterName].HasProperty("Ignore Collisions"))monster.ignoresCollision=DATA["Monsters"][MonsterName]["Ignore Collisions"].GetBool();
if(DATA["Monsters"][MonsterName].HasProperty("Mounted Animation"))monster.mountedAnimName=DATA["Monsters"][MonsterName]["Mounted Animation"].GetString(); 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].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)}; 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)};
@ -398,4 +399,8 @@ const std::optional<const std::string>MonsterData::GetMountedAnimation()const{
const vf2d&MonsterData::GetMountedAnimationOffset()const{ 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!"); 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; return mountedAnimationOffset;
}
const bool MonsterData::IgnoresTerrainCollision()const{
return ignoresCollision;
} }

@ -94,6 +94,7 @@ public:
const bool HasMountedAnimation()const; const bool HasMountedAnimation()const;
const std::optional<const std::string>GetMountedAnimation()const; const std::optional<const std::string>GetMountedAnimation()const;
const vf2d&GetMountedAnimationOffset()const; const vf2d&GetMountedAnimationOffset()const;
const bool IgnoresTerrainCollision()const;
private: private:
std::string name; std::string name;
int hp; int hp;
@ -116,4 +117,5 @@ private:
bool fourWayDirectionalSprites=false; //When this flag is set, a monster has 4-way animations instead of the default 1-direction animation. bool fourWayDirectionalSprites=false; //When this flag is set, a monster has 4-way animations instead of the default 1-direction animation.
std::optional<std::string>mountedAnimName; std::optional<std::string>mountedAnimName;
vf2d mountedAnimationOffset{}; vf2d mountedAnimationOffset{};
bool ignoresCollision{false}; //If set to true, this monster does not run into terrain.
}; };

@ -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 0 #define VERSION_PATCH 0
#define VERSION_BUILD 9247 #define VERSION_BUILD 9252
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="238" height="369" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="43"> <map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="238" height="369" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="46">
<properties> <properties>
<property name="Backdrop" propertytype="Backdrop" value="mountain_day"/> <property name="Backdrop" propertytype="Backdrop" value="mountain_day"/>
<property name="Background Music" propertytype="BGM" value="foresty1_1"/> <property name="Background Music" propertytype="BGM" value="foresty1_1"/>
@ -1922,5 +1922,15 @@
<property name="spawner" type="object" value="15"/> <property name="spawner" type="object" value="15"/>
</properties> </properties>
</object> </object>
<object id="44" template="../maps/Monsters/Hawk.tx" x="4567" y="8053">
<properties>
<property name="spawner" type="object" value="15"/>
</properties>
</object>
<object id="45" template="../maps/Monsters/Hawk.tx" x="4636" y="7938">
<properties>
<property name="spawner" type="object" value="15"/>
</properties>
</object>
</objectgroup> </objectgroup>
</map> </map>

@ -698,7 +698,14 @@ MonsterStrategy
} }
Hawk Hawk
{ {
# Amount of Z (in pixels) the Hawk flies at.
Flight Height = 48
# Amount of Z (in pixels) higher or lower the Hawk chooses to fly at.
Flight Height Variance = 8
# 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
} }
Stone Elemental Stone Elemental
{ {

@ -719,10 +719,12 @@ Monsters
# Animations must be defined in the same order as they are in their sprite sheets # Animations must be defined in the same order as they are in their sprite sheets
# The First Four animations must represent a standing, walking, attack, and death animation. Their names are up to the creator. # 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 IDLE = 1, 0.6, Repeat
JUMP = 1, 0.2, Repeat JUMP = 4, 0.2, Repeat
SHOOT = 1, 0.2, OneShot ATTACK = 2, 0.2, OneShot
DEATH = 1, 0.15, OneShot DEATH = 3, 0.15, OneShot
} }
Ignore Collisions = True
Hurt Sound = Monster Hurt Hurt Sound = Monster Hurt
Death Sound = Slime Dead Death Sound = Slime Dead

@ -17,57 +17,60 @@ Credits
LINE[14]="&" LINE[14]="&"
LINE[15]="#D8F4F5Killer Rabbit Media#FFFFFF" LINE[15]="#D8F4F5Killer Rabbit Media#FFFFFF"
LINE[16]=" " LINE[16]=" "
LINE[17]="Tools & Tech" LINE[17]="Monster Artist"
LINE[18]="~~~~~~~~~~~~~~~~" LINE[18]="#00EBE7Kashif Ali#FFFFFF"
LINE[19]="Game Engine" LINE[19]=" "
LINE[20]="#FE9900javidx9#FFFFFF" LINE[20]="Tools & Tech"
LINE[21]="#FEF500olc::PixelGameEngine v.2.25#FFFFFF" LINE[21]="~~~~~~~~~~~~~~~~"
LINE[22]=" " LINE[22]="Game Engine"
LINE[23]="olcPGEX_MiniAudio Copyright` 2024 by Moros Smith under the OLC-3 License" LINE[23]="#FE9900javidx9#FFFFFF"
LINE[24]=" " LINE[24]="#FEF500olc::PixelGameEngine v.2.25#FFFFFF"
LINE[25]="olcPGEX_ViewPort by Gorbit99" LINE[25]=" "
LINE[26]=" " LINE[26]="olcPGEX_MiniAudio Copyright` 2024 by Moros Smith under the OLC-3 License"
LINE[27]="miniaudio library Copyright` 2024 by David Reid under the MIT No Attribution License" LINE[27]=" "
LINE[28]="Ogg Vorbis audio decoder - v1.22 - public domain http://nothings.org/stb_vorbis/" LINE[28]="olcPGEX_ViewPort by Gorbit99"
LINE[29]=" " LINE[29]=" "
LINE[30]="Portions of this software are copyright ` 2024 The FreeType Project (www.freetype.org). All rights reserved." LINE[30]="miniaudio library Copyright` 2024 by David Reid under the MIT No Attribution License"
LINE[31]=" " LINE[31]="Ogg Vorbis audio decoder - v1.22 - public domain http://nothings.org/stb_vorbis/"
LINE[32]="Assets" LINE[32]=" "
LINE[33]="~~~~~~~~~~~~~~~~" LINE[33]="Portions of this software are copyright ` 2024 The FreeType Project (www.freetype.org). All rights reserved."
LINE[34]="Pokemon-based Nico Yazawa sprite that started it all..." LINE[34]=" "
LINE[35]="DeviantArt: @kirbysmith" LINE[35]="Assets"
LINE[36]=" " LINE[36]="~~~~~~~~~~~~~~~~"
LINE[37]="Animated Slime by Calciumtrice - Creative Commons Attribution 3.0." LINE[37]="Pokemon-based Nico Yazawa sprite that started it all..."
LINE[38]=" " LINE[38]="DeviantArt: @kirbysmith"
LINE[39]="ERA OF FANTASY - GRASSLANDS" LINE[39]=" "
LINE[40]="X: @Namatnieks" LINE[40]="Animated Slime by Calciumtrice - Creative Commons Attribution 3.0."
LINE[41]=" " LINE[41]=" "
LINE[42]="*** Minifantasy - Tiny Overworld v1.0 ***" LINE[42]="ERA OF FANTASY - GRASSLANDS"
LINE[43]="Minifantasy is an original idea by Krishna Palacio" LINE[43]="X: @Namatnieks"
LINE[44]=" " LINE[44]=" "
LINE[45]="Public Domain Font Authors" LINE[45]="*** Minifantasy - Tiny Overworld v1.0 ***"
LINE[46]="c64esque by andraaspar" LINE[46]="Minifantasy is an original idea by Krishna Palacio"
LINE[47]="Habbo by Omni" LINE[47]=" "
LINE[48]="Unknown by Anonymous" LINE[48]="Public Domain Font Authors"
LINE[49]=" " LINE[49]="c64esque by andraaspar"
LINE[50]="Nb Pixel Font Bundle" LINE[50]="Habbo by Omni"
LINE[51]="Nb Pixel Font Bundle 2" LINE[51]="Unknown by Anonymous"
LINE[52]=" " LINE[52]=" "
LINE[53]=" " LINE[53]="Nb Pixel Font Bundle"
LINE[54]="Game License" LINE[54]="Nb Pixel Font Bundle 2"
LINE[55]="~~~~~~~~~~~~~~~~" LINE[55]=" "
LINE[56]="License (OLC-3)" LINE[56]=" "
LINE[57]="~~~~~~~~~~~~~~~" LINE[57]="Game License"
LINE[58]=" " LINE[58]="~~~~~~~~~~~~~~~~"
LINE[59]="Copyright ` 2024 Sig Productions <niconiconii@lestoria.net>" LINE[59]="License (OLC-3)"
LINE[60]=" " LINE[60]="~~~~~~~~~~~~~~~"
LINE[61]="Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:" LINE[61]=" "
LINE[62]=" " LINE[62]="Copyright ` 2024 Sig Productions <niconiconii@lestoria.net>"
LINE[63]="1. Redistributions or derivations of source code must retain the above copyright notice, this list of conditions and the following disclaimer." LINE[63]=" "
LINE[64]=" " LINE[64]="Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:"
LINE[65]="2. Redistributions or derivative works in binary form must reproduce the above copyright notice. This list of conditions and the following disclaimer must be reproduced in the documentation and/or other materials provided with the distribution." LINE[65]=" "
LINE[66]=" " LINE[66]="1. Redistributions or derivations of source code must retain the above copyright notice, this list of conditions and the following disclaimer."
LINE[67]="3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission." LINE[67]=" "
LINE[68]=" " LINE[68]="2. Redistributions or derivative works in binary form must reproduce the above copyright notice. This list of conditions and the following disclaimer must be reproduced in the documentation and/or other materials provided with the distribution."
LINE[69]="THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." LINE[69]=" "
LINE[70]="3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission."
LINE[71]=" "
LINE[72]="THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
} }
Loading…
Cancel
Save