|
|
|
@ -1,11 +1,13 @@ |
|
|
|
|
#include "Monster.h" |
|
|
|
|
#include "DamageNumber.h" |
|
|
|
|
#include "Crawler.h" |
|
|
|
|
#include "DEFINES.h" |
|
|
|
|
|
|
|
|
|
INCLUDE_ANIMATION_DATA |
|
|
|
|
INCLUDE_MONSTER_DATA |
|
|
|
|
INCLUDE_MONSTER_LIST |
|
|
|
|
INCLUDE_DAMAGENUMBER_LIST |
|
|
|
|
INCLUDE_game |
|
|
|
|
|
|
|
|
|
MonsterData::MonsterData(){} |
|
|
|
|
MonsterData::MonsterData(MonsterName type,int hp,int atk,std::vector<AnimationState>animations,float moveSpd,float size,MonsterStrategy strategy): |
|
|
|
@ -65,14 +67,79 @@ void Monster::UpdateAnimation(AnimationState state){ |
|
|
|
|
animation.ChangeState(internal_animState,state); |
|
|
|
|
} |
|
|
|
|
bool Monster::Update(float fElapsedTime){ |
|
|
|
|
if(IsAlive()){ |
|
|
|
|
for(Monster&m:MONSTER_LIST){ |
|
|
|
|
if(&m==this)continue; |
|
|
|
|
if(geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(m.GetPos(),12*m.GetSizeMult()/2))){ |
|
|
|
|
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(geom2d::overlaps(geom2d::circle(pos,12*size/2),geom2d::circle(game->GetPlayer().GetPos(),12*game->GetPlayer().GetSizeMult()/2))){ |
|
|
|
|
geom2d::line line(pos,game->GetPlayer().GetPos()); |
|
|
|
|
float dist = line.length(); |
|
|
|
|
SetPosition(line.rpoint(-0.1)); |
|
|
|
|
vel=line.vector().norm()*-128; |
|
|
|
|
} |
|
|
|
|
if(state==NORMAL){ |
|
|
|
|
if(game->GetPlayer().GetX()>pos.x){ |
|
|
|
|
facingDirection=RIGHT; |
|
|
|
|
} else { |
|
|
|
|
facingDirection=LEFT; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
switch(strategy){ |
|
|
|
|
RUN_TOWARDS:{ |
|
|
|
|
|
|
|
|
|
case RUN_TOWARDS:{ |
|
|
|
|
targetAcquireTimer=std::max(0.f,targetAcquireTimer-fElapsedTime); |
|
|
|
|
if(targetAcquireTimer==0){ |
|
|
|
|
targetAcquireTimer=3; |
|
|
|
|
target=geom2d::line(pos,game->GetPlayer().GetPos()).upoint(1.2); |
|
|
|
|
state=MOVE_TOWARDS; |
|
|
|
|
} |
|
|
|
|
if(state==MOVE_TOWARDS&&geom2d::line(pos,target).length()>100*fElapsedTime*moveSpd){ |
|
|
|
|
pos+=geom2d::line(pos,target).vector().norm()*100*fElapsedTime*moveSpd; |
|
|
|
|
switch(type){ |
|
|
|
|
case SLIME_GREEN:{ |
|
|
|
|
animation.ChangeState(internal_animState,AnimationState::GREEN_SLIME_JUMP); |
|
|
|
|
}break; |
|
|
|
|
case SLIME_RED:{ |
|
|
|
|
animation.ChangeState(internal_animState,AnimationState::RED_SLIME_JUMP); |
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if(state==MOVE_TOWARDS){ |
|
|
|
|
state=NORMAL;//Revert state once we've finished moving towards target.
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}break; |
|
|
|
|
SHOOT_AFAR:{ |
|
|
|
|
case SHOOT_AFAR:{ |
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
} |
|
|
|
|
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(hp<=0){ |
|
|
|
|
deathTimer+=fElapsedTime; |
|
|
|
|
if(deathTimer>3){ |
|
|
|
@ -83,6 +150,37 @@ bool Monster::Update(float fElapsedTime){ |
|
|
|
|
randomFrameOffset=0; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
Key Monster::GetFacingDirection(){ |
|
|
|
|
return facingDirection; |
|
|
|
|
} |
|
|
|
|
void Monster::Draw(){ |
|
|
|
|
if(GetFacingDirection()==RIGHT){ |
|
|
|
|
game->view.DrawPartialDecal((GetPos()+vf2d{float(GetFrame().GetSourceRect().size.x),0}*GetSizeMult())-vf2d{12,12}*GetSizeMult(),GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult()*-1,GetSizeMult())); |
|
|
|
|
} else { |
|
|
|
|
game->view.DrawPartialDecal(GetPos()-vf2d{12,12}*GetSizeMult(),GetFrame().GetSourceImage()->Decal(),GetFrame().GetSourceRect().pos,GetFrame().GetSourceRect().size,vf2d(GetSizeMult(),GetSizeMult())); |
|
|
|
|
} |
|
|
|
|
if(GetTargetPos()!=vf2d{0,0}){ |
|
|
|
|
game->view.DrawLine(GetPos(),GetTargetPos(),RED,0xF4F4F4F4); |
|
|
|
|
game->view.DrawCircle(GetTargetPos(),6,RED); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void Monster::Collision(Player&p){ |
|
|
|
|
Collision(); |
|
|
|
|
} |
|
|
|
|
void Monster::Collision(Monster&m){ |
|
|
|
|
Collision(); |
|
|
|
|
} |
|
|
|
|
void Monster::Collision(){ |
|
|
|
|
if(strategy==RUN_TOWARDS&&state==MOVE_TOWARDS){ |
|
|
|
|
state=NORMAL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
void Monster::SetVelocity(vf2d vel){ |
|
|
|
|
this->vel=vel; |
|
|
|
|
} |
|
|
|
|
void Monster::SetPosition(vf2d pos){ |
|
|
|
|
this->pos=pos; |
|
|
|
|
} |
|
|
|
|
AnimationState Monster::GetDeathAnimationName(){ |
|
|
|
|
switch(type){ |
|
|
|
|
case SLIME_GREEN:{ |
|
|
|
@ -112,6 +210,9 @@ bool Monster::Hurt(int damage){ |
|
|
|
|
bool Monster::IsAlive(){ |
|
|
|
|
return hp>0; |
|
|
|
|
} |
|
|
|
|
vf2d&Monster::GetTargetPos(){ |
|
|
|
|
return target; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
MonsterSpawner::MonsterSpawner(){} |
|
|
|
|
MonsterSpawner::MonsterSpawner(vf2d pos,int range,std::vector<std::pair<MonsterName,vf2d>>monsters): |
|
|
|
|