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.
This commit is contained in:
parent
1fd37bbd51
commit
6b2f4f7bf9
@ -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;
|
||||
|
BIN
Adventures in Lestoria/assets/aiming_line.png
Normal file
BIN
Adventures in Lestoria/assets/aiming_line.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 591 B |
BIN
Adventures in Lestoria/assets/aiming_target.png
Normal file
BIN
Adventures in Lestoria/assets/aiming_target.png
Normal file
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…
x
Reference in New Issue
Block a user