Make lerp functions require both arguments to be the same for deduced return type. Fix buggy monster spawns to account for monster sizes. BOTTOM RIGHT EDGE FOR COORDINATES ??? Release Build 11794.

This commit is contained in:
sigonasr2 2024-11-12 22:52:41 -08:00
parent 10b8e68b22
commit ef1d4e5470
21 changed files with 47 additions and 41 deletions

View File

@ -2452,7 +2452,9 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){
vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2;
for(XMLTag&monster:spawnData.monsters){
std::string monsterName=monster.GetString("value");
monster_list.push_back({monsterName,{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}});
const vi2d frameSize{ANIMATION_DATA[std::format("{}_{}",monsterName,MONSTER_DATA[monsterName].GetDefaultIdleAnimation())].GetFrame(0.f).GetSourceRect().size};
const float monsterSizeMult{MONSTER_DATA[monsterName].GetSizeMult()};
monster_list.emplace_back(monsterName,vf2d{monster.GetInteger("x")+(frameSize.x*monsterSizeMult/2)-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-(frameSize.y*monsterSizeMult/2)-spawnData.ObjectData.GetFloat("y")});
}
const int spawnerId=spawnData.ObjectData.GetInteger("id");
@ -4044,7 +4046,7 @@ void AiL::RenderFadeout(){
SetMosaicEffect(1U);
GameState::_ChangeState(transitionState);
}else{
SetMosaicEffect(util::lerp(1U,mosaicEffectTransition,1-(fadeOutDuration/fadeOutTotalTime)));
SetMosaicEffect(util::lerp(uint8_t(1),mosaicEffectTransition,1-(fadeOutDuration/fadeOutTotalTime)));
alpha=uint8_t(util::lerp(0,255,1-(fadeOutDuration/fadeOutTotalTime)));
}
}else

View File

