Added aiming system for controllers, integrated aiming and hot swapping between keyboard/gamepad controls. Switched all mouse aiming functions for classes to modular aiming function. Disable vibration when not using the controller.

pull/30/head
sigonasr2 1 year ago
parent 1fd37bbd51
commit 6b2f4f7bf9
  1. 67
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 101
      Adventures in Lestoria/Key.cpp
  3. 6
      Adventures in Lestoria/Key.h
  4. 63
      Adventures in Lestoria/Player.cpp
  5. 4
      Adventures in Lestoria/Player.h
  6. 10
      Adventures in Lestoria/Ranger.cpp
  7. 2
      Adventures in Lestoria/Version.h
  8. 4
      Adventures in Lestoria/Warrior.cpp
  9. 10
      Adventures in Lestoria/Wizard.cpp
  10. BIN
      Adventures in Lestoria/assets/aiming_line.png
  11. BIN
      Adventures in Lestoria/assets/aiming_target.png
  12. 3
      Adventures in Lestoria/assets/config/Player.txt
  13. 2
      Adventures in Lestoria/assets/config/gfx/gfx.txt
  14. 9
      Adventures in Lestoria/olcPGEX_Gamepad.h

@ -379,6 +379,7 @@ void AiL::HandleUserInput(float fElapsedTime){
return std::string("NONE");
};
std::string staircaseDirection=GetPlayerStaircaseDirection();
vf2d newAimingAngle{};
if(RightHeld()){
player->SetX(player->GetX()+fElapsedTime*"Player.MoveSpd"_F*player->GetMoveSpdMult());
player->movementVelocity.x="Player.MoveSpd"_F;
@ -394,6 +395,9 @@ void AiL::HandleUserInput(float fElapsedTime){
if(player->GetState()==State::NORMAL||player->GetState()==State::PREP_CAST){
player->UpdateWalkingAnimation(RIGHT);
}
newAimingAngle+=vf2d{1,0};
setIdleAnimation=false;
heldDownMovementKey=true;
}
@ -414,6 +418,9 @@ void AiL::HandleUserInput(float fElapsedTime){
player->UpdateWalkingAnimation(LEFT);
}
}
newAimingAngle-=vf2d{1,0};
setIdleAnimation=false;
heldDownMovementKey=true;
}
@ -426,6 +433,9 @@ void AiL::HandleUserInput(float fElapsedTime){
player->UpdateWalkingAnimation(UP);
}
}
newAimingAngle-=vf2d{0,1};
setIdleAnimation=false;
heldDownMovementKey=true;
}
@ -438,9 +448,15 @@ void AiL::HandleUserInput(float fElapsedTime){
player->UpdateWalkingAnimation(DOWN);
}
}
newAimingAngle+=vf2d{0,1};
setIdleAnimation=false;
heldDownMovementKey=true;
}
if(newAimingAngle!=vf2d{}){
player->aimingAngle=newAimingAngle.norm().polar();
}
}
if(UpReleased()){
player->SetLastReleasedMovementKey(UP);
@ -567,13 +583,7 @@ void AiL::UpdateCamera(float fElapsedTime){
worldShakeTime-=fElapsedTime;
if(worldShakeTime<=0){
camera.SetTarget(player->GetPos());
#pragma region Gamepad Stop Vibration
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
gamepad->stopVibration();
}
}
#pragma endregion
Input::StopVibration();
}
if(lastWorldShakeAdjust==0){
lastWorldShakeAdjust=0.02f;
@ -1050,10 +1060,10 @@ void AiL::RenderWorld(float fElapsedTime){
float precastSize=GetPlayer()->castPrepAbility->precastInfo.size;
float precastRange=GetPlayer()->castPrepAbility->precastInfo.range;
vf2d scale=vf2d{precastSize,precastSize}*2/3.f;
vf2d centerPoint=GetWorldMousePos()-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
float distance=float(sqrt(pow(player->GetX()-GetWorldMousePos().x,2)+pow(player->GetY()-GetWorldMousePos().y,2)));
vf2d centerPoint=GetPlayer()->GetWorldAimingLocation()-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
float distance=float(sqrt(pow(player->GetX()-GetPlayer()->GetWorldAimingLocation().x,2)+pow(player->GetY()-GetPlayer()->GetWorldAimingLocation().y,2)));
if(distance>precastRange){//Clamp the distance.
vf2d pointToCursor = {GetWorldMousePos().x-player->GetX(),GetWorldMousePos().y-player->GetY()};
vf2d pointToCursor = {GetPlayer()->GetWorldAimingLocation().x-player->GetX(),GetPlayer()->GetWorldAimingLocation().y-player->GetY()};
pointToCursor=pointToCursor.norm()*precastRange;
vf2d centerPoint=player->GetPos()+pointToCursor-vf2d{GFX["circle.png"].Sprite()->width*scale.x/2,GFX["circle.png"].Sprite()->height*scale.y/2};
view.DrawDecal(centerPoint,GFX["circle.png"].Decal(),scale,{255,0,0,96});
@ -1379,6 +1389,31 @@ Player*AiL::GetPlayer(){
}
void AiL::RenderHud(){
auto RenderAimingCursor=[&](){
if(Input::UsingGamepad()&&Input::AxesActive()){
vf2d aimingLocation=player->GetAimingLocation();
float analogStickDistance=geom2d::line<float>(GetScreenSize()/2,aimingLocation).length();
if(analogStickDistance>12.f){
float aimingDist=geom2d::line<float>(view.WorldToScreen(player->GetPos()),aimingLocation).length();
if(aimingDist>"Player.Aiming Cursor Max Distance"_F/100*24.f){
//Clamp the line to the max possible distance.
aimingLocation=geom2d::line<float>(view.WorldToScreen(player->GetPos()),aimingLocation).rpoint("Player.Aiming Cursor Max Distance"_F/100*24.f);
aimingDist=geom2d::line<float>(view.WorldToScreen(player->GetPos()),aimingLocation).length();
}
geom2d::line<float>aimingLine=geom2d::line<float>(view.WorldToScreen(player->GetPos()),aimingLocation);
DrawRotatedDecal(aimingLocation,GFX["aiming_target.png"].Decal(),0.f,GFX["aiming_target.png"].Sprite()->Size()/2,{1.0f,1.0f},{255,255,255,128});
vf2d lineScale=vf2d(GFX["aiming_line.png"].Sprite()->Size())*vf2d{aimingDist/GFX["aiming_line.png"].Sprite()->width,1};
DrawPartialRotatedDecal(view.WorldToScreen(player->GetPos()),GFX["aiming_line.png"].Decal(),aimingLine.vector().polar().y,{0,0},{0,0},lineScale,vf2d{aimingDist,1.f}/lineScale,{255,255,255,192});
}
}
};
RenderAimingCursor();
ItemOverlay::Draw();
RenderCooldowns();
@ -1560,13 +1595,7 @@ void AiL::SetupWorldShake(float duration){
worldShakeTime=duration;
worldShake=vf2d{player->GetPos()};
camera.SetTarget(worldShake);
#pragma region Controller Vibration
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
gamepad->startVibration();
}
}
#pragma endregion
Input::StartVibration();
}
@ -2315,7 +2344,7 @@ void AiL::InitializeDefaultKeybinds(){
Player::KEY_ABILITY3.AddKeybind({KEY,R});
Player::KEY_ABILITY3.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::FACE_R)});
Player::KEY_ABILITY4.AddKeybind({KEY,F});
Player::KEY_ABILITY4.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::L2)});
Player::KEY_ABILITY4.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::FACE_D)});
Player::KEY_DEFENSIVE.AddKeybind({MOUSE,Mouse::RIGHT});
Player::KEY_DEFENSIVE.AddKeybind({KEY,SPACE});
Player::KEY_DEFENSIVE.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::R2)});
@ -2326,7 +2355,7 @@ void AiL::InitializeDefaultKeybinds(){
Player::KEY_ITEM3.AddKeybind({KEY,K3});
Player::KEY_ITEM3.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::R3)});
KEY_ATTACK.AddKeybind({MOUSE,Mouse::LEFT});
KEY_ATTACK.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::FACE_D)});
KEY_ATTACK.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::L2)});
KEY_LEFT.AddKeybind({KEY,LEFT});
KEY_LEFT.AddKeybind({KEY,A});
KEY_LEFT.AddKeybind({CONTROLLER,static_cast<int>(GPButtons::DPAD_L)});

@ -42,66 +42,86 @@ All rights reserved.
INCLUDE_game
bool Input::usingGamepad;
Input::Input(InputType type,int key)
:type(type),key(key){}
bool Input::Pressed(){
if(!game->IsFocused())return false;
bool inputPressed=false;
switch(type){
case KEY:{
return game->GetKey(Key(key)).bPressed;
inputPressed=game->GetKey(Key(key)).bPressed;
}break;
case MOUSE:{
return game->GetMouse(key).bPressed;
inputPressed=game->GetMouse(key).bPressed;
}break;
case CONTROLLER:{
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bPressed)return true;
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bPressed)inputPressed=true;
}
return false;
}break;
default:{
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
}
}
if(inputPressed){
usingGamepad=type==CONTROLLER;
return true;
}
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
return false;
}
bool Input::Held(){
if(!game->IsFocused())return false;
bool inputHeld=false;
switch(type){
case KEY:{
return game->GetKey(Key(key)).bHeld;
inputHeld=game->GetKey(Key(key)).bHeld;
}break;
case MOUSE:{
return game->GetMouse(key).bHeld;
inputHeld=game->GetMouse(key).bHeld;
}break;
case CONTROLLER:{
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bHeld)return true;
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bHeld)inputHeld=true;
}
return false;
}break;
default:{
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
}
}
if(inputHeld){
usingGamepad=type==CONTROLLER;
return true;
}
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
return false;
}
bool Input::Released(){
if(!game->IsFocused())return false;
bool inputReleased=false;
switch(type){
case KEY:{
return game->GetKey(Key(key)).bReleased;
inputReleased=game->GetKey(Key(key)).bReleased;
}break;
case MOUSE:{
return game->GetMouse(key).bReleased;
inputReleased=game->GetMouse(key).bReleased;
}break;
case CONTROLLER:{
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bReleased)return true;
if(gamepad->stillConnected&&gamepad->getButton(static_cast<GPButtons>(key)).bReleased)inputReleased=true;
}
return false;
}break;
default:{
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
}
}
if(inputReleased){
usingGamepad=type==CONTROLLER;
return true;
}
ERR("Invalid Control Scheme detected! We shouldn't be here!! Type is "<<type);
return false;
}
@ -269,4 +289,53 @@ std::map<std::pair<InputType,int>,std::string> GenericKey::keyLiteral={
{{CONTROLLER, static_cast<int>(GPButtons::DPAD_R)},"RIGHT"},
{{CONTROLLER, static_cast<int>(GPButtons::DPAD_U)},"UP"},
{{CONTROLLER, static_cast<int>(GPButtons::DPAD_D)},"DOWN"},
};
};
void Input::SetUsingGamepad(const bool usingGamepad){
Input::usingGamepad=usingGamepad;
}
const bool Input::UsingGamepad(){
return usingGamepad;
}
const bool Input::AxesActive(){
float xAxis=0.f,yAxis=0.f;
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
if(fabs(gamepad->getAxis(GPAxes::RX))>0.f){
xAxis=gamepad->getAxis(GPAxes::RX);
}else
if(fabs(gamepad->getAxis(GPAxes::LX))>0.f){
xAxis=gamepad->getAxis(GPAxes::LX);
}
if(fabs(gamepad->getAxis(GPAxes::RY))>0.f){
yAxis=gamepad->getAxis(GPAxes::RY);
}else
if(fabs(gamepad->getAxis(GPAxes::LY))>0.f){
yAxis=gamepad->getAxis(GPAxes::LY);
}
if(xAxis!=0.f||yAxis!=0.f)break; //Found a controller, so we're good to break.
}
}
return xAxis!=0.f||yAxis!=0.f;
}
void Input::StartVibration(){
if(UsingGamepad()){
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
gamepad->startVibration();
}
}
}
}
void Input::StopVibration(){
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
gamepad->stopVibration();
}
}
}

@ -52,6 +52,8 @@ class Input{
friend class InputGroup;
InputType type;
int key; //This will be interpreted differently depending on input type.
static bool usingGamepad;
static void SetUsingGamepad(const bool usingGamepad);
public:
Input(InputType type,int key);
bool Pressed();
@ -61,6 +63,10 @@ public:
bool operator<(const Input&rhs)const{
return type<rhs.type||(type==rhs.type&&key<rhs.key);
}
static const bool UsingGamepad();
static const bool AxesActive();
static void StartVibration();
static void StopVibration();
};
class InputGroup{

@ -288,13 +288,7 @@ void Player::Update(float fElapsedTime){
if(hurtRumbleTime>0.f){
hurtRumbleTime=std::max(0.f,hurtRumbleTime-fElapsedTime);
if(hurtRumbleTime==0.f){
#pragma region Gamepad Stop Vibration
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
gamepad->stopVibration();
}
}
#pragma endregion
Input::StopVibration();
}
}
blockTimer=std::max(0.f,blockTimer-fElapsedTime);
@ -621,7 +615,7 @@ void Player::Update(float fElapsedTime){
if(rapidFireTimer<=0){
if(remainingRapidFireShots>0){
remainingRapidFireShots--;
geom2d::line pointTowardsCursor(GetPos(),game->GetWorldMousePos());
geom2d::line pointTowardsCursor(GetPos(),GetWorldAimingLocation());
vf2d extendedLine=pointTowardsCursor.upoint(1.1f);
float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x);
attack_cooldown_timer=ARROW_ATTACK_COOLDOWN;
@ -718,14 +712,8 @@ bool Player::Hurt(int damage,bool onUpperLevel,float z){
}
hp=std::max(0,hp-int(mod_dmg));
#pragma region Gamepad Vibration
hurtRumbleTime="Player.Hurt Rumble Time"_F;
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
gamepad->startVibration();
}
}
#pragma endregion
hurtRumbleTime="Player.Hurt Rumble Time"_F;
Input::StartVibration();
if(lastHitTimer>0){
damageNumberPtr.get()->damage+=int(mod_dmg);
@ -873,10 +861,10 @@ void Player::RemoveAllBuffs(){
}
void Player::CastSpell(Ability&ability){
vf2d castPosition=game->GetWorldMousePos();
float distance=float(sqrt(pow(GetX()-game->GetWorldMousePos().x,2)+pow(GetY()-game->GetWorldMousePos().y,2)));
vf2d castPosition=GetWorldAimingLocation();
float distance=float(sqrt(pow(GetX()-GetWorldAimingLocation().x,2)+pow(GetY()-GetWorldAimingLocation().y,2)));
if(distance>ability.precastInfo.range){//Clamp the distance.
vf2d pointToCursor = {game->GetWorldMousePos().x-GetX(),game->GetWorldMousePos().y-GetY()};
vf2d pointToCursor = {GetWorldAimingLocation().x-GetX(),GetWorldAimingLocation().y-GetY()};
pointToCursor=pointToCursor.norm()*ability.precastInfo.range;
castPosition=GetPos()+pointToCursor;
}
@ -1153,7 +1141,6 @@ const float Player::GetCritDmgPct()const{
return modCritDmgPct;
}
const float Player::GetHPRecoveryPct()const{
float modHPRecoveryPct=0;
modHPRecoveryPct+=GetStat("HP Recovery %")/100;
@ -1268,4 +1255,40 @@ void Player::Knockup(float duration){
knockUpTimer+=duration;
totalKnockupTime+=duration;
knockUpZAmt+=32*pow(duration,2);
}
const vf2d Player::GetWorldAimingLocation(){
return game->view.ScreenToWorld(GetAimingLocation());
}
const vf2d Player::GetAimingLocation(){
if(Input::UsingGamepad()){
float xAxis=0.f,yAxis=0.f;
for(GamePad*gamepad:GamePad::getGamepads()){
if(gamepad->stillConnected){
if(fabs(gamepad->getAxis(GPAxes::RX))>0.f){
xAxis=gamepad->getAxis(GPAxes::RX);
}else
if(fabs(gamepad->getAxis(GPAxes::LX))>0.f){
xAxis=gamepad->getAxis(GPAxes::LX);
}
if(fabs(gamepad->getAxis(GPAxes::RY))>0.f){
yAxis=gamepad->getAxis(GPAxes::RY);
}else
if(fabs(gamepad->getAxis(GPAxes::LY))>0.f){
yAxis=gamepad->getAxis(GPAxes::LY);
}
if(xAxis!=0.f||yAxis!=0.f)break; //Found a controller, so we're good to break.
}
}
if(xAxis!=0.f||yAxis!=0.f){
return {(game->ScreenWidth()*xAxis)/2+game->ScreenWidth()/2,(game->ScreenHeight()*yAxis)/2+game->ScreenHeight()/2};
}else{
return game->GetScreenSize()/2+vf2d{"Player.Aiming Cursor Max Distance"_F/100*24.f,aimingAngle.y}.cart();
}
}else{
return game->GetMousePos();
}
}

@ -238,6 +238,8 @@ public:
void AddAccumulatedXP(const uint32_t xpGain);
//Knockup the player for duration amount of seconds, and Zamt pixels.
void Knockup(float duration);
const vf2d GetAimingLocation();
const vf2d GetWorldAimingLocation();
private:
int hp="Warrior.BaseHealth"_I;
int mana="Player.BaseMana"_I;
@ -262,6 +264,8 @@ private:
float knockUpTimer=0.f;
float totalKnockupTime=0.f;
float knockUpZAmt=0.f;
//angle in polar coords.
vf2d aimingAngle{};
std::pair<std::string,float> notEnoughManaDisplay={"",0.f};
float teleportAttemptWaitTime=0; //If a teleport fails, we wait awhile before trying again, it's expensive.
State::State state=State::NORMAL;

@ -67,7 +67,7 @@ void Ranger::OnUpdate(float fElapsedTime){
}
bool Ranger::AutoAttack(){
geom2d::line pointTowardsCursor(GetPos(),game->GetWorldMousePos());
geom2d::line pointTowardsCursor(GetPos(),GetWorldAimingLocation());
vf2d extendedLine=pointTowardsCursor.upoint(1.1f);
float angleToCursor=atan2(extendedLine.y-GetPos().y,extendedLine.x-GetPos().x);
attack_cooldown_timer=ARROW_ATTACK_COOLDOWN-GetAttackRecoveryRateReduction();
@ -82,7 +82,7 @@ void Ranger::InitializeClassAbilities(){
#pragma region Ranger Right-click Ability (Retreat)
Ranger::rightClickAbility.action=
[](Player*p,vf2d pos={}){
geom2d::line mouseDir{game->GetWorldMousePos(),p->GetPos()};
geom2d::line mouseDir{p->GetWorldAimingLocation(),p->GetPos()};
float velocity=(0.5f*-p->friction*p->RETREAT_TIME*p->RETREAT_TIME-p->RETREAT_DISTANCE)/-p->RETREAT_TIME; //Derived from kinetic motion formula.
p->SetVelocity(mouseDir.vector().norm()*velocity);
p->retreatTimer=p->RETREAT_TIME;
@ -90,7 +90,7 @@ void Ranger::InitializeClassAbilities(){
p->ghostPositions.push_back(p->GetPos()+vf2d{0,-p->GetZ()});
p->ghostFrameTimer=p->RETREAT_GHOST_FRAME_DELAY;
p->ghostRemoveTimer=p->RETREAT_GHOST_FRAMES*p->RETREAT_GHOST_FRAME_DELAY;
float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
float angleToCursor=atan2(p->GetWorldAimingLocation().y-p->GetPos().y,p->GetWorldAimingLocation().x-p->GetPos().x);
p->SetAnimationBasedOnTargetingDirection(angleToCursor);
p->SetState(State::RETREAT);
SoundEffect::PlaySFX("Ranger.Right Click Ability.Sound"_S,SoundEffect::CENTERED);
@ -112,7 +112,7 @@ void Ranger::InitializeClassAbilities(){
#pragma region Ranger Ability 2 (Charged Shot)
Ranger::ability2.action=
[](Player*p,vf2d pos={}){
vf2d arrowVelocity=util::pointTo(p->GetPos(),game->GetWorldMousePos());
vf2d arrowVelocity=util::pointTo(p->GetPos(),p->GetWorldAimingLocation());
BULLET_LIST.push_back(std::make_unique<ChargedArrow>(p->GetPos(),arrowVelocity*"Ranger.Ability 2.Speed"_F,12*"Ranger.Ability 2.Radius"_F/100,p->GetAttack()*"Ranger.Ability 2.DamageMult"_F,p->OnUpperLevel(),true));
p->SetAnimationBasedOnTargetingDirection(atan2(arrowVelocity.y,arrowVelocity.x));
game->SetupWorldShake("Ranger.Ability 2.WorldShakeTime"_F);
@ -124,7 +124,7 @@ void Ranger::InitializeClassAbilities(){
#pragma region Ranger Ability 3 (Multi Shot)
Ranger::ability3.action=
[](Player*p,vf2d pos={}){
geom2d::line pointTowardsCursor=geom2d::line(p->GetPos(),game->GetWorldMousePos());
geom2d::line pointTowardsCursor=geom2d::line(p->GetPos(),p->GetWorldAimingLocation());
float shootingDist=pointTowardsCursor.length();
vf2d shootingDirMiddle=pointTowardsCursor.vector();
float shootingAngle=atan2(shootingDirMiddle.y,shootingDirMiddle.x);

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 5837
#define VERSION_BUILD 5867
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -73,8 +73,8 @@ bool Warrior::AutoAttack(){
for(Monster&m:MONSTER_LIST){
if(m.IsAlive()
&&geom2d::overlaps(geom2d::circle<float>(GetPos(),attack_range*GetSizeMult()*12),geom2d::circle<float>(m.GetPos(),m.GetSizeMult()*12))
&&geom2d::line<float>(game->GetWorldMousePos(),m.GetPos()).length()<closest_dist){
closest_dist=geom2d::line<float>(game->GetWorldMousePos(),m.GetPos()).length();
&&geom2d::line<float>(GetWorldAimingLocation(),m.GetPos()).length()<closest_dist){
closest_dist=geom2d::line<float>(GetWorldAimingLocation(),m.GetPos()).length();
closest=&m;
}
}

@ -103,7 +103,7 @@ void Wizard::OnUpdate(float fElapsedTime){
bool Wizard::AutoAttack(){
attack_cooldown_timer=MAGIC_ATTACK_COOLDOWN-GetAttackRecoveryRateReduction();
float angleToCursor=atan2(game->GetWorldMousePos().y-GetPos().y,game->GetWorldMousePos().x-GetPos().x);
float angleToCursor=atan2(GetWorldAimingLocation().y-GetPos().y,GetWorldAimingLocation().x-GetPos().x);
BULLET_LIST.push_back(std::make_unique<EnergyBolt>(EnergyBolt(GetPos(),{cos(angleToCursor)*"Wizard.Auto Attack.Speed"_F,sin(angleToCursor)*"Wizard.Auto Attack.Speed"_F},"Wizard.Auto Attack.Radius"_F/100*12,int(GetAttack()*"Wizard.Auto Attack.DamageMult"_F),upperLevel,true,WHITE)));
SoundEffect::PlaySFX("Wizard Auto Attack",SoundEffect::CENTERED);
return true;
@ -112,9 +112,9 @@ void Wizard::InitializeClassAbilities(){
#pragma region Wizard Right-click Ability (Teleport)
Wizard::rightClickAbility.action=
[](Player*p,vf2d pos={}){
float pointMouseDirection=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
float pointMouseDirection=atan2(p->GetWorldAimingLocation().y-p->GetPos().y,p->GetWorldAimingLocation().x-p->GetPos().x);
vf2d pointTowardsMouse={cos(pointMouseDirection),sin(pointMouseDirection)};
float dist=std::clamp(geom2d::line<float>{p->GetPos(),game->GetWorldMousePos()}.length(),0.f,"Wizard.Right Click Ability.TeleportRange"_F/100*24);
float dist=std::clamp(geom2d::line<float>{p->GetPos(),p->GetWorldAimingLocation()}.length(),0.f,"Wizard.Right Click Ability.TeleportRange"_F/100*24);
if(dist<"Wizard.Right Click Ability.TilesMin"_I*12)return false;
vf2d teleportPoint=p->GetPos()+pointTowardsMouse*dist;
while(dist>0&&game->HasTileCollision(game->GetCurrentLevel(),teleportPoint)&&p->CanPathfindTo(p->GetPos(),teleportPoint,float("Wizard.Right Click Ability.TilesMax"_I))){
@ -151,7 +151,7 @@ void Wizard::InitializeClassAbilities(){
#pragma region Wizard Ability 1 (Fire Bolt)
Wizard::ability1.action=
[](Player*p,vf2d pos={}){
float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
float angleToCursor=atan2(p->GetWorldAimingLocation().y-p->GetPos().y,p->GetWorldAimingLocation().x-p->GetPos().x);
CreateBullet(FireBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 1.BulletSpeed"_F},"Wizard.Ability 1.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 1.InitialDamageMult"_F),p->upperLevel,true,"Wizard.Ability 1.BulletColor"_Pixel)EndBullet;
SoundEffect::PlaySFX("Wizard Fire Bolt Shoot",SoundEffect::CENTERED);
return true;
@ -160,7 +160,7 @@ void Wizard::InitializeClassAbilities(){
#pragma region Wizard Ability 2 (Lightning Bolt)
Wizard::ability2.action=
[](Player*p,vf2d pos={}){
float angleToCursor=atan2(game->GetWorldMousePos().y-p->GetPos().y,game->GetWorldMousePos().x-p->GetPos().x);
float angleToCursor=atan2(p->GetWorldAimingLocation().y-p->GetPos().y,p->GetWorldAimingLocation().x-p->GetPos().x);
CreateBullet(LightningBolt)(p->GetPos(),{cos(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F,sin(angleToCursor)*"Wizard.Ability 2.BulletSpeed"_F},"Wizard.Ability 2.Radius"_F/100*12,int(p->GetAttack()*"Wizard.Ability 2.DamageMult"_F),p->upperLevel,true,"Wizard.Ability 2.BulletColor"_Pixel)EndBullet;
SoundEffect::PlaySFX("Wizard Lightning Bolt Shoot",SoundEffect::CENTERED);
return true;

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@ -29,6 +29,9 @@ Player
# How long between each footstep.
Footstep Timer = 0.4
# Distance the aiming cursor may be aimed at in controller aiming mode.
Aiming Cursor Max Distance = 600
# How long the rumble lasts when getting hit by a monster.
Hurt Rumble Time = 0.1s

@ -48,6 +48,8 @@ Images
GFX_TitleBack = title_back.png
GFX_FrogTongue = tongue.png
GFX_FrogTongueEnd = tongue_end.png
GFX_AimingTarget = aiming_target.png
GFX_AimingLine = aiming_line.png
# Ability Icons
GFX_Warrior_BattleCry_Icon = Ability Icons/battlecry.png

@ -155,6 +155,7 @@ namespace olc {
#pragma endregion
class GamePad : public olc::PGEX {
friend class Input;
public:
#ifdef WIN32
GamePad(LPCDIDEVICEINSTANCEA lpddi);
@ -199,10 +200,6 @@ namespace olc {
[[nodiscard]] int getButtonCount() const;
void startVibration(float strength = 1) const;
void stopVibration() const;
static GamePad *selectWithButton(olc::GPButtons b);
static GamePad *selectWithAnyButton();
@ -217,6 +214,10 @@ namespace olc {
static void updateGamepads();
void startVibration(float strength = 1) const;
void stopVibration() const;
std::string name;
int axisCount = GP_AXIS_COUNT;
int buttonCount = GP_BUTTON_COUNT;

Loading…
Cancel
Save