@ -92,7 +92,7 @@ bool _DEBUG_MAP_LOAD_INFO = false;
//360x240
//360x240
vi2d WINDOW_SIZE = { 24 * 15 , 24 * 10 } ;
vi2d WINDOW_SIZE = { 24 * 15 , 24 * 10 } ;
safemap < std : : string , Animate2D : : FrameSequence > ANIMATION_DATA ;
safemap < std : : string , Animate2D : : FrameSequence > ANIMATION_DATA ;
std : : vector < Monster > MONSTER_LIST ;
std : : vector < std : : unique_ptr < Monster > > MONSTER_LIST ;
std : : vector < MonsterSpawner > SPAWNER_LIST ;
std : : vector < MonsterSpawner > SPAWNER_LIST ;
std : : vector < std : : shared_ptr < DamageNumber > > DAMAGENUMBER_LIST ;
std : : vector < std : : shared_ptr < DamageNumber > > DAMAGENUMBER_LIST ;
std : : vector < std : : unique_ptr < Bullet > > BULLET_LIST ;
std : : vector < std : : unique_ptr < Bullet > > BULLET_LIST ;
@ -734,23 +734,23 @@ void AiL::UpdateBullets(float fElapsedTime){
b - > distanceTraveled + = totalDistance / 24.f * 100.f ;
b - > distanceTraveled + = totalDistance / 24.f * 100.f ;
const auto CollisionCheck = [ & ] ( ) {
const auto CollisionCheck = [ & ] ( ) {
if ( b - > friendly ) {
if ( b - > friendly ) {
for ( Monster & m : MONSTER_LIST ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
if ( geom2d : : overlaps ( m . Hitbox ( ) , 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 - > hitList . find ( & * m ) = = b - > hitList . end ( ) & & m - > Hurt ( b - > damage , b - > OnUpperLevel ( ) , 0 ) ) {
if ( ! b - > hitsMultiple ) {
if ( ! b - > hitsMultiple ) {
if ( b - > MonsterHit ( m ) ) {
if ( b - > MonsterHit ( * m ) ) {
b - > dead = true ;
b - > dead = true ;
}
}
return false ;
return false ;
}
}
b - > hitList . insert ( & m ) ;
b - > hitList . insert ( & * m ) ;
}
}
}
}
}
}
} else {
} else {
if ( geom2d : : overlaps ( player - > Hitbox ( ) , 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 ( player - > Hurt ( b - > damage , b - > OnUpperLevel ( ) , 0 ) ) {
if ( b - > PlayerHit ( player . get ( ) ) ) {
if ( b - > PlayerHit ( & * player ) ) {
b - > dead = true ;
b - > dead = true ;
}
}
return false ;
return false ;
@ -790,10 +790,10 @@ void AiL::UpdateBullets(float fElapsedTime){
}
}
const MonsterHurtList AiL : : HurtEnemies ( vf2d pos , float radius , int damage , bool upperLevel , float z ) const {
const MonsterHurtList AiL : : HurtEnemies ( vf2d pos , float radius , int damage , bool upperLevel , float z ) const {
MonsterHurtList hitList ;
MonsterHurtList hitList ;
for ( Monster & m : MONSTER_LIST ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
if ( geom2d : : overlaps ( geom2d : : circle ( pos , radius ) , geom2d : : circle ( m . GetPos ( ) , 12 * m . GetSizeMult ( ) ) ) ) {
if ( geom2d : : overlaps ( geom2d : : circle ( pos , radius ) , geom2d : : circle ( m - > GetPos ( ) , 12 * m - > GetSizeMult ( ) ) ) ) {
HurtReturnValue returnVal = m . Hurt ( damage , upperLevel , z ) ;
HurtReturnValue returnVal = m - > Hurt ( damage , upperLevel , z ) ;
hitList . push_back ( { & m , returnVal } ) ;
hitList . push_back ( { & * m , returnVal } ) ;
}
}
}
}
return hitList ;
return hitList ;
@ -801,11 +801,11 @@ const MonsterHurtList AiL::HurtEnemies(vf2d pos,float radius,int damage,bool upp
const MonsterHurtList AiL : : HurtEnemiesNotHit ( vf2d pos , float radius , int damage , HitList & hitList , bool upperLevel , float z ) {
const MonsterHurtList AiL : : HurtEnemiesNotHit ( vf2d pos , float radius , int damage , HitList & hitList , bool upperLevel , float z ) {
MonsterHurtList affectedList ;
MonsterHurtList affectedList ;
for ( Monster & m : MONSTER_LIST ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
if ( ! hitList . count ( & m ) & & geom2d : : overlaps ( geom2d : : circle ( pos , radius ) , geom2d : : circle ( m . GetPos ( ) , 12 * m . GetSizeMult ( ) ) ) ) {
if ( ! hitList . count ( & * m ) & & geom2d : : overlaps ( geom2d : : circle ( pos , radius ) , geom2d : : circle ( m - > GetPos ( ) , 12 * m - > GetSizeMult ( ) ) ) ) {
HurtReturnValue returnVal = m . Hurt ( damage , upperLevel , z ) ;
HurtReturnValue returnVal = m - > Hurt ( damage , upperLevel , z ) ;
affectedList . push_back ( { & m , returnVal } ) ;
affectedList . push_back ( { & * m , returnVal } ) ;
hitList . insert ( & m ) ;
hitList . insert ( & * m ) ;
}
}
}
}
return affectedList ;
return affectedList ;
@ -813,14 +813,14 @@ const MonsterHurtList AiL::HurtEnemiesNotHit(vf2d pos,float radius,int damage,Hi
const MonsterHurtList AiL : : HurtEnemiesConeNotHit ( vf2d pos , float radius , float angle , float sweepAngle , int damage , HitList & hitList , bool upperLevel , float z ) {
const MonsterHurtList AiL : : HurtEnemiesConeNotHit ( vf2d pos , float radius , float angle , float sweepAngle , int damage , HitList & hitList , bool upperLevel , float z ) {
MonsterHurtList affectedList ;
MonsterHurtList affectedList ;
for ( Monster & m : MONSTER_LIST ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
if ( ! hitList . count ( & m ) & & geom2d : : overlaps ( geom2d : : circle ( pos , radius ) , geom2d : : circle ( m . GetPos ( ) , 12 * m . GetSizeMult ( ) ) ) ) {
if ( ! hitList . count ( & * m ) & & geom2d : : overlaps ( geom2d : : circle ( pos , radius ) , geom2d : : circle ( m - > GetPos ( ) , 12 * m - > GetSizeMult ( ) ) ) ) {
float angleToMonster = geom2d : : line < float > { pos , m . GetPos ( ) } . vector ( ) . polar ( ) . y ;
float angleToMonster = geom2d : : line < float > { pos , m - > GetPos ( ) } . vector ( ) . polar ( ) . y ;
float angleDiff = util : : angle_difference ( angleToMonster , angle ) ;
float angleDiff = util : : angle_difference ( angleToMonster , angle ) ;
if ( abs ( angleDiff ) < = sweepAngle ) {
if ( abs ( angleDiff ) < = sweepAngle ) {
HurtReturnValue returnVal = m . Hurt ( damage , upperLevel , z ) ;
HurtReturnValue returnVal = m - > Hurt ( damage , upperLevel , z ) ;
affectedList . push_back ( { & m , returnVal } ) ;
affectedList . push_back ( { & * m , returnVal } ) ;
hitList . insert ( & m ) ;
hitList . insert ( & * m ) ;
}
}
}
}
}
}
@ -851,14 +851,14 @@ void AiL::PopulateRenderLists(){
Player * pl = GetPlayer ( ) ;
Player * pl = GetPlayer ( ) ;
pl - > rendered = false ;
pl - > rendered = false ;
std : : sort ( MONSTER_LIST . begin ( ) , MONSTER_LIST . end ( ) , [ ] ( Monster & m1 , Monster & m2 ) { return m1 . GetPos ( ) . y < m2 . GetPos ( ) . y ; } ) ;
std : : sort ( MONSTER_LIST . begin ( ) , MONSTER_LIST . end ( ) , [ ] ( std : : unique_ptr < Monster > & m1 , std : : unique_ptr < Monster > & m2 ) { return m1 - > GetPos ( ) . y < m2 - > GetPos ( ) . y ; } ) ;
std : : sort ( ItemDrop : : drops . begin ( ) , ItemDrop : : drops . end ( ) , [ ] ( ItemDrop & id1 , ItemDrop & id2 ) { return id1 . GetPos ( ) . y < id2 . GetPos ( ) . y ; } ) ;
std : : sort ( ItemDrop : : drops . begin ( ) , ItemDrop : : drops . end ( ) , [ ] ( ItemDrop & id1 , ItemDrop & id2 ) { return id1 . GetPos ( ) . y < id2 . GetPos ( ) . y ; } ) ;
std : : sort ( BULLET_LIST . begin ( ) , BULLET_LIST . end ( ) , [ ] ( std : : unique_ptr < Bullet > & b1 , std : : unique_ptr < Bullet > & b2 ) { return b1 - > pos . y < b2 - > pos . y ; } ) ;
std : : sort ( BULLET_LIST . begin ( ) , BULLET_LIST . end ( ) , [ ] ( std : : unique_ptr < Bullet > & b1 , std : : unique_ptr < Bullet > & b2 ) { return b1 - > pos . y < b2 - > pos . y ; } ) ;
std : : sort ( foregroundEffects . begin ( ) , foregroundEffects . end ( ) , [ ] ( std : : unique_ptr < Effect > & e1 , std : : unique_ptr < Effect > & e2 ) { return e1 - > pos . y < e2 - > pos . y ; } ) ;
std : : sort ( foregroundEffects . begin ( ) , foregroundEffects . end ( ) , [ ] ( std : : unique_ptr < Effect > & e1 , std : : unique_ptr < Effect > & e2 ) { return e1 - > pos . y < e2 - > pos . y ; } ) ;
std : : sort ( backgroundEffects . begin ( ) , backgroundEffects . end ( ) , [ ] ( std : : unique_ptr < Effect > & e1 , std : : unique_ptr < Effect > & e2 ) { return e1 - > pos . y < e2 - > pos . y ; } ) ;
std : : sort ( backgroundEffects . begin ( ) , backgroundEffects . end ( ) , [ ] ( std : : unique_ptr < Effect > & e1 , std : : unique_ptr < Effect > & e2 ) { return e1 - > pos . y < e2 - > pos . y ; } ) ;
for ( auto it = MONSTER_LIST . begin ( ) ; it ! = MONSTER_LIST . end ( ) ; + + it ) {
for ( auto it = MONSTER_LIST . begin ( ) ; it ! = MONSTER_LIST . end ( ) ; + + it ) {
Monster & m = * it ;
Monster & m = * * it ;
if ( m . GetPos ( ) . y < pl - > GetPos ( ) . y ) { //This monster renders before the player does (behind the player)
if ( m . GetPos ( ) . y < pl - > GetPos ( ) . y ) { //This monster renders before the player does (behind the player)
if ( m . OnUpperLevel ( ) ) {
if ( m . OnUpperLevel ( ) ) {
monstersBeforeUpper . push_back ( & m ) ;
monstersBeforeUpper . push_back ( & m ) ;
@ -1021,8 +1021,8 @@ void AiL::RenderWorld(float fElapsedTime){
multiplierX * = ( 1 - abs ( cos ( 1.5f * reflectionStepTime ) ) * " water_reflection_scale_factor " _F ) ;
multiplierX * = ( 1 - abs ( cos ( 1.5f * reflectionStepTime ) ) * " water_reflection_scale_factor " _F ) ;
float reflectionRatioX = abs ( sin ( reflectionStepTime ) ) * " water_reflection_scale_factor " _F ;
float reflectionRatioX = abs ( sin ( reflectionStepTime ) ) * " water_reflection_scale_factor " _F ;
RenderPlayer ( player - > GetPos ( ) + vf2d { reflectionRatioX * player - > GetFrame ( ) . GetSourceRect ( ) . size . x , float ( player - > GetFrame ( ) . GetSourceRect ( ) . size . y ) - 8 } * player - > GetSizeMult ( ) , { multiplierX , - 1 } ) ;
RenderPlayer ( player - > GetPos ( ) + vf2d { reflectionRatioX * player - > GetFrame ( ) . GetSourceRect ( ) . size . x , float ( player - > GetFrame ( ) . GetSourceRect ( ) . size . y ) - 8 } * player - > GetSizeMult ( ) , { multiplierX , - 1 } ) ;
for ( Monster & m : MONSTER_LIST ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
m . DrawReflection ( reflectionRatioX , multiplierX ) ;
m - > DrawReflection ( reflectionRatioX , multiplierX ) ;
}
}
SetDecalMode ( DecalMode : : NORMAL ) ;
SetDecalMode ( DecalMode : : NORMAL ) ;
}
}
@ -1689,8 +1689,8 @@ void AiL::RenderWorld(float fElapsedTime){
}
}
}
}
for ( Monster & m : MONSTER_LIST ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
m . strategyDrawOverlay ( this , m , MONSTER_DATA [ m . GetName ( ) ] . GetAIStrategy ( ) ) ;
m - > strategyDrawOverlay ( this , * m , MONSTER_DATA [ m - > GetName ( ) ] . GetAIStrategy ( ) ) ;
}
}
# ifdef _DEBUG
# ifdef _DEBUG
@ -2415,9 +2415,9 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){
LoadingScreen : : AddPhase ( [ & ] ( ) {
LoadingScreen : : AddPhase ( [ & ] ( ) {
for ( NPCData data : game - > MAP_DATA [ game - > GetCurrentLevel ( ) ] . npcs ) {
for ( NPCData data : game - > MAP_DATA [ game - > GetCurrentLevel ( ) ] . npcs ) {
if ( Unlock : : IsUnlocked ( data . unlockCondition ) ) {
if ( Unlock : : IsUnlocked ( data . unlockCondition ) ) {
MONSTER_LIST . push_back ( Monster { data . spawnPos , MONSTER_DATA [ data . name ] } ) ;
MONSTER_LIST . push_back ( std : : make_unique < Monster > ( data . spawnPos , MONSTER_DATA [ data . name ] ) ) ;
MONSTER_LIST . back ( ) . iframe_timer = INFINITE ;
MONSTER_LIST . back ( ) - > iframe_timer = INFINITE ;
MONSTER_LIST . back ( ) . npcData = data ;
MONSTER_LIST . back ( ) - > npcData = data ;
}
}
}
}
return true ;
return true ;
@ -3930,12 +3930,12 @@ rcode AiL::LoadResource(Renderable&renderable,std::string_view imgPath,bool filt
}
}
void AiL : : UpdateMonsters ( ) {
void AiL : : UpdateMonsters ( ) {
for ( Monster & m : MONSTER_LIST ) {
for ( std : : unique_ptr < Monster > & m : MONSTER_LIST ) {
m . Update ( game - > GetElapsedTime ( ) ) ;
m - > Update ( game - > GetElapsedTime ( ) ) ;
}
}
for ( Monster & m : game - > monstersToBeSpawned ) {
for ( Monster & m : game - > monstersToBeSpawned ) {
size_t prevCapacity = MONSTER_LIST . capacity ( ) ;
size_t prevCapacity = MONSTER_LIST . capacity ( ) ;
MONSTER_LIST . push_back ( m ) ;
MONSTER_LIST . push_back ( std : : make_unique < Monster > ( m ) ) ;
if ( MONSTER_LIST . capacity ( ) > prevCapacity ) LOG ( std : : format ( " WARNING! The monster list has automatically reserved more space and resized to {}! This caused one potential frame where bullet/effect hitlists that stored information on what monsters were hit to potentially be hit a second time or cause monsters that should've been hit to never be hit. Consider starting with a larger default reserved size for MONSTER_LIST if your intention was to have this many monsters! " , MONSTER_LIST . capacity ( ) ) ) ;
if ( MONSTER_LIST . capacity ( ) > prevCapacity ) LOG ( std : : format ( " WARNING! The monster list has automatically reserved more space and resized to {}! This caused one potential frame where bullet/effect hitlists that stored information on what monsters were hit to potentially be hit a second time or cause monsters that should've been hit to never be hit. Consider starting with a larger default reserved size for MONSTER_LIST if your intention was to have this many monsters! " , MONSTER_LIST . capacity ( ) ) ) ;
}
}
game - > monstersToBeSpawned . clear ( ) ;
game - > monstersToBeSpawned . clear ( ) ;