@ -103,7 +103,7 @@ BulletDestroyState Bomb::MonsterHit(Monster&monster,const uint8_t markStacksBefo
void Bomb::Draw(const Pixel blendCol)const{
Bullet::Draw(blendCol);
game->view.DrawPartialRotatedDecal(pos-vf2d{0,GetZ()},bomb_animation.GetFrame(animation).GetSourceImage()->Decal(),rotates?atan2(vel.y,vel.x)-PI/2:0,bomb_animation.GetFrame(animation).GetSourceRect().size/2,bomb_animation.GetFrame(animation).GetSourceRect().pos,bomb_animation.GetFrame(animation).GetSourceRect().size,scale,fadeOutTime==0?col:Pixel{col.r,col.g,col.b,uint8_t(util::lerp(col.a,0,1-((fadeOutTime-GetFadeoutTimer())/fadeOutTime)))});
game->view.DrawPartialRotatedDecal(pos-vf2d{0,GetZ()},bomb_animation.GetFrame(animation).GetSourceImage()->Decal(),rotates?atan2(vel.y,vel.x)-PI/2:0,bomb_animation.GetFrame(animation).GetSourceRect().size/2,bomb_animation.GetFrame(animation).GetSourceRect().pos,bomb_animation.GetFrame(animation).GetSourceRect().size,scale,fadeOutTime==0?col:Pixel{col.r,col.g,col.b,uint8_t(util::lerp(col.a,uint8_t(0),1-((fadeOutTime-GetFadeoutTimer())/fadeOutTime)))});
}
void Bomb::ModifyOutgoingDamageData(HurtDamageInfo&data){}

View File

@ -56,7 +56,7 @@ void FrogTongue::Update(float fElapsedTime){
geom2d::line<float>lineToTarget(pos,targetPos);
vf2d drawVec=lineToTarget.vector().norm()*3;
tongueLength=util::lerp(0,lineToTarget.length(),pow(sin((lifetime*PI)/duration),20.f));
tongueLength=util::lerp(0.f,lineToTarget.length(),pow(sin((lifetime*PI)/duration),20.f));
vf2d tongueEndPos=geom2d::line<float>(pos+drawVec,targetPos).upoint(pow(sin((lifetime*PI)/duration),20.f));
geom2d::line<float>tongueLine(pos+drawVec,tongueEndPos);

View File

@ -173,8 +173,8 @@ void IBullet::_Draw()const{
Pixel blendCol=col;
if(fadeInTime==0&&fadeOutTime==0)blendCol.a=col.a;
else if(fadeOutTime>0)blendCol.a=uint8_t(util::lerp(col.a,0,1-((fadeOutTime-fadeOutTimer)/fadeOutTime)));
else if(fadeInTime>0)blendCol.a=uint8_t(util::lerp(col.a,0,((fadeInTime-fadeInTimer)/fadeInTime)));
else if(fadeOutTime>0)blendCol.a=uint8_t(util::lerp(col.a,uint8_t(0),1-((fadeOutTime-fadeOutTimer)/fadeOutTime)));
else if(fadeInTime>0)blendCol.a=uint8_t(util::lerp(col.a,uint8_t(0),((fadeInTime-fadeInTimer)/fadeInTime)));
if(GetZ()>0){
vf2d shadowScale=vf2d{8*scale.x/3.f,1}/std::max(1.f,GetZ()/8);

View File

@ -488,10 +488,10 @@ void Monster::Draw()const{
const bool NotOnTitleScreen=GameState::STATE!=GameState::states[States::MAIN_MENU];
uint8_t blendColAlpha=blendCol.a;
if(fadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(0,blendCol.a,fadeTimer)); //Fade timer goes from 1 to 0 seconds.
if(fadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(uint8_t(0),blendCol.a,fadeTimer)); //Fade timer goes from 1 to 0 seconds.
else if(NotOnTitleScreen
&&(OnUpperLevel()!=game->GetPlayer()->OnUpperLevel()||abs(GetZ()-game->GetPlayer()->GetZ())>1))blendColAlpha=blendCol.a*0.62f;
else if(IsSolid()&&solidFadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(blendCol.a,255-TileGroup::FADE_AMT,solidFadeTimer/TileGroup::FADE_TIME));
else if(IsSolid()&&solidFadeTimer>0.f)blendColAlpha=uint8_t(util::lerp(blendCol.a,uint8_t(255-TileGroup::FADE_AMT),solidFadeTimer/TileGroup::FADE_TIME));
blendCol.a=blendColAlpha;

View File

@ -116,12 +116,12 @@ void Monster::STRATEGY::OCTOPUS_ARM(Monster&m,float fElapsedTime,std::string str
Arc attackArc{GetAttackArc(m)};
m.SetStrategyDrawFunction([&attackArc,&storedArc=m.ANY(A::STORED_ARC),&alphaTimer=m.F(A::ENVIRONMENT_TIMER),attackEffectTime=ConfigFloat("Attack Effect Time")](AiL*game,Monster&monster,const std::string&strategy){
const float alphaTimer{std::fmod(game->GetRunTime(),2.f)};
uint8_t alpha{util::lerp(0,255,alphaTimer)};
const float alphaTimer{float(std::fmod(game->GetRunTime(),2.f))};
uint8_t alpha{util::lerp(uint8_t(0),uint8_t(255),alphaTimer)};
if(alphaTimer>1.f)alpha=util::lerp(0,255,1-(alphaTimer-1));
attackArc.Draw(game,{0,0,255,uint8_t(alpha)});
if(storedArc.has_value()){
const uint8_t effectAlpha{util::lerp(0,255,alphaTimer/attackEffectTime)};
const uint8_t effectAlpha{util::lerp(uint8_t(0),uint8_t(255),alphaTimer/attackEffectTime)};
std::any_cast<Arc>(storedArc).Draw(game,{255,255,255,effectAlpha});
}
});

View File

@ -147,9 +147,9 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,std::string str
}
}
if(m.F(A::JUMP_LANDING_TIMER)>=m.F(A::JUMP_ORIGINAL_LANDING_TIMER)/2){
m.SetZ(util::lerp(0,float(ConfigInt("JumpHeight")),1-jumpLandingTimerRatio));
m.SetZ(util::lerp(0.f,float(ConfigInt("JumpHeight")),1-jumpLandingTimerRatio));
}else{
m.SetZ(util::lerp(0,float(ConfigInt("JumpHeight")),jumpLandingTimerRatio*2));
m.SetZ(util::lerp(0.f,float(ConfigInt("JumpHeight")),jumpLandingTimerRatio*2));
}
if(m.F(A::JUMP_LANDING_TIMER)==0){
m.state=State::RECOVERY;

View File

@ -191,9 +191,9 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,std::string strat
}
}
if(m.F(A::JUMP_LANDING_TIMER)>=m.F(A::JUMP_ORIGINAL_LANDING_TIMER)/2){
m.SetZ(util::lerp(0,float(ConfigInt("JumpHeight")),1-jumpLandingTimerRatio));
m.SetZ(util::lerp(0.f,float(ConfigInt("JumpHeight")),1-jumpLandingTimerRatio));
}else{
m.SetZ(util::lerp(0,float(ConfigInt("JumpHeight")),jumpLandingTimerRatio*2));
m.SetZ(util::lerp(0.f,float(ConfigInt("JumpHeight")),jumpLandingTimerRatio*2));
}
if(m.F(A::JUMP_LANDING_TIMER)==0){
m.state=State::RECOVERY;

View File

@ -75,7 +75,7 @@ void State_Death::OnUserUpdate(AiL*game){
}
game->view.SetZoom(util::lerp(1.f,2.f,(gameSlowdownPct-1)/10.f),game->view.WorldToScreen(game->GetPlayer()->GetPos()));
game->SetWorldColor({uint8_t(util::lerp(255,0,(gameSlowdownPct-1)/10.f)),uint8_t(util::lerp(255,0,(gameSlowdownPct-1)/10.f)),uint8_t(util::lerp(255,0,(gameSlowdownPct-1)/10.f)),255});
Audio::SetBGMPitch(util::lerp(1.f,0,(gameSlowdownPct-1)/10.f));
Audio::SetBGMPitch(util::lerp(1.f,0.f,(gameSlowdownPct-1)/10.f));
if(gameSlowdownPct<5.f){
game->SetMosaicEffect(uint8_t(util::lerp(1.f,9.f,(gameSlowdownPct-1)/7.f)));
}else{

View File

@ -111,7 +111,7 @@ void Monster::STRATEGY::STONE_GOLEM(Monster&m,float fElapsedTime,std::string str
std::for_each(m.VEC(A::STAGE_POLYGONS).begin(),m.VEC(A::STAGE_POLYGONS).end(),[&](std::any&data){
StageMaskPolygon&polygon{std::any_cast<StageMaskPolygon&>(data)};
Pixel newCol{PixelLerp(Pixel{uint32_t(m.I(A::SHOCKWAVE_COLOR))},BLACK,sin(geom2d::pi*game->GetRunTime()*2)/2.f+0.5f)};
newCol.a=util::lerp(Pixel{uint32_t(m.I(A::SHOCKWAVE_COLOR))}.a,0.f,sin(geom2d::pi*game->GetRunTime()*2)/2.f+0.5f);
newCol.a=util::lerp(Pixel{uint32_t(m.I(A::SHOCKWAVE_COLOR))}.a,uint8_t(0),sin(geom2d::pi*game->GetRunTime()*2)/2.f+0.5f);
polygon.SetBlendColor(newCol);
polygon.Draw();
});

View File

@ -104,8 +104,8 @@ void TitleScreen::Update(){
double t=pixelMoveTime/(animationTime-2);
for(Particle&p:particles){
p.pos=p.originalPos.lerp(p.targetPos,sqrt(t));
p.rot=util::lerp(p.rot,0,t);
p.scale=util::lerp(p.scale,1,t);
p.rot=util::lerp(p.rot,0.f,t);
p.scale=util::lerp(p.scale,1.f,t);
}
if(currentAnimationTime==5.0f){
state=WAITING;

View File

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

View File

@ -321,7 +321,7 @@ void VisualNovel::Draw(const uint8_t backgroundAlpha){
game->DrawDropShadowStringDecal(narratorFont,dialogDisplayPos-vf2d{10,6}+dialogTextSize.offset,activeText,{190,190,220});
}
}
float yOffset=util::lerp(dialogDisplaySize.y+12,-8,textScrollTime/maxTextScrollTime);
float yOffset=util::lerp(dialogDisplaySize.y+12,-8.f,textScrollTime/maxTextScrollTime);
game->DrawPolygonDecal(
Menu::GetPatchPart(1,1).Decal(),
{dialogDisplayPos-vf2d{12,-yOffset},dialogDisplayPos+vf2d{-12,dialogDisplaySize.y+12},dialogDisplayPos+dialogDisplaySize+vf2d{12,12},dialogDisplayPos+vf2d{dialogDisplaySize.x+12,yOffset}},

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.10.2" class="Map" orientation="orthogonal" renderorder="right-down" width="214" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="12" nextobjectid="526">
<map version="1.10" tiledversion="1.11.0" class="Map" orientation="orthogonal" renderorder="right-down" width="214" height="205" tilewidth="24" tileheight="24" infinite="0" backgroundcolor="#475500" nextlayerid="12" nextobjectid="526">
<properties>
<property name="Backdrop" propertytype="Backdrop" value="forest"/>
<property name="Background Music" propertytype="BGM" value="foresty1_1"/>
@ -1835,7 +1835,7 @@
<property name="spawner" type="object" value="80"/>
</properties>
</object>
<object id="87" template="../maps/Monsters/Flower Turret.tx" type="Monster" x="2345.33" y="2350.67">
<object id="87" template="../maps/Monsters/Flower Turret.tx" type="Monster" x="2328" y="2352">
<properties>
<property name="spawner" type="object" value="80"/>
</properties>
@ -1845,7 +1845,7 @@
<property name="spawner" type="object" value="80"/>
</properties>
</object>
<object id="89" template="../maps/Monsters/Flower Turret.tx" type="Monster" x="1908.66" y="2169.66">
<object id="89" template="../maps/Monsters/Flower Turret.tx" type="Monster" x="1896" y="2184">
<properties>
<property name="spawner" type="object" value="80"/>
</properties>

View File

@ -343,42 +343,42 @@
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="11" template="../maps/Monsters/Octopus Arm.tx" x="936" y="912">
<object id="11" template="../maps/Monsters/Octopus Arm.tx" x="864" y="960">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="12" template="../maps/Monsters/Octopus Arm.tx" x="672" y="912">
<object id="12" template="../maps/Monsters/Octopus Arm.tx" x="600" y="960">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="13" template="../maps/Monsters/Octopus Arm.tx" x="504" y="744">
<object id="13" template="../maps/Monsters/Octopus Arm.tx" x="432" y="792">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="14" template="../maps/Monsters/Octopus Arm.tx" x="384" y="552">
<object id="14" template="../maps/Monsters/Octopus Arm.tx" x="312" y="600">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="15" template="../maps/Monsters/Octopus Arm.tx" x="600" y="384">
<object id="15" template="../maps/Monsters/Octopus Arm.tx" x="528" y="432">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="16" template="../maps/Monsters/Octopus Arm.tx" x="1032" y="384">
<object id="16" template="../maps/Monsters/Octopus Arm.tx" x="960" y="432">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="17" template="../maps/Monsters/Octopus Arm.tx" x="1248" y="504">
<object id="17" template="../maps/Monsters/Octopus Arm.tx" x="1176" y="552">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>
</object>
<object id="18" template="../maps/Monsters/Octopus Arm.tx" x="1128" y="720">
<object id="18" template="../maps/Monsters/Octopus Arm.tx" x="1056" y="768">
<properties>
<property name="spawner" type="object" value="19"/>
</properties>

View File

@ -1729,6 +1729,9 @@ Monsters
XP = 0
# A flag to show an arrow indicator when the boss is off-screen.
ShowBossIndicator = True
Collision Radius = 20
Ignore Collisions = True
@ -1765,13 +1768,14 @@ Monsters
Attack = 50
CollisionDmg = 30
Immovable = True
MoveSpd = 0%
Size = 400%
Size = 200%
XP = 0
Collision Radius = 20
Collision Radius = 24
Ignore Collisions = True

View File

@ -37,7 +37,7 @@
<object id="40" template="Monsters/Pirate Marauder.tx" type="Monster" x="-72" y="492"/>
<object id="41" template="Monsters/Sandworm.tx" type="Monster" x="168" y="534"/>
<object id="42" template="Monsters/Giant Crab.tx" type="Monster" x="-108" y="582"/>
<object id="43" template="Monsters/Octopus Arm.tx" type="Monster" x="-48" y="744" width="192" height="192"/>
<object id="43" template="Monsters/Octopus Arm.tx" type="Monster" x="-48" y="744"/>
<object id="44" template="Monsters/Giant Octopus.tx" type="Monster" x="120" y="744"/>
</objectgroup>
</map>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<template>
<tileset firstgid="1" source="../Monsters.tsx"/>
<object name="Octopus Arm" type="Monster" gid="31" width="48" height="48"/>
<object name="Octopus Arm" type="Monster" gid="31" width="192" height="192"/>
</template>

View File

@ -58,19 +58,19 @@ namespace olc::util{
const float dirToAngle(const Direction dir);
#pragma region Lerp templates + specializations
template<class T,class U>
inline auto lerp(const T val1,const U val2,const float t){
return decltype(val1+val2)(val1*(1-t)+val2*t);
template<class T>
inline auto lerp(const T val1,const T val2,const float t){
return T(val1*(1-t)+val2*t);
}
template<>
inline auto lerp<vf2d,vf2d>(const vf2d val1,const vf2d val2,const float t){
inline auto lerp<vf2d>(const vf2d val1,const vf2d val2,const float t){
return val1.lerp(val2,t);
}
template<>
//NOTE: Also interpolates the alpha!!!
inline auto lerp<Pixel,Pixel>(const Pixel val1,const Pixel val2,const float t){
inline auto lerp<Pixel>(const Pixel val1,const Pixel val2,const float t){
Pixel col{PixelLerp(val1,val2,t)};
col.a=lerp(val1.a,val2.a,t);
return col;