Implemented Ranger auto attack plus animations.

pull/28/head
sigonasr2 1 year ago
parent 79a8dca88a
commit 9ebe5a21a0
  1. 17
      Crawler/Animation.cpp
  2. 3
      Crawler/Animation.h
  3. 39
      Crawler/Arrow.cpp
  4. 9
      Crawler/Bullet.h
  5. 11
      Crawler/BulletTypes.h
  6. 12
      Crawler/Crawler.cpp
  7. 1
      Crawler/Crawler.vcxproj
  8. 3
      Crawler/Crawler.vcxproj.filters
  9. 3
      Crawler/EnergyBolt.cpp
  10. 3
      Crawler/FireBolt.cpp
  11. 3
      Crawler/LightningBolt.cpp
  12. 2
      Crawler/Player.h
  13. 26
      Crawler/Ranger.cpp
  14. 1
      Crawler/State.h
  15. 2
      Crawler/Version.h

@ -91,6 +91,17 @@ void sig::Animation::InitializeAnimations(){
//Ranger animations //Ranger animations
SetupClassWalkIdleAnimations(game->GFX_Ranger_Sheet,AnimationState::RANGER_WALK_S); SetupClassWalkIdleAnimations(game->GFX_Ranger_Sheet,AnimationState::RANGER_WALK_S);
Animate2D::FrameSequence pl_ranger_shoot_s,pl_ranger_shoot_n,pl_ranger_shoot_e,pl_ranger_shoot_w;
for(int i=0;i<3;i++){
pl_ranger_shoot_s.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,0}*24,{24,24}}});
pl_ranger_shoot_n.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,1}*24,{24,24}}});
pl_ranger_shoot_e.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,3}*24,{24,24}}});
pl_ranger_shoot_w.AddFrame({&game->GFX_Ranger_Sheet,{vi2d{3+i,2}*24,{24,24}}});
}
ANIMATION_DATA[AnimationState::RANGER_SHOOT_S]=pl_ranger_shoot_s;
ANIMATION_DATA[AnimationState::RANGER_SHOOT_N]=pl_ranger_shoot_n;
ANIMATION_DATA[AnimationState::RANGER_SHOOT_E]=pl_ranger_shoot_e;
ANIMATION_DATA[AnimationState::RANGER_SHOOT_W]=pl_ranger_shoot_w;
//Wizard animations //Wizard animations
SetupClassWalkIdleAnimations(game->GFX_Wizard_Sheet,AnimationState::WIZARD_WALK_S); SetupClassWalkIdleAnimations(game->GFX_Wizard_Sheet,AnimationState::WIZARD_WALK_S);
@ -184,7 +195,7 @@ void sig::Animation::InitializeAnimations(){
CreateHorizontalAnimationSequence(game->GFX_EnergyParticle,3,{3,3},AnimationState::ENERGY_PARTICLE); CreateHorizontalAnimationSequence(game->GFX_EnergyParticle,3,{3,3},AnimationState::ENERGY_PARTICLE);
CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},AnimationState::LIGHTNING_BOLT,{0.05}); CreateHorizontalAnimationSequence(game->GFX_Splash_Effect,5,{24,24},AnimationState::SPLASH_EFFECT,{0.05});
CreateStillAnimation(game->GFX_BulletCircle,{3,3},AnimationState::DOT_PARTICLE); CreateStillAnimation(game->GFX_BulletCircle,{3,3},AnimationState::DOT_PARTICLE);
@ -234,6 +245,10 @@ void sig::Animation::SetupPlayerAnimations(){
game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_E); game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_E);
game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_S); game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_S);
game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_W); game->GetPlayer()->AddAnimation(AnimationState::RANGER_IDLE_W);
game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_S);
game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_N);
game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_W);
game->GetPlayer()->AddAnimation(AnimationState::RANGER_SHOOT_E);
game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_N); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_N);
game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_E); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_E);
game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_S); game->GetPlayer()->AddAnimation(AnimationState::WIZARD_WALK_S);

