Adjust sword slash effect to accept config values. Add DrawPartialSquishedRotatedDecal to PGE. Performs rotation transform before scale transformation. Add thief animations to animation databases. Setup thief's auto attack ability. Release Build 10053.

mac-build
sigonasr2 5 months ago
parent 477c3ab086
commit 10f5521ec2
  1. 20
      Adventures in Lestoria/Animation.cpp
  2. 4
      Adventures in Lestoria/Effect.h
  3. 17
      Adventures in Lestoria/Player.cpp
  4. 6
      Adventures in Lestoria/SwordSlash.cpp
  5. 9
      Adventures in Lestoria/TODO.txt
  6. 50
      Adventures in Lestoria/Thief.cpp
  7. 2
      Adventures in Lestoria/Version.h
  8. 2
      Adventures in Lestoria/Warrior.cpp
  9. 3
      Adventures in Lestoria/assets/config/Player.txt
  10. 2
      Adventures in Lestoria/assets/config/classes/Warrior.txt
  11. 2
      Adventures in Lestoria/assets/config/gfx/gfx.txt
  12. BIN
      Adventures in Lestoria/assets/gamepack.pak
  13. BIN
      Adventures in Lestoria/assets/nico-thief.png
  14. BIN
      Adventures in Lestoria/assets/nico-thief.xcf
  15. 32
      Adventures in Lestoria/olcPixelGameEngine.h
  16. BIN
      x64/Release/Adventures in Lestoria.exe

@ -211,6 +211,26 @@ void sig::Animation::InitializeAnimations(){
}
ANIMATION_DATA["WIZARD_CAST_W"]=pl_wizard_cast_w;
//Thief animations.
SetupClassWalkIdleAnimations(GFX["nico-thief.png"],"THIEF");
Animate2D::FrameSequence pl_thief_swing_s(0.05f),pl_thief_swing_n(0.05f),pl_thief_swing_e(0.05f),pl_thief_swing_w(0.05f);
for (int i=0;i<4;i++){
pl_thief_swing_s.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,0}*24,{24,24}}});
}
for (int i=0;i<4;i++){
pl_thief_swing_n.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,1}*24,{24,24}}});
}
for (int i=0;i<4;i++){
pl_thief_swing_w.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,2}*24,{24,24}}});
}
for (int i=0;i<4;i++){
pl_thief_swing_e.AddFrame({&GFX["nico-thief.png"],{vi2d{4+i,3}*24,{24,24}}});
}
ANIMATION_DATA["THIEF_SWINGSWORD_N"]=pl_thief_swing_n;
ANIMATION_DATA["THIEF_SWINGSWORD_E"]=pl_thief_swing_e;
ANIMATION_DATA["THIEF_SWINGSWORD_S"]=pl_thief_swing_s;
ANIMATION_DATA["THIEF_SWINGSWORD_W"]=pl_thief_swing_w;
CreateHorizontalAnimationSequence("ground-slam-attack-back.png",5,{64,64},{0.02f,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence("ground-slam-attack-front.png",5,{64,64},{0.02f,Animate2D::Style::OneShot});
CreateHorizontalAnimationSequence("battlecry_effect.png",5,{84,84},{0.02f,Animate2D::Style::OneShot});

@ -97,10 +97,12 @@ struct PulsatingFire:Effect{
};
struct SwordSlash:Effect{
SwordSlash(float lifetime,std::string imgFile,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false);
SwordSlash(float lifetime,std::string imgFile,float damageMult, float swordSweepAngle,vf2d size={1,1},float fadeout=0.0f,vf2d spd={},Pixel col=WHITE,float rotation=0,float rotationSpd=0,bool additiveBlending=false);
bool Update(float fElapsedTime)override;
private:
HitList hitList;
const float damageMult;
const float swordSweepAngle;
};
//This draws effects using screen coordinates instead of world coordinates, useful for applying effects directly on the screen.

@ -1019,8 +1019,7 @@ void Player::SetAnimationBasedOnTargetingDirection(float targetDirection){
auto FacingNorth=[&](){return targetDirection>=-3*PI/4&&targetDirection<-PI/4;};
switch(GetClass()){
case Class::WARRIOR:
case Class::THIEF:{
case Class::WARRIOR:{
if(FacingNorth()){
UpdateAnimation("WARRIOR_SWINGSWORD_N");
}else
@ -1049,6 +1048,20 @@ void Player::SetAnimationBasedOnTargetingDirection(float targetDirection){
UpdateAnimation("RANGER_SHOOT_E");
}
}break;
case Class::THIEF:{
if(FacingNorth()){
UpdateAnimation("THIEF_SWINGSWORD_N");
}else
if(FacingSouth()){
UpdateAnimation("THIEF_SWINGSWORD_S");
}else
if(FacingWest()){
UpdateAnimation("THIEF_SWINGSWORD_W");
}else
if(FacingEast()){
UpdateAnimation("THIEF_SWINGSWORD_E");
}
}break;
}
}

@ -41,12 +41,12 @@ All rights reserved.
INCLUDE_game
SwordSlash::SwordSlash(float lifetime, std::string imgFile, vf2d size, float fadeout, vf2d spd, Pixel col, float rotation, float rotationSpd, bool additiveBlending)
:Effect(game->GetPlayer()->GetPos(),lifetime,imgFile,game->GetPlayer()->OnUpperLevel(),size,fadeout,spd,col,rotation,rotationSpd,additiveBlending){}
SwordSlash::SwordSlash(float lifetime, std::string imgFile,float damageMult, float swordSweepAngle,vf2d size, float fadeout, vf2d spd, Pixel col, float rotation, float rotationSpd, bool additiveBlending)
:damageMult(damageMult),swordSweepAngle(swordSweepAngle),Effect(game->GetPlayer()->GetPos(),lifetime,imgFile,game->GetPlayer()->OnUpperLevel(),size,fadeout,spd,col,rotation,rotationSpd,additiveBlending){}
bool SwordSlash::Update(float fElapsedTime){
if(lifetime>0){
game->HurtConeNotHit(game->GetPlayer()->GetPos(),game->GetPlayer()->GetAttackRangeMult()*12.f,rotation,util::degToRad("Warrior.Auto Attack.SwordSlashSweepAngle"_F),game->GetPlayer()->GetAttack(),hitList,game->GetPlayer()->OnUpperLevel(),game->GetPlayer()->GetZ(),HurtType::MONSTER);
game->HurtConeNotHit(game->GetPlayer()->GetPos(),game->GetPlayer()->GetAttackRangeMult()*12.f,rotation,util::degToRad(swordSweepAngle),game->GetPlayer()->GetAttack()*damageMult,hitList,game->GetPlayer()->OnUpperLevel(),game->GetPlayer()->GetZ(),HurtType::MONSTER);
}
pos=game->GetPlayer()->GetPos();

@ -27,3 +27,12 @@ PGETinker notes
===============
Changing zoom size does not affect the indentation breadcumb immediately (requires scrolling to change the view)
Enabling javid mode does not immediately re-evaluate code.
Adding new class animations
===========================
Player.txt contains animation names the player has to have loaded.
<className>.cpp contains walk and idle animation references that must be loaded in the Initialize() function.
Animation.cpp contains the SetupClassWalkIdleAnimations() function which all classes need to implement with their spritesheet and class name (all caps) to create the WALK and IDLE animations in the animation database.
All other custom player class animations must be added here too.

@ -41,6 +41,7 @@ All rights reserved.
#include "Effect.h"
#include "AdventuresInLestoria.h"
#include "config.h"
#include "SoundEffect.h"
INCLUDE_MONSTER_LIST
INCLUDE_BULLET_LIST
@ -48,14 +49,14 @@ INCLUDE_game
void Thief::Initialize(){
READFROMCONFIG(Thief,THIEF);
Thief::idle_n="WARRIOR_IDLE_N";
Thief::idle_e="WARRIOR_IDLE_E";
Thief::idle_s="WARRIOR_IDLE_S";
Thief::idle_w="WARRIOR_IDLE_W";
Thief::walk_n="WARRIOR_WALK_N";
Thief::walk_e="WARRIOR_WALK_E";
Thief::walk_s="WARRIOR_WALK_S";
Thief::walk_w="WARRIOR_WALK_W";
Thief::idle_n="THIEF_IDLE_N";
Thief::idle_e="THIEF_IDLE_E";
Thief::idle_s="THIEF_IDLE_S";
Thief::idle_w="THIEF_IDLE_W";
Thief::walk_n="THIEF_WALK_N";
Thief::walk_e="THIEF_WALK_E";
Thief::walk_s="THIEF_WALK_S";
Thief::walk_w="THIEF_WALK_W";
}
SETUP_CLASS(Thief)
@ -65,7 +66,38 @@ void Thief::OnUpdate(float fElapsedTime){
}
bool Thief::AutoAttack(){
return false;
bool attack=false;
Monster*closest=nullptr;
float closest_dist=999999;
for(std::unique_ptr<Monster>&m:MONSTER_LIST){
if(m->IsAlive()&&
geom2d::overlaps(geom2d::circle<float>(GetPos(),attack_range*GetSizeMult()*12),geom2d::circle<float>(m->GetPos(),m->GetSizeMult()*12))&&
geom2d::line<float>(GetWorldAimingLocation(),m->GetPos()).length()<closest_dist){
closest_dist=geom2d::line<float>(GetWorldAimingLocation(),m->GetPos()).length();
closest=&*m;
}
}
float targetDirection;
if(closest!=nullptr){
float dirToEnemy=geom2d::line<float>(GetPos(),closest->GetPos()).vector().polar().y;
targetDirection=dirToEnemy;
SetAnimationBasedOnTargetingDirection(dirToEnemy);
}else{
float dirToMouse=geom2d::line<float>(GetPos(),GetWorldAimingLocation()).vector().polar().y;
targetDirection=dirToMouse;
SetAnimationBasedOnTargetingDirection(dirToMouse);
}
attack_cooldown_timer=ATTACK_COOLDOWN-GetAttackRecoveryRateReduction();
swordSwingTimer="Thief.Auto Attack.SwordAnimationSwingTime"_F;
game->AddEffect(std::make_unique<SwordSlash>(0.125f,"swordslash.png"s,"Thief.Auto Attack.DamageMult"_F,"Thief.Auto Attack.SwordSlashSweepAngle"_F,vf2d{0.9f,0.9f}*"Thief.Auto Attack.Range"_F/100.f,0.1f,vf2d{0.f,0.f},WHITE,targetDirection));
SetState(State::SWING_SWORD);
SoundEffect::PlaySFX("Warrior Auto Attack",SoundEffect::CENTERED);
return true;
}
void Thief::InitializeClassAbilities(){
#pragma region Thief Right-click Ability (???)

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

@ -94,7 +94,7 @@ bool Warrior::AutoAttack(){
attack_cooldown_timer=ATTACK_COOLDOWN-GetAttackRecoveryRateReduction();
swordSwingTimer="Warrior.Auto Attack.SwordAnimationSwingTime"_F;
game->AddEffect(std::make_unique<SwordSlash>(0.125f,"swordslash.png"s,vf2d{0.9f,0.9f}*"Warrior.Auto Attack.Range"_F/100.f,0.1f,vf2d{0.f,0.f},WHITE,targetDirection));
game->AddEffect(std::make_unique<SwordSlash>(0.125f,"swordslash.png"s,"Warrior.Auto Attack.DamageMult"_F,"Warrior.Auto Attack.SwordSlashSweepAngle"_F,vf2d{0.9f,0.9f}*"Warrior.Auto Attack.Range"_F/100.f,0.1f,vf2d{0.f,0.f},WHITE,targetDirection));
SetState(State::SWING_SWORD);
SoundEffect::PlaySFX("Warrior Auto Attack",SoundEffect::CENTERED);

@ -83,6 +83,9 @@ Player
PLAYER_ANIMATION[9] = WIZARD_ATTACK
PLAYER_ANIMATION[10] = WIZARD_CAST
PLAYER_ANIMATION[11] = WIZARD_IDLE
PLAYER_ANIMATION[12] = THIEF_IDLE
PLAYER_ANIMATION[13] = THIEF_WALK
PLAYER_ANIMATION[14] = THIEF_SWINGSWORD
}

@ -14,7 +14,7 @@ Warrior
Auto Attack
{
DamageMult = 1
DamageMult = 1x
Range = 150
Cooldown = 0.35
# Whether or not this ability cancels casts.

@ -108,6 +108,8 @@ Images
GFX_Feather = feather.png
GFX_LargeRock = large_rock.png
GFX_Thief_Sheet = nico-thief.png
# Ability Icons
GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png
GFX_Warrior_Block_Icon = Ability Icons/block.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

@ -1144,6 +1144,7 @@ namespace olc
// Draws a decal rotated to specified angle, wit point of rotation offset
void DrawRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE);
void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
void DrawPartialSquishedRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE);
// Draws a multiline string as a decal, with tiniting and scaling
void DrawStringDecal(const olc::vf2d& pos, std::string_view sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f },const float width=std::numeric_limits<float>::max(),const bool disableDynamicScaling=false);
void DrawOGStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
@ -3321,6 +3322,37 @@ namespace olc
di.structure = nDecalStructure;
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}
void PixelGameEngine::DrawPartialSquishedRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale, const olc::Pixel& tint)
{
DecalInstance di;
di.decal = decal;
di.points = 4;
di.tint = { tint, tint, tint, tint };
di.w = { 1, 1, 1, 1 };
di.pos.resize(4);
di.pos[0] = (olc::vf2d(0.0f, 0.0f) - center);
di.pos[1] = (olc::vf2d(0.0f, source_size.y) - center);
di.pos[2] = (olc::vf2d(source_size.x, source_size.y) - center);
di.pos[3] = (olc::vf2d(source_size.x, 0.0f) - center);
float c = cos(fAngle), s = sin(fAngle);
for (int i = 0; i < 4; i++)
{
di.pos[i] = pos + olc::vf2d(di.pos[i].x * c - di.pos[i].y * s, di.pos[i].x * s + di.pos[i].y * c);
di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f - olc::vf2d(1.0f, 1.0f);
di.pos[i].y *= -1.0f;
}
di.pos[0] *= scale;
di.pos[1] *= scale;
di.pos[2] *= scale;
di.pos[3] *= scale;
olc::vf2d uvtl = source_pos * decal->vUVScale;
olc::vf2d uvbr = uvtl + (source_size * decal->vUVScale);
di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } };
di.mode = nDecalMode;
di.structure = nDecalStructure;
vLayers[nTargetLayer].vecDecalInstance.push_back(di);
}
void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint)
{

Loading…
Cancel
Save