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.
This commit is contained in:
parent
34510e732a
commit
5f40ee8306
@ -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();
|
||||
|
||||
|
@ -26,4 +26,13 @@ Add Spell Names on info screen.
|
||||
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.
|
||||
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.
BIN
Adventures in Lestoria/assets/nico-thief.png
Normal file
BIN
Adventures in Lestoria/assets/nico-thief.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
BIN
Adventures in Lestoria/assets/nico-thief.xcf
Normal file
BIN
Adventures in Lestoria/assets/nico-thief.xcf
Normal file
Binary file not shown.
@ -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)
|
||||
{
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user