@ -22,7 +22,8 @@ enum AnimationState{
LIGHTNING_BOLT,LIGHTNING_BOLT_PARTICLE1,LIGHTNING_BOLT_PARTICLE2,LIGHTNING_BOLT_PARTICLE3,LIGHTNING_BOLT_PARTICLE4, LIGHTNING_BOLT,LIGHTNING_BOLT_PARTICLE1,LIGHTNING_BOLT_PARTICLE2,LIGHTNING_BOLT_PARTICLE3,LIGHTNING_BOLT_PARTICLE4,
CHAIN_LIGHTNING,LIGHTNING_SPLASH, CHAIN_LIGHTNING,LIGHTNING_SPLASH,
WIZARD_CAST_S,WIZARD_CAST_N,WIZARD_CAST_E,WIZARD_CAST_W,METEOR, WIZARD_CAST_S,WIZARD_CAST_N,WIZARD_CAST_E,WIZARD_CAST_W,METEOR,
FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5,ARROW FIRE_RING1,FIRE_RING2,FIRE_RING3,FIRE_RING4,FIRE_RING5,ARROW,
RANGER_SHOOT_S,RANGER_SHOOT_N,RANGER_SHOOT_E,RANGER_SHOOT_W,
}; };
namespace sig{ namespace sig{

@ -0,0 +1,39 @@
#include "BulletTypes.h"
#include "Effect.h"
#include "Crawler.h"
#include "DEFINES.h"
#include "utils.h"
#include "olcUTIL_Geometry2D.h"
INCLUDE_game
Arrow::Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:finalDistance(geom2d::line(pos,targetPos).length()),
Bullet(pos,vel,radius,damage,
AnimationState::ARROW,upperLevel,false,INFINITE,true,friendly,col){}
void Arrow::Update(float fElapsedTime){
float speed=vel.mag();
travelDistance+=speed*fElapsedTime;
vel.y+=acc*fElapsedTime;
if(!deactivated&&travelDistance>=finalDistance){
deactivated=true;
fadeOutTime=0.2f;
}
}
bool Arrow::PlayerHit(Player*player)
{
deactivated=true;
fadeOutTime=0.2f;
game->AddEffect(std::make_unique<Effect>(player->GetPos(),0,AnimationState::SPLASH_EFFECT,upperLevel,player->GetSizeMult(),0.25));
return false;
}
bool Arrow::MonsterHit(Monster& monster)
{
deactivated=true;
fadeOutTime=0.2f;
game->AddEffect(std::make_unique<Effect>(monster.GetPos(),0,AnimationState::SPLASH_EFFECT,upperLevel,monster.GetSizeMult(),0.25));
return false;
}

@ -7,8 +7,8 @@
struct Bullet{ struct Bullet{
friend class Crawler; friend class Crawler;
vf2d pos;
vf2d vel; vf2d vel;
vf2d pos;
float radius; float radius;
int damage; int damage;
Pixel col; Pixel col;
@ -17,11 +17,12 @@ struct Bullet{
bool rotates=false; bool rotates=false;
bool animated=false; bool animated=false;
bool deactivated=false; //A deactivated bullet no longer interacts with the world. It's just a visual. bool deactivated=false; //A deactivated bullet no longer interacts with the world. It's just a visual.
float fadeOutTime=0; float fadeOutTime=0; //Setting the fade out time causes the bullet's lifetime to be set to the fadeout time as well, as that's when the bullet's alpha will reach 0, so it dies.
bool friendly=false; //Whether or not it's a player bullet or enemy bullet. bool friendly=false; //Whether or not it's a player bullet or enemy bullet.
bool upperLevel=false; bool upperLevel=false;
private: protected:
float fadeOutTimer=0; float fadeOutTimer=0;
private:
void UpdateFadeTime(float fElapsedTime); void UpdateFadeTime(float fElapsedTime);
public: public:
Animate2D::Animation<AnimationState>animation; Animate2D::Animation<AnimationState>animation;
@ -38,6 +39,6 @@ public:
//Return true when the bullet should be destroyed. Return false to handle it otherwise (like deactivating it instead). You become responsible for getting rid of the bullet. //Return true when the bullet should be destroyed. Return false to handle it otherwise (like deactivating it instead). You become responsible for getting rid of the bullet.
virtual bool MonsterHit(Monster&monster); virtual bool MonsterHit(Monster&monster);
Animate2D::Frame GetFrame(); Animate2D::Frame GetFrame();
void Draw(); virtual void Draw();
bool OnUpperLevel(); bool OnUpperLevel();
}; };

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "Bullet.h" #include "Bullet.h"
#include "olcPixelGameEngine.h"
struct EnergyBolt:public Bullet{ struct EnergyBolt:public Bullet{
float lastParticleSpawn=0; float lastParticleSpawn=0;
@ -24,3 +25,13 @@ struct LightningBolt:public Bullet{
bool PlayerHit(Player*player)override; bool PlayerHit(Player*player)override;
bool MonsterHit(Monster&monster)override; bool MonsterHit(Monster&monster)override;
}; };
struct Arrow:public Bullet{
float travelDistance=0;
float finalDistance=0;
float acc=PI/2*250;
Arrow(vf2d pos,vf2d targetPos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly=false,Pixel col=WHITE);
void Update(float fElapsedTime)override;
bool PlayerHit(Player*player)override;
bool MonsterHit(Monster&monster)override;
};

@ -182,11 +182,14 @@ void Crawler::HandleUserInput(float fElapsedTime){
std::string staircaseDirection=GetPlayerStaircaseDirection(); std::string staircaseDirection=GetPlayerStaircaseDirection();
if(RightHeld()){ if(RightHeld()){
player->SetX(player->GetX()+fElapsedTime*100*player->GetMoveSpdMult()); player->SetX(player->GetX()+fElapsedTime*100*player->GetMoveSpdMult());
player->movementVelocity.x=100;
if(staircaseDirection=="RIGHT"){ if(staircaseDirection=="RIGHT"){
player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult()); player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult());
player->movementVelocity.y=-60;
} else } else
if(staircaseDirection=="LEFT"){ if(staircaseDirection=="LEFT"){
player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult()); player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult());
player->movementVelocity.y=60;
} }
player->SetFacingDirection(RIGHT); player->SetFacingDirection(RIGHT);
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
@ -196,11 +199,14 @@ void Crawler::HandleUserInput(float fElapsedTime){
} }
if(LeftHeld()){ if(LeftHeld()){
player->SetX(player->GetX()-fElapsedTime*100*player->GetMoveSpdMult()); player->SetX(player->GetX()-fElapsedTime*100*player->GetMoveSpdMult());
player->movementVelocity.x=-100;
if(staircaseDirection=="RIGHT"){ if(staircaseDirection=="RIGHT"){
player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult()); player->SetY(player->GetY()+60*fElapsedTime*player->GetMoveSpdMult());
player->movementVelocity.y=60;
} else } else
if(staircaseDirection=="LEFT"){ if(staircaseDirection=="LEFT"){
player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult()); player->SetY(player->GetY()-60*fElapsedTime*player->GetMoveSpdMult());
player->movementVelocity.y=-60;
} }
if(setIdleAnimation){ if(setIdleAnimation){
player->SetFacingDirection(LEFT); player->SetFacingDirection(LEFT);
@ -212,6 +218,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
} }
if(UpHeld()){ if(UpHeld()){
player->SetY(player->GetY()-fElapsedTime*100*player->GetMoveSpdMult()); player->SetY(player->GetY()-fElapsedTime*100*player->GetMoveSpdMult());
player->movementVelocity.y=-100*fElapsedTime;
if(setIdleAnimation){ if(setIdleAnimation){
player->SetFacingDirection(UP); player->SetFacingDirection(UP);
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
@ -222,6 +229,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
} }
if(DownHeld()){ if(DownHeld()){
player->SetY(player->GetY()+fElapsedTime*100*player->GetMoveSpdMult()); player->SetY(player->GetY()+fElapsedTime*100*player->GetMoveSpdMult());
player->movementVelocity.y=100*fElapsedTime;
if(setIdleAnimation){ if(setIdleAnimation){
player->SetFacingDirection(DOWN); player->SetFacingDirection(DOWN);
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
@ -233,6 +241,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
} }
if(UpReleased()){ if(UpReleased()){
player->SetLastReleasedMovementKey(UP); player->SetLastReleasedMovementKey(UP);
player->movementVelocity.y=0;
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(RightHeld()){ if(RightHeld()){
player->UpdateWalkingAnimation(RIGHT); player->UpdateWalkingAnimation(RIGHT);
@ -247,6 +256,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
} }
if(RightReleased()){ if(RightReleased()){
player->SetLastReleasedMovementKey(RIGHT); player->SetLastReleasedMovementKey(RIGHT);
player->movementVelocity.x=0;
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(UpHeld()){ if(UpHeld()){
player->UpdateWalkingAnimation(UP); player->UpdateWalkingAnimation(UP);
@ -261,6 +271,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
} }
if(LeftReleased()){ if(LeftReleased()){
player->SetLastReleasedMovementKey(LEFT); player->SetLastReleasedMovementKey(LEFT);
player->movementVelocity.x=0;
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(RightHeld()){ if(RightHeld()){
player->UpdateWalkingAnimation(RIGHT); player->UpdateWalkingAnimation(RIGHT);
@ -275,6 +286,7 @@ void Crawler::HandleUserInput(float fElapsedTime){
} }
if(DownReleased()){ if(DownReleased()){
player->SetLastReleasedMovementKey(DOWN); player->SetLastReleasedMovementKey(DOWN);
player->movementVelocity.y=0;
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){ if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
if(RightHeld()){ if(RightHeld()){
player->UpdateWalkingAnimation(RIGHT); player->UpdateWalkingAnimation(RIGHT);

@ -203,6 +203,7 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="Ability.cpp" /> <ClCompile Include="Ability.cpp" />
<ClCompile Include="Animation.cpp" /> <ClCompile Include="Animation.cpp" />
<ClCompile Include="Arrow.cpp" />
<ClCompile Include="Bullet.cpp" /> <ClCompile Include="Bullet.cpp" />
<ClCompile Include="Crawler.cpp" /> <ClCompile Include="Crawler.cpp" />
<ClCompile Include="DamageNumber.cpp" /> <ClCompile Include="DamageNumber.cpp" />

@ -191,6 +191,9 @@
<ClCompile Include="PulsatingFire.cpp"> <ClCompile Include="PulsatingFire.cpp">
<Filter>Source Files\Effects</Filter> <Filter>Source Files\Effects</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Arrow.cpp">
<Filter>Source Files\Bullet Types</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

@ -7,7 +7,8 @@
INCLUDE_game INCLUDE_game
EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) EnergyBolt::EnergyBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:Bullet(pos,vel,radius,damage,AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} :Bullet(pos,vel,radius,damage,
AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){}
void EnergyBolt::Update(float fElapsedTime){ void EnergyBolt::Update(float fElapsedTime){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);

@ -8,7 +8,8 @@ INCLUDE_game
INCLUDE_MONSTER_LIST INCLUDE_MONSTER_LIST
FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) FireBolt::FireBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:Bullet(pos,vel,radius,damage,AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){} :Bullet(pos,vel,radius,damage,
AnimationState::ENERGY_BOLT,upperLevel,false,INFINITE,true,friendly,col){}
void FireBolt::Update(float fElapsedTime){ void FireBolt::Update(float fElapsedTime){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);

@ -10,7 +10,8 @@ INCLUDE_MONSTER_LIST
INCLUDE_EMITTER_LIST INCLUDE_EMITTER_LIST
LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col) LightningBolt::LightningBolt(vf2d pos,vf2d vel,float radius,int damage,bool upperLevel,bool friendly,Pixel col)
:Bullet(pos,vel,radius,damage,AnimationState::LIGHTNING_BOLT,upperLevel,false,INFINITE,true,friendly,col){} :Bullet(pos,vel,radius,damage,
AnimationState::LIGHTNING_BOLT,upperLevel,false,INFINITE,true,friendly,col){}
void LightningBolt::Update(float fElapsedTime){ void LightningBolt::Update(float fElapsedTime){
lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime); lastParticleSpawn=std::max(0.f,lastParticleSpawn-fElapsedTime);

@ -49,9 +49,11 @@ struct Player{
void AddAnimation(AnimationState state); void AddAnimation(AnimationState state);
std::vector<Buff>buffList; std::vector<Buff>buffList;
CastInfo castInfo={"",0}; CastInfo castInfo={"",0};
vf2d movementVelocity={};//This tells us if the player is moving (mostly controlled by user input) since their velocity is not used for regular movement.
protected: protected:
const float ATTACK_COOLDOWN=0.35f; const float ATTACK_COOLDOWN=0.35f;
const float MAGIC_ATTACK_COOLDOWN=0.85f; const float MAGIC_ATTACK_COOLDOWN=0.85f;
const float ARROW_ATTACK_COOLDOWN=0.6f;
void SetSwordSwingTimer(float val); void SetSwordSwingTimer(float val);
void SetState(State newState); void SetState(State newState);
void SetFacingDirection(Key direction); void SetFacingDirection(Key direction);

@ -4,6 +4,7 @@
#include "Player.h" #include "Player.h"
#include "Effect.h" #include "Effect.h"
#include "Crawler.h" #include "Crawler.h"
#include "BulletTypes.h"
INCLUDE_MONSTER_LIST INCLUDE_MONSTER_LIST
INCLUDE_BULLET_LIST INCLUDE_BULLET_LIST
@ -28,12 +29,35 @@ AnimationState Ranger::walk_w=RANGER_WALK_W;
SETUP_CLASS(Ranger) SETUP_CLASS(Ranger)
void Ranger::OnUpdate(float fElapsedTime){ void Ranger::OnUpdate(float fElapsedTime){
if(GetState()==SHOOT_ARROW){
if(attack_cooldown_timer<=ARROW_ATTACK_COOLDOWN-0.3){
SetState(NORMAL);
}
}
} }
bool Ranger::AutoAttack(){ bool Ranger::AutoAttack(){
attack_cooldown_timer=ARROW_ATTACK_COOLDOWN;
geom2d::line pointTowardsCursor(GetPos(),game->GetWorldMousePos());
vf2d extendedLine=pointTowardsCursor.upoint(1.1);
float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x);
BULLET_LIST.push_back(std::make_unique<Arrow>(Arrow(GetPos(),extendedLine,vf2d{cos(angleToCursor)*250,float(sin(angleToCursor)*250-PI/8*250)}+movementVelocity,12,GetAttack(),OnUpperLevel(),true)));
SetState(State::SHOOT_ARROW);
if(angleToCursor<=PI/4&&angleToCursor>-PI/4){
UpdateAnimation(AnimationState::RANGER_SHOOT_E);
} else
if(angleToCursor>=3*PI/4||angleToCursor<-3*PI/4){
UpdateAnimation(AnimationState::RANGER_SHOOT_W);
} else
if(angleToCursor<=3*PI/4&&angleToCursor>PI/4){
UpdateAnimation(AnimationState::RANGER_SHOOT_S);
} else
if(angleToCursor>=-3*PI/4&&angleToCursor<-PI/4){
UpdateAnimation(AnimationState::RANGER_SHOOT_N);
}
return false; return false;
} }
void Ranger::InitializeClassAbilities(){ void Ranger::InitializeClassAbilities(){
#pragma region Ranger Right-click Ability (???) #pragma region Ranger Right-click Ability (???)
Ranger::rightClickAbility.action= Ranger::rightClickAbility.action=

@ -12,4 +12,5 @@ enum State{
PATH_AROUND, PATH_AROUND,
CASTING, CASTING,
PREP_CAST, PREP_CAST,
SHOOT_ARROW,
}; };

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 0 #define VERSION_PATCH 0
#define VERSION_BUILD 769 #define VERSION_BUILD 803
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

Loading…
Cancel
Save