The open source repository for the action RPG game in development by Sig Productions titled 'Adventures in Lestoria'! https://forums.lestoria.net
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdventuresInLestoria/Crawler/Player.cpp

267 lines
5.9 KiB

#include "Monster.h"
#include "Player.h"
#include "Crawler.h"
#include "DamageNumber.h"
#include "DEFINES.h"
INCLUDE_MONSTER_DATA
INCLUDE_MONSTER_LIST
INCLUDE_ANIMATION_DATA
INCLUDE_SPAWNER_LIST
INCLUDE_DAMAGENUMBER_LIST
INCLUDE_game
const float Player::GROUND_SLAM_SPIN_TIME=0.6f;
const float Player::GROUND_SLAM_COOLDOWN=20;
Player::Player():
state(State::NORMAL),lastReleasedMovementKey(DOWN),facingDirection(DOWN){
}
Player::Player(vf2d pos):
pos(pos),state(State::NORMAL),lastReleasedMovementKey(DOWN),facingDirection(DOWN){
}
void Player::SetX(float x){
pos.x=x;
};
void Player::SetY(float y){
pos.y=y;
}
void Player::SetZ(float z){
this->z=z;
}
void Player::SetPos(vf2d pos){
this->pos=pos;
}
vf2d&Player::GetPos(){
return pos;
}
float Player::GetX(){
return pos.x;
}
float Player::GetY(){
return pos.y;
}
float Player::GetZ(){
return z;
}
int Player::GetHealth(){
return hp;
}
int Player::GetMaxHealth(){
return maxhp;
}
int Player::GetAttack(){
return atk;
}
float Player::GetMoveSpdMult(){
return moveSpd;
}
float Player::GetSizeMult(){
return size;
}
float Player::GetAttackRangeMult(){
return attack_range;
}
float Player::GetSpinAngle(){
return spin_angle;
}
State Player::GetState(){
return state;
}
void Player::Update(float fElapsedTime){
attack_cooldown_timer=std::max(0.f,attack_cooldown_timer-fElapsedTime);
switch(state){
case SPIN:{
switch(facingDirection){
case UP:{
if(lastAnimationFlip==0){
lastAnimationFlip=0.03;
facingDirection=DOWN;
animation.ChangeState(internal_animState,AnimationState::WALK_S);
}
}break;
case DOWN:{
if(lastAnimationFlip==0){
lastAnimationFlip=0.03;
facingDirection=UP;
animation.ChangeState(internal_animState,AnimationState::WALK_N);
}
}break;
}
if(facingDirection==RIGHT){
spin_angle+=spin_spd*fElapsedTime;
} else {
spin_angle-=spin_spd*fElapsedTime;
}
if(spin_attack_timer>0){
z=50*sin(3.3*(GROUND_SLAM_SPIN_TIME-spin_attack_timer)/GROUND_SLAM_SPIN_TIME);
spin_attack_timer=std::max(0.f,spin_attack_timer-fElapsedTime);
} else {
state=NORMAL;
spin_angle=0;
z=0;
game->HurtEnemies(pos,3*12,atk*2.5);
game->AddEffect(Effect{GetPos(),0.5,AnimationState::GROUND_SLAM_ATTACK_FRONT,1.33f,0.6f},Effect{GetPos(),0.5,AnimationState::GROUND_SLAM_ATTACK_BACK,1.33f,0.6f});
}
if(lastAnimationFlip>0){
lastAnimationFlip=std::max(0.f,lastAnimationFlip-fElapsedTime);
}
}break;
default:{
//Update animations normally.
}
}
animation.UpdateState(internal_animState,fElapsedTime);
groundSlamCooldown=std::max(0.f,groundSlamCooldown-fElapsedTime);
for(Monster&m:MONSTER_LIST){
if(geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){
if(m.IsAlive()){
m.Collision(*this);
}
geom2d::line line(pos,m.GetPos());
float dist = line.length();
m.SetPosition(line.rpoint(dist*1.1));
if(m.IsAlive()){
vel=line.vector().norm()*-128;
}
}
}
if(vel.x>0){
vel.x=std::max(0.f,vel.x-friction*fElapsedTime);
} else {
vel.x=std::min(0.f,vel.x+friction*fElapsedTime);
}
if(vel.y>0){
vel.y=std::max(0.f,vel.y-friction*fElapsedTime);
} else {
vel.y=std::min(0.f,vel.y+friction*fElapsedTime);
}
float newX=pos.x+vel.x*fElapsedTime;
if(newX-12*size>0&&newX+12*size<game->WORLD_SIZE.x*24){
pos.x=newX;
}
float newY=pos.y+vel.y*fElapsedTime;
if(newY-12*size>0&&newY+12*size<game->WORLD_SIZE.y*24){
pos.y=newY;
}
if(attack_cooldown_timer==0&&game->GetMouse(0).bHeld){
bool attack=false;
Monster*closest=nullptr;
float closest_dist=999999;
for(Monster&m:MONSTER_LIST){
if(m.IsAlive()
&&geom2d::overlaps(geom2d::circle<float>(pos-vf2d{size*12,size*12},attack_range*size*12),geom2d::circle<float>(m.GetPos()-vf2d{m.GetSizeMult()*12,m.GetSizeMult()*12},m.GetSizeMult()*12))
&&geom2d::line<float>(game->GetWorldMousePos(),m.GetPos()).length()<closest_dist){
closest_dist=geom2d::line<float>(game->GetWorldMousePos(),m.GetPos()).length();
closest=&m;
}
}
if(closest!=nullptr&&closest->Hurt(atk)){
attack_cooldown_timer=ATTACK_COOLDOWN;
swordSwingTimer=0.2;
SetState(State::SWING_SWORD);
switch(facingDirection){
case DOWN:{
UpdateAnimation(AnimationState::SWINGSWORD_S);
}break;
case RIGHT:{
UpdateAnimation(AnimationState::SWINGSWORD_E);
}break;
case LEFT:{
UpdateAnimation(AnimationState::SWINGSWORD_W);
}break;
case UP:{
UpdateAnimation(AnimationState::SWINGSWORD_N);
}break;
}
}
}
}
float Player::GetSwordSwingTimer(){
return swordSwingTimer;
}
void Player::SetSwordSwingTimer(float val){
swordSwingTimer=val;
}
void Player::SetState(State newState){
state=newState;
}
vf2d Player::GetVelocity(){
return vel;
}
void Player::Hurt(int damage){
if(hp<=0) return;
hp=std::max(0,hp-damage);
DAMAGENUMBER_LIST.push_back(DamageNumber(pos,damage));
}
void Player::AddAnimation(AnimationState state){
animation.AddState(state,ANIMATION_DATA[state]);
}
void Player::UpdateAnimation(AnimationState animState){
animation.ChangeState(internal_animState,animState);
}
Animate2D::Frame Player::GetFrame(){
return animation.GetFrame(internal_animState);
}
void Player::SetLastReleasedMovementKey(Key k){
lastReleasedMovementKey=k;
}
Key Player::GetLastReleasedMovementKey(){
return lastReleasedMovementKey;
}
void Player::SetFacingDirection(Key direction){
facingDirection=direction;
}
Key Player::GetFacingDirection(){
return facingDirection;
}
void Player::Moved(){
for(MonsterSpawner&spawner:SPAWNER_LIST){
if(!spawner.SpawnTriggered()&&geom2d::overlaps(geom2d::circle<float>(pos-vf2d{size*12,size*12},size*12),geom2d::circle<float>(spawner.GetPos(),spawner.GetRange()))){
spawner.SetTriggered(true);
}
}
}
float Player::GetGroundSlamCooldown(){
return groundSlamCooldown;
}
void Player::Spin(float duration,float spinSpd){
state=State::SPIN;
spin_attack_timer=duration;
spin_spd=spinSpd;
spin_angle=0;
groundSlamCooldown=GROUND_SLAM_COOLDOWN;
}