Add afterimage rendering for monsters. Release Build 12003.

master
sigonasr2 1 week ago
parent 4e099b71f9
commit 24d36da0ab
  1. 12
      Adventures in Lestoria/GhostOfPirateCaptain.cpp
  2. 39
      Adventures in Lestoria/Monster.cpp
  3. 6
      Adventures in Lestoria/Monster.h
  4. 2
      Adventures in Lestoria/Version.h
  5. BIN
      x64/Release/Adventures in Lestoria.exe

@ -52,6 +52,7 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
enum PhaseName{
INIT,
NORMAL,
AFTERIMAGE_FADEIN,
};
enum CannonShotType{
@ -75,6 +76,10 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
if(!m.B(A::FIRST_WAVE_COMPLETE)){
m.B(A::FIRST_WAVE_COMPLETE)=true;
m.ForceSetPos(m.spawnPos);
m.SetupAfterImage();
m.SetCollisionRadius(0.f);
m.F(A::CASTING_TIMER)=1.f;
SETPHASE(AFTERIMAGE_FADEIN);
}
}
}};
@ -160,5 +165,12 @@ void Monster::STRATEGY::GHOST_OF_PIRATE_CAPTAIN(Monster&m,float fElapsedTime,std
}break;
}
}break;
case AFTERIMAGE_FADEIN:{
m.F(A::CASTING_TIMER)-=fElapsedTime;
if(m.F(A::CASTING_TIMER)<=0.f){
SETPHASE(NORMAL);
m.SetCollisionRadius(m.GetOriginalCollisionRadius());
}
}break;
}
}

@ -82,6 +82,8 @@ Monster::Monster(vf2d pos,MonsterData data,bool upperLevel,bool bossMob):
monsterWalkSoundTimer=util::random(1.f);
UpdateFacingDirection(game->GetPlayer()->GetPos());
animation.UpdateState(internal_animState,randomFrameOffset);
const vf2d&currentRect{GetFrame().GetSourceRect().size};
afterImage.Create(currentRect.x,currentRect.y);
}
const vf2d&Monster::GetPos()const{
return pos;
@ -406,6 +408,29 @@ void Monster::Update(const float fElapsedTime){
animation.UpdateState(internal_animState,fElapsedTime);
if(HasMountedMonster())mounted_animation.value().UpdateState(internal_mounted_animState,fElapsedTime);
attackedByPlayer=false;
#pragma region Afterimage Handling
const auto RemoveScanLine=[&](uint8_t scanLine){
for(int x:std::ranges::iota_view(0,afterImage.Sprite()->width)){
afterImage.Sprite()->SetPixel({x,scanLine},BLANK);
}
afterImage.Decal()->Update();
};
//Scan Line goes through 1-(height-1) (odd numbers) first, then 0-22.
const bool ScanLineFinished{scanLine==afterImage.Sprite()->height};
if(!ScanLineFinished){
removeLineTimer-=fElapsedTime;
if(removeLineTimer<=0.f){
removeLineTimer=TIME_BETWEEN_LINE_REMOVALS;
RemoveScanLine(scanLine);
scanLine+=2;
if(scanLine>afterImage.Sprite()->height-1&&scanLine%2==1){
scanLine=0;
}
}
}
#pragma endregion
}
Direction Monster::GetFacingDirection()const{
return facingDirection;
@ -512,6 +537,7 @@ void Monster::Draw()const{
};
if(glowPurpleBuff.has_value())DrawBaseMonster(glowPurpleImageScale,{43,0,66,blendCol.a});
DrawAfterImage:game->view.DrawRotatedDecal(afterImagePos,afterImage.Decal(),0.f,afterImage.Sprite()->Size()/2,{GetSizeMult(),GetSizeMult()},Pixel{0xFFDCDA});
DrawBaseMonster(imageScale,blendCol);
if(overlaySprite.length()!=0){
if(glowPurpleBuff.has_value())DrawOverlayMonster(imageScale,{43,0,66,overlaySpriteTransparency});
@ -574,8 +600,8 @@ void Monster::Draw()const{
#pragma endregion
if(GameSettings::TerrainCollisionBoxesEnabled()&&IsSolid()&&solidFadeTimer>0.f){
float distToPlayer=geom2d::line<float>(game->GetPlayer()->GetPos(),GetPos()).length();
const float collisionRadiusFactor=GetCollisionRadius()/12.f;
const float distToPlayer{geom2d::line<float>(game->GetPlayer()->GetPos(),GetPos()).length()};
const float collisionRadiusFactor{GetCollisionRadius()/12.f};
if(distToPlayer<24*3*collisionRadiusFactor){
game->DrawPie(game->view.WorldToScreen(GetPos()),GetCollisionRadius(),0.f,{255,0,0,uint8_t(128*(blendColAlpha/255.f)/sqrt(distToPlayer*collisionRadiusFactor))});
game->SetDecalMode(DecalMode::WIREFRAME);
@ -1677,3 +1703,12 @@ void Monster::ForceSetPos(vf2d pos){
this->pos=pos;
Moved();
}
void Monster::SetupAfterImage(){
game->SetDrawTarget(afterImage.Sprite());
game->Clear(BLANK);
game->DrawPartialSprite({},animation.GetFrame(internal_animState).GetSourceImage()->Sprite(),animation.GetFrame(internal_animState).GetSourceRect().pos,animation.GetFrame(internal_animState).GetSourceRect().size,1U,0U,{255,255,254}); //Off-white so that the sprite is rendered completely in white.
game->SetDrawTarget(nullptr);
afterImage.Decal()->Update();
removeLineTimer=TIME_BETWEEN_LINE_REMOVALS;
scanLine=1U;
}

@ -338,6 +338,12 @@ private:
float collisionRadius{}; //The collision radius can be modified, it's just set initially to the monster database entry.
//Ignores collision checking and sets the monster at the given position.
void ForceSetPos(vf2d pos);
Renderable afterImage;
void SetupAfterImage();
float removeLineTimer{};
const float TIME_BETWEEN_LINE_REMOVALS{0.025f};
uint8_t scanLine{24};
vf2d afterImagePos{};
struct STRATEGY{
static std::string ERR;

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 12001
#define VERSION_BUILD 12003
#define stringify(a) stringify_(a)
#define stringify_(a) #a

Loading…
Cancel
Save