@ -49,6 +49,20 @@ namespace battle{
# define MESSAGE_SCROLL_WAIT_SPD 2 //Number of frames to wait.
# define BATTLE_CAMERA_SCROLL_SPD 0.05 //How fast to scroll over to the battle.
class DisplayNumber {
public :
int number ; //Negative means healing.
int frame ; //Frame it was created.
int x , y ;
int alpha = 255 ;
DisplayNumber ( int numb , int x , int y , int frameCount ) {
this - > number = numb ;
this - > x = x ;
this - > y = y ;
this - > frame = frameCount ;
}
} ;
class Animation {
public :
Decal * spr ;
@ -136,6 +150,7 @@ class Entity{
this - > name = name ;
this - > x = x ;
this - > y = y ;
this - > maxhp = hp ;
this - > hp = hp ;
this - > maxhp = maxhp ;
this - > moveSet = moveset ;
@ -219,7 +234,7 @@ public:
WEATHER_POWER * METEOR_STORM = new WEATHER_POWER ( " Meteor Storm " , " Larger space rocks. 120+60d " , & POWER_METEOR_STORM_ANIMATION , & POWER_METEOR_STORM_ANIMATION , 120 , 60 , 140 , Pixel ( 89 , 4 , 33 , 255 ) , Pixel ( 130 , 56 , 1 , 255 ) , 120 ) ;
WEATHER_POWER * SNOWSTORM = new WEATHER_POWER ( " Snowstorm " , " Slows down targets and causes rapid temperature drops. 15+10d " , & POWER_SNOWSTORM_ANIMATION , & POWER_SNOWSTORM_ANIMATION , 15 , 10 , 140 , Pixel ( 183 , 196 , 194 , 255 ) , Pixel ( 222 , 255 , 254 , 255 ) , 120 ) ;
WEATHER_POWER * SANDSTORM = new WEATHER_POWER ( " Sandstorm " , " " , & POWER_HAILSTORM_ANIMATION , & POWER_HAILSTORM_ANIMATION , 5 , 10 , 64 , Pixel ( 93 , 161 , 163 , 255 ) , Pixel ( 72 , 160 , 212 , 255 ) , 120 ) ;
WEATHER_POWER * SEED_STORM = new WEATHER_POWER ( " Seed Storm " , " " , & POWER_HAILSTORM_ANIMATION , & POWER_HAILSTORM_ANIMATION , 8 , 20 , 164 , Pixel ( 93 , 161 , 163 , 255 ) , Pixel ( 72 , 160 , 212 , 255 ) , 120 ) ;
WEATHER_POWER * SEED_STORM = new WEATHER_POWER ( " Seed Storm " , " " , & POWER_HAILSTORM_ANIMATION , & POWER_HAILSTORM_ANIMATION , - 10 , 15 , 30 , Pixel ( 93 , 161 , 163 , 255 ) , Pixel ( 72 , 160 , 212 , 255 ) , 120 ) ;
WEATHER_POWER * AVALANCHE = new WEATHER_POWER ( " Avalanche " , " " , & POWER_HAILSTORM_ANIMATION , & POWER_HAILSTORM_ANIMATION , 15 , 10 , 200 , Pixel ( 93 , 161 , 163 , 255 ) , Pixel ( 72 , 160 , 212 , 255 ) , 120 ) ;
bool IN_BATTLE_ENCOUNTER = false ;
int BATTLE_ENTRY_TIMER = 0 ;
@ -240,6 +255,7 @@ public:
int PLAYER_HP = PLAYER_MAXHP ;
int BATTLE_CURRENT_TURN_ENTITY = - 1 ;
int CURRENT_ENCOUNTER_IND = - 1 ;
std : : vector < DisplayNumber > BATTLE_DISPLAY_NUMBERS ;
std : : vector < WEATHER_POWER * > MOVESET_SPIDEY ;
@ -742,6 +758,19 @@ public:
}
}
for ( int i = 0 ; i < BATTLE_DISPLAY_NUMBERS . size ( ) ; i + + ) {
DisplayNumber * numb = & BATTLE_DISPLAY_NUMBERS [ i ] ;
if ( frameCount - numb - > frame > 60 ) {
delete numb ;
BATTLE_DISPLAY_NUMBERS . erase ( BATTLE_DISPLAY_NUMBERS . begin ( ) + i - - ) ;
} else {
if ( frameCount % 8 = = 0 ) {
numb - > y - - ;
numb - > alpha - = 255 / 8 ;
}
}
}
if ( IN_BATTLE_ENCOUNTER ) {
BATTLE_ENTRY_TIMER + + ;
switch ( BATTLE_STATE ) {
@ -789,6 +818,20 @@ public:
} else {
ref = CURRENT_ENCOUNTER . entities [ BATTLE_CURRENT_TURN_ENTITY ] . selectedMove ;
}
if ( EFFECT_TIMER = = 30 & & ref - > name . compare ( " Seed Storm " ) = = 0 ) {
if ( BATTLE_CURRENT_TURN_ENTITY = = - 1 ) {
effectRadius ( { PLAYER_COORDS [ 0 ] , PLAYER_COORDS [ 1 ] } , ref , true ) ;
} else {
effectRadius ( { CURRENT_ENCOUNTER . entities [ BATTLE_CURRENT_TURN_ENTITY ] . x , CURRENT_ENCOUNTER . entities [ BATTLE_CURRENT_TURN_ENTITY ] . y } , ref , false ) ;
}
} else
if ( EFFECT_TIMER = = ref - > effectTime - 10 ) {
if ( BATTLE_CURRENT_TURN_ENTITY = = - 1 ) {
effectRadius ( { PLAYER_COORDS [ 0 ] , PLAYER_COORDS [ 1 ] } , ref , true ) ;
} else {
effectRadius ( { CURRENT_ENCOUNTER . entities [ BATTLE_CURRENT_TURN_ENTITY ] . x , CURRENT_ENCOUNTER . entities [ BATTLE_CURRENT_TURN_ENTITY ] . y } , ref , false ) ;
}
}
if ( EFFECT_TIMER > ref - > effectTime ) {
BATTLE_STATE = battle : : DAMAGE_RESOLUTION ;
EFFECT_TIMER = 0 ;
@ -1018,6 +1061,17 @@ public:
DrawStringDecal ( { 4 + 1 , HEIGHT - 10 - GetTextSize ( " HP: " ) . y + 1 } , " HP: " + std : : to_string ( PLAYER_HP ) , BLACK ) ;
DrawStringDecal ( { 4 , HEIGHT - 10 - GetTextSize ( " HP: " ) . y } , " HP: " + std : : to_string ( PLAYER_HP ) ) ;
DrawHealthbar ( { 2 , HEIGHT - 10 } , WIDTH / 2 , PLAYER_HP / PLAYER_MAXHP , BLACK ) ;
for ( auto & numb : BATTLE_DISPLAY_NUMBERS ) {
std : : string display = ( ( numb . number > 0 ) ? " - " + std : : to_string ( numb . number ) : " + " + std : : to_string ( numb . number * - 1 ) ) ;
for ( int x = - 1 ; x < = 1 ; x + + ) {
for ( int y = - 1 ; y < = 1 ; y + + ) {
if ( x ! = 0 & & y ! = 0 ) {
DrawStringDecal ( { numb . x - GetTextSize ( display ) . x / 2 + x , numb . y - 8 - GetTextSize ( display ) . y / 2 + y } , display , ( numb . number > 0 ) ? Pixel ( 255 , 0 , 0 , numb . alpha ) : Pixel ( 0 , 255 , 0 , numb . alpha ) , { 2 , 2 } ) ;
}
}
}
DrawStringDecal ( { numb . x - GetTextSize ( display ) . x / 2 , numb . y - 8 - GetTextSize ( display ) . y / 2 } , display , Pixel ( 255 , 255 , 255 , numb . alpha ) , { 2 , 2 } ) ;
}
}
if ( messageBoxVisible ) {
DrawDialogBox ( { 4 , HEIGHT - 60 } , { WIDTH / 2 , 16 } , Pixel ( 18 , 0 , 33 , 180 ) ) ;
@ -1305,6 +1359,50 @@ public:
DrawStringPropDecal ( { ( WIDTH / 6 + 4 + WIDTH / 3 * 2 - 8 - GetTextSizeProp ( std : : to_string ( data - > playerOwnCount ) + " uses remaining. " ) . x * 1.5 ) * scale . x + offset . x , ( HEIGHT / 6 * 3 + HEIGHT / 6 * 2 - GetTextSizeProp ( std : : to_string ( data - > playerOwnCount ) + " uses remaining. " ) . y * 1.5 - 4 ) * scale . y + offset . y } , std : : to_string ( data - > playerOwnCount ) + " uses remaining. " , olc : : WHITE * darknessFactor , { 1.5 * scale . x , 1.5 * scale . y } ) ;
}
void effectRadius ( vi2d coords , WEATHER_POWER * power , bool playerForce ) {
int finalDamage = power - > damage + rand ( ) % power - > damageRoll * sign ( power - > damage ) ;
if ( finalDamage < 0 ) {
//This is a healing effect.
if ( playerForce ) {
PLAYER_HP = std : : clamp ( PLAYER_HP - finalDamage , 0 , PLAYER_MAXHP ) ;
DisplayNumber numb ( finalDamage , PLAYER_COORDS [ 0 ] , PLAYER_COORDS [ 1 ] , frameCount ) ;
BATTLE_DISPLAY_NUMBERS . push_back ( numb ) ;
} else {
for ( int i = 0 ; i < CURRENT_ENCOUNTER . entities . size ( ) ; i + + ) {
Entity * ent = & CURRENT_ENCOUNTER . entities [ i ] ;
if ( distancetoCoords ( { ent - > x , ent - > y } , coords ) < = power - > range ) {
ent - > hp = std : : clamp ( ent - > hp - finalDamage , 0 , ent - > maxhp ) ;
DisplayNumber numb ( finalDamage , ent - > x , ent - > y , frameCount ) ;
BATTLE_DISPLAY_NUMBERS . push_back ( numb ) ;
}
}
}
} else {
//Damaging effect.
if ( playerForce ) {
for ( int i = 0 ; i < CURRENT_ENCOUNTER . entities . size ( ) ; i + + ) {
Entity * ent = & CURRENT_ENCOUNTER . entities [ i ] ;
if ( distancetoCoords ( { ent - > x , ent - > y } , coords ) < = power - > range ) {
ent - > hp = std : : clamp ( ent - > hp - finalDamage , 0 , ent - > maxhp ) ;
DisplayNumber numb ( finalDamage , ent - > x , ent - > y , frameCount ) ;
BATTLE_DISPLAY_NUMBERS . push_back ( numb ) ;
}
}
} else {
PLAYER_HP = std : : clamp ( PLAYER_HP - finalDamage , 0 , PLAYER_MAXHP ) ;
BATTLE_DISPLAY_NUMBERS . push_back ( numb ) ;
}
}
}
double distancetoCoords ( vf2d c1 , vf2d c2 ) {
return sqrt ( pow ( c1 . x - c2 . x , 2 ) + pow ( c2 . y - c1 . y , 2 ) ) ;
}
int sign ( int x ) {
return ( x > 0 ) - ( x < 0 ) ;
}
} ;