Frog animations setup. Frog tongue bullet setup.

pull/30/head
sigonasr2 11 months ago
parent 8e8e145403
commit 1655fe7b51
  1. 5
      Adventures in Lestoria/Adventures in Lestoria.vcxproj
  2. 6
      Adventures in Lestoria/Adventures in Lestoria.vcxproj.filters
  3. 5
      Adventures in Lestoria/AdventuresInLestoria.cpp
  4. 3
      Adventures in Lestoria/AdventuresInLestoria.h
  5. 12
      Adventures in Lestoria/BulletTypes.h
  6. 23
      Adventures in Lestoria/Chapter_1_Creatures_Part_2.txt
  7. 86
      Adventures in Lestoria/FrogTongue.cpp
  8. 4
      Adventures in Lestoria/Monster.cpp
  9. 1
      Adventures in Lestoria/Monster.h
  10. 8
      Adventures in Lestoria/Player.cpp
  11. 2
      Adventures in Lestoria/Player.h
  12. 2
      Adventures in Lestoria/Version.h
  13. 5
      Adventures in Lestoria/Wizard.cpp
  14. 10
      Adventures in Lestoria/assets/Campaigns/1_2.tmx
  15. 10
      Adventures in Lestoria/assets/Campaigns/1_5.tmx
  16. 10
      Adventures in Lestoria/assets/Campaigns/1_7.tmx
  17. 12
      Adventures in Lestoria/assets/config/Monsters.txt
  18. 2
      Adventures in Lestoria/assets/config/gfx/gfx.txt
  19. BIN
      Adventures in Lestoria/assets/items/Frog Skin.png
  20. BIN
      Adventures in Lestoria/assets/monsters/Frog.png
  21. BIN
      Adventures in Lestoria/assets/tongue.png
  22. BIN
      Adventures in Lestoria/assets/tongue_end.png
  23. 7
      Adventures in Lestoria/olcUTIL_Geometry2D.h

@ -564,6 +564,10 @@
</ClCompile>
<ClCompile Include="FallingDebris.h" />
<ClCompile Include="FireBolt.cpp" />
<ClCompile Include="FrogTongue.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="GameState.cpp" />
<ClCompile Include="InventoryConsumableWindow.cpp" />
<ClCompile Include="InventoryCreator.cpp">
@ -704,6 +708,7 @@
<Text Include="assets\config\story\Chapter 1.txt" />
<Text Include="Adventures in Lestoria_Story_Chapter_1 (2).txt" />
<Text Include="Adventures in Lestoria_System_Overview.txt" />
<Text Include="Chapter_1_Creatures_Part_2.txt" />
<Text Include="Merchant%27s Items.txt" />
<Text Include="NewClasses.txt" />
<Text Include="InitialConcept.txt" />

@ -713,6 +713,9 @@
<ClCompile Include="SoundEffect.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FrogTongue.cpp">
<Filter>Source Files\Bullet Types</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />
@ -846,6 +849,9 @@
<Text Include="assets\config\gfx\backdrops.txt">
<Filter>Configurations\GFX</Filter>
</Text>
<Text Include="Chapter_1_Creatures_Part_2.txt">
<Filter>Documentation\Mechanics</Filter>
</Text>
</ItemGroup>
<ItemGroup>
<Image Include="assets\heart.ico">

@ -606,7 +606,7 @@ void AiL::UpdateBullets(float fElapsedTime){
const auto CollisionCheck=[&](){
if(b->friendly){
for(Monster&m:MONSTER_LIST){
if(geom2d::overlaps(geom2d::circle(m.GetPos(),12*m.GetSizeMult()),geom2d::circle(b->pos,b->radius))){
if(geom2d::overlaps(m.Hitbox(),geom2d::circle(b->pos,b->radius))){
if(b->hitList.find(&m)==b->hitList.end()&&m.Hurt(b->damage,b->OnUpperLevel(),0)){
if(!b->hitsMultiple){
if(b->MonsterHit(m)){
@ -619,7 +619,7 @@ void AiL::UpdateBullets(float fElapsedTime){
}
}
} else {
if(geom2d::overlaps(geom2d::circle(player->GetPos(),12*player->GetSizeMult()/2),geom2d::circle(b->pos,b->radius))){
if(geom2d::overlaps(player->Hitbox(),geom2d::circle(b->pos,b->radius))){
if(player->Hurt(b->damage,b->OnUpperLevel(),0)){
if(b->PlayerHit(player.get())){
b->dead=true;
@ -804,7 +804,6 @@ void AiL::RenderWorld(float fElapsedTime){
if(player->teleportAnimationTimer>0){
playerScale.x=120*float(abs(pow(player->teleportAnimationTimer-"Wizard.Right Click Ability.AnimationTime"_F/2,3)));
pos=player->teleportStartPosition.lerp(player->teleportTarget,("Wizard.Right Click Ability.AnimationTime"_F-player->teleportAnimationTimer)/"Wizard.Right Click Ability.AnimationTime"_F);
std::cout<<pos<<std::endl;
}
const std::vector<Buff>attackBuffs=player->GetStatBuffs({"Attack","Attack %"});
view.DrawPartialRotatedDecal(pos+vf2d{0,-player->GetZ()*(std::signbit(scale.y)?-1:1)},player->GetFrame().GetSourceImage()->Decal(),player->GetSpinAngle(),{12,12},player->GetFrame().GetSourceRect().pos,player->GetFrame().GetSourceRect().size,playerScale*scale,attackBuffs.size()>0?Pixel{255,uint8_t(255*abs(sin(1.4*attackBuffs[0].duration))),uint8_t(255*abs(sin(1.4*attackBuffs[0].duration)))}:WHITE);

@ -56,6 +56,9 @@ All rights reserved.
#include "olcPGEX_SplashScreen.h"
#include "olcPixelGameEngine.h"
#define CreateBullet(type) BULLET_LIST.push_back(std::make_unique<type>(type
#define EndBullet ));
class AiL : public olc::PixelGameEngine
{
friend class GameState;

@ -79,3 +79,15 @@ struct ChargedArrow:public Bullet{
bool PlayerHit(Player*player)override;
bool MonsterHit(Monster&monster)override;
};
struct FrogTongue:public Bullet{
vf2d targetPos;
float tongueLength;
float tongueSpd;
float duration;
FrogTongue(vf2d pos,vf2d targetPos,float lifetime,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
void Update(float fElapsedTime)override;
bool PlayerHit(Player*player)override;
bool MonsterHit(Monster&monster)override;
void Draw()override;
};

@ -0,0 +1,23 @@
Wolf
HP: 110
Atk: 12
Move-Spd: 120%
Size: 90%
Strategie: Runs Towards Player, in 400 range it locks on current player position and charges that position with additional 15% move speed.
After Attack 1 second not doing anything.
After that move speed increases by 30% and it disengages on an 800 range where it circles around the player for 3 seconds. after that time move speed resets to normal and it attacks again.
Bear
HP: 210
Atk: 45
Move-Spd: 60%
Size: 200%
Strategie: Moves towards player. Once next to the Player character builds itself up and smashes the ground infront of him. 2 seconds time to dodge attack once it locks the area its attacking.
Frog
HP: 60
Atk: 15
Move-Spd: 70%
Size: 70%
Strategie: Moves with small jumps. if range to player is 350 or lower locks on to player and keep facing its direction without moving for the next 1.5 seconds it will attack the position the player was last in this time frame with another 1 seconds delay. Tongue max range: 450
after attack 0.5 seconds doing nothing then starts again closing the gap or prepares for an attack again depending if range is bigger then 350 again.

@ -0,0 +1,86 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions or derivations of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
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.
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.
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.
Portions of this software are copyright © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "BulletTypes.h"
#include "AdventuresInLestoria.h"
#include "util.h"
INCLUDE_game
INCLUDE_MONSTER_LIST
INCLUDE_GFX
FrogTongue::FrogTongue(vf2d pos,vf2d targetPos,float lifetime,int damage,bool upperLevel,bool friendly,Pixel col)
:Bullet(pos,{},0,damage,upperLevel,friendly,col),targetPos(targetPos),tongueSpd(tongueSpd),tongueLength(0.f){
this->lifetime=lifetime;
duration=lifetime;
}
void FrogTongue::Update(float fElapsedTime){
geom2d::line<float>lineToTarget(pos,targetPos);
tongueLength=util::lerp(0,lineToTarget.length(),sin((lifetime*PI)/duration));
if(!friendly&&geom2d::overlaps(game->GetPlayer()->Hitbox(),lineToTarget)){
PlayerHit(game->GetPlayer());
}
if(friendly){
for(Monster&m:MONSTER_LIST){
if(geom2d::overlaps(m.Hitbox(),lineToTarget)){
MonsterHit(m);
}
}
}
}
bool FrogTongue::PlayerHit(Player*player){
player->Hurt(damage,OnUpperLevel(),0);
deactivated=true;
return false;
}
bool FrogTongue::MonsterHit(Monster&monster){
monster.Hurt(damage,OnUpperLevel(),0);
deactivated=true;
return false;
}
void FrogTongue::Draw(){
geom2d::line<float>lineToTarget(pos,targetPos);
vf2d drawVec=lineToTarget.vector().norm()*3;
vf2d tongueEndPos=geom2d::line<float>(pos+drawVec,targetPos).upoint(sin((lifetime*PI)/duration));
game->view.DrawRotatedDecal(pos+drawVec,GFX["tongue.png"].Decal(),drawVec.polar().y,{0.f,1.f},{tongueLength,1.0f},col);
game->view.DrawRotatedDecal(tongueEndPos,GFX["tongue_end.png"].Decal(),drawVec.polar().y,{2.f,2.f},{1.f,1.f},col);
}

@ -584,3 +584,7 @@ const EventName&Monster::GetDeathSound(){
const EventName&Monster::GetWalkSound(){
return MONSTER_DATA[name].GetWalkSound();
}
geom2d::circle<float>Monster::Hitbox(){
return {GetPos(),12*GetSizeMult()};
}

@ -163,6 +163,7 @@ public:
void SetZ(float z);
const std::function<void(Monster&,float,std::string)>&GetStrategy()const;
void SetSize(float newSize,bool immediate=true);
geom2d::circle<float>Hitbox();
void SetStrategyDrawFunction(std::function<void(AiL*)>func);
std::function<void(AiL*)>strategyDraw=[](AiL*pge){};
const ItemAttributable&GetStats()const;

@ -537,6 +537,10 @@ void Player::Update(float fElapsedTime){
}
}
if(game->GetKey(G).bPressed){
CreateBullet(FrogTongue)(GetPos(),game->GetWorldMousePos(),1.f,10,OnUpperLevel(),true,RED)EndBullet;
}
#pragma region Warrior
switch(GetState()){
case State::SWING_SWORD:{
@ -1216,3 +1220,7 @@ void EntityStats::Reset(){
equipStats.clear();
baseStats.clear();
}
geom2d::circle<float>Player::Hitbox(){
return {GetPos(),12*GetSizeMult()/2};
}

@ -200,6 +200,8 @@ public:
virtual std::string&GetIdleSAnimation()=0;
virtual std::string&GetIdleWAnimation()=0;
geom2d::circle<float>Hitbox();
void CheckEndZoneCollision();
CastInfo&GetCastInfo();

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

@ -136,7 +136,6 @@ void Wizard::InitializeClassAbilities(){
p->teleportAnimationTimer="Wizard.Right Click Ability.AnimationTime"_F;
p->teleportTarget=teleportPoint;
p->teleportStartPosition=p->GetPos();
std::cout<<"Start Position: "<<(p->teleportStartPosition)<<std::endl;
p->iframe_time="Wizard.Right Click Ability.IframeTime"_F;
for(int i=0;i<"Wizard.Right Click Ability.ParticleCount"_I;i++){
game->AddEffect(std::make_unique<Effect>(p->GetPos()+vf2d{(util::random("Wizard.Right Click Ability.ParticleRange"_F/100*2)-"Wizard.Right Click Ability.ParticleRange"_F/100)*12,(util::random("Wizard.Right Click Ability.ParticleRange"_F/100*2)-"Wizard.Right Click Ability.ParticleRange"_F/100)*12},util::random("Wizard.Right Click Ability.ParticleLifetimeMax"_F)+"Wizard.Right Click Ability.ParticleLifetimeMin"_F,"circle.png",p->upperLevel,"Wizard.Right Click Ability.ParticleSize"_F,"Wizard.Right Click Ability.ParticleFadetime"_F,vf2d{util::random("Wizard.Right Click Ability.ParticleSpeedMax"_F*2)+"Wizard.Right Click Ability.ParticleSpeedMin"_F,util::random("Wizard.Right Click Ability.ParticleSpeedMax"_F*2)+"Wizard.Right Click Ability.ParticleSpeedMin"_F},"Wizard.Right Click Ability.ParticleColor"_Pixel));
@ -153,7 +152,7 @@ void Wizard::InitializeClassAbilities(){
Wizard::ability1.action=
[](Player*p,vf2d pos={}){
float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
BULLET_LIST.push_back(std::make_unique<FireBolt>(FireBolt(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F},"Wizard.Ability 1.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 1.InitialDamageMult"_F),p->upperLevel,true,"Wizard.Ability 1.BulletColor"_Pixel)));
CreateBullet(FireBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F},"Wizard.Ability 1.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 1.InitialDamageMult"_F),p->upperLevel,true,"Wizard.Ability 1.BulletColor"_Pixel)EndBullet;
SoundEffect::PlaySFX("Wizard Fire Bolt Shoot",SoundEffect::CENTERED);
return true;
};
@ -162,7 +161,7 @@ void Wizard::InitializeClassAbilities(){
Wizard::ability2.action=
[](Player*p,vf2d pos={}){
float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
BULLET_LIST.push_back(std::make_unique<LightningBolt>(LightningBolt(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F},"Wizard.Ability 2.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 2.DamageMult"_F),p->upperLevel,true,"Wizard.Ability 2.BulletColor"_Pixel)));
CreateBullet(LightningBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F},"Wizard.Ability 2.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 2.DamageMult"_F),p->upperLevel,true,"Wizard.Ability 2.BulletColor"_Pixel)EndBullet;
SoundEffect::PlaySFX("Wizard Lightning Bolt Shoot",SoundEffect::CENTERED);
return true;
};

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="174" height="144" tilewidth="24" tileheight="24" infinite="0" nextlayerid="6" nextobjectid="108">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="174" height="144" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="109">
<properties>
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
@ -1218,4 +1218,12 @@
<point/>
</object>
</objectgroup>
<objectgroup id="6" name="Environmental Sounds">
<object id="108" name="Waterfall Sound" type="AudioEnvironmentalSound" x="1404" y="1014">
<properties>
<property name="Sound Name" propertytype="EnvironmentalSounds" value="Waterfall"/>
</properties>
<point/>
</object>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="250" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="30">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="200" height="250" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="31">
<properties>
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
@ -1109,4 +1109,12 @@
</object>
<object id="29" name="Player Spawn" type="PlayerSpawnLocation" x="1704" y="5448" width="24" height="24"/>
</objectgroup>
<objectgroup id="7" name="Environmental Sounds">
<object id="30" name="Waterfall Sound" type="AudioEnvironmentalSound" x="4313" y="2678">
<properties>
<property name="Sound Name" propertytype="EnvironmentalSounds" value="Waterfall"/>
</properties>
<point/>
</object>
</objectgroup>
</map>

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="225" height="150" tilewidth="24" tileheight="24" infinite="0" nextlayerid="7" nextobjectid="24">
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="right-down" width="225" height="150" tilewidth="24" tileheight="24" infinite="0" nextlayerid="8" nextobjectid="25">
<properties>
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
@ -685,4 +685,12 @@
<object id="22" name="Player Spawn" type="PlayerSpawnLocation" x="1776" y="288" width="24" height="24"/>
<object id="23" name="End Zone" type="EndZone" x="5016" y="2718" width="120" height="120"/>
</objectgroup>
<objectgroup id="7" name="Environmental Sounds">
<object id="24" name="Waterfall Sound" type="AudioEnvironmentalSound" x="3329" y="144">
<properties>
<property name="Sound Name" propertytype="EnvironmentalSounds" value="Waterfall"/>
</properties>
<point/>
</object>
</objectgroup>
</map>

@ -260,14 +260,16 @@ Monsters
#Size of each animation frame
SheetFrameSize = 24,24
# Tongue shoots from (9,13)
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
IdleAnimation = 3, 0.2, PingPong
JumpAnimation = 4, 0.06, PingPong
ShootAnimation = 10, 0.1, OneShot
DeathAnimation = 4, 0.1, OneShot
IdleAnimation = 4, 0.13, PingPong
JumpAnimation = 10, 0.06, Repeat
ShootAnimation = 6, 0.15, PingPong
DeathAnimation = 6, 0.1, OneShot
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Wolf Skin,35%,1,2
DROP[0] = Frog Skin,35%,1,2
Hurt Sound = Monster Hurt
Death Sound = Slime Dead

@ -47,6 +47,8 @@ Images
GFX_Pixel = pixel.png
GFX_Title = title_transparent.png
GFX_TitleBack = title_back.png
GFX_FrogTongue = tongue.png
GFX_FrogTongueEnd = tongue_end.png
# Ability Icons
GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 739 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 904 B

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 513 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

@ -311,12 +311,7 @@ namespace olc
// Linearly interpolate between this vector, and another vector, given normalised parameter 't'
inline constexpr v_2d lerp(const v_2d& v1, const double t) const
{
return this->operator*(T(1.0 - t)) + (v1 * T(t));
}
inline constexpr v_2d operator * (const T& rhs) const
{
return v_2d(this->x * rhs, this->y * rhs);
return (*this) * (T(1.0 - t)) + (v1 * T(t));
}
// Compare if this vector is numerically equal to another

Loading…
Cancel
Save