Wolf behavior implemented. Fixed facing direction behavior for AI scripts.
This commit is contained in:
parent
acaf1bc3bf
commit
db9c35f813
@ -1983,7 +1983,7 @@ geom2d::rect<float>AiL::GetTileCollision(MapName map,vf2d pos,bool upperLevel){
|
|||||||
int tileID=layer.tiles[int(pos.y)/GetCurrentMapData().tilewidth][int(pos.x)/GetCurrentMapData().tilewidth]-1;
|
int tileID=layer.tiles[int(pos.y)/GetCurrentMapData().tilewidth][int(pos.x)/GetCurrentMapData().tilewidth]-1;
|
||||||
if(tileID!=-1&&GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){
|
if(tileID!=-1&&GetTileSheet(map,tileID%1000000).tileset->collision.find(tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1)!=GetTileSheet(map,tileID%1000000).tileset->collision.end()){
|
||||||
geom2d::rect<float>collisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
|
geom2d::rect<float>collisionRect=GetTileSheet(map,tileID%1000000).tileset->collision[tileID%1000000-GetTileSheet(map,tileID%1000000).firstgid+1].collision;
|
||||||
if(foundRect.pos==NO_COLLISION.pos&&foundRect.size==NO_COLLISION.size){
|
if(foundRect==NO_COLLISION){
|
||||||
foundRect=collisionRect;
|
foundRect=collisionRect;
|
||||||
}else{
|
}else{
|
||||||
//When we find another rectangle in the same square, we expand it to consume the area, whichever tile creates a larger surface or the combination of the two.
|
//When we find another rectangle in the same square, we expand it to consume the area, whichever tile creates a larger surface or the combination of the two.
|
||||||
|
@ -74,4 +74,10 @@ public:
|
|||||||
}
|
}
|
||||||
return std::get<vf2d>(attributes[a]);
|
return std::get<vf2d>(attributes[a]);
|
||||||
};
|
};
|
||||||
|
inline std::vector<std::any>&GetVec(Attribute a){
|
||||||
|
if(attributes.count(a)==0){
|
||||||
|
attributes[a]=std::vector<std::any>{};
|
||||||
|
}
|
||||||
|
return std::get<std::vector<std::any>>(attributes[a]);
|
||||||
|
};
|
||||||
};
|
};
|
@ -65,7 +65,7 @@ using BackdropName=std::string;
|
|||||||
|
|
||||||
#define ACCESS_PLAYER Player*p=game->GetPlayer();
|
#define ACCESS_PLAYER Player*p=game->GetPlayer();
|
||||||
|
|
||||||
#define VARIANTS float,int,std::string,bool,vf2d
|
#define VARIANTS float,int,std::string,bool,vf2d,std::vector<std::any>
|
||||||
#undef INFINITE
|
#undef INFINITE
|
||||||
#define INFINITE 999999
|
#define INFINITE 999999
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ bool Monster::_SetX(float x,const bool monsterInvoked){
|
|||||||
vf2d newPos={x,pos.y};
|
vf2d newPos={x,pos.y};
|
||||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||||
if(collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size){
|
if(collisionRect==game->NO_COLLISION){
|
||||||
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
||||||
Moved();
|
Moved();
|
||||||
return true;
|
return true;
|
||||||
@ -155,7 +155,7 @@ bool Monster::_SetY(float y,const bool monsterInvoked){
|
|||||||
vf2d newPos={pos.x,y};
|
vf2d newPos={pos.x,y};
|
||||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||||
if(collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size){
|
if(collisionRect==game->NO_COLLISION){
|
||||||
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
||||||
Moved();
|
Moved();
|
||||||
return true;
|
return true;
|
||||||
@ -267,6 +267,15 @@ bool Monster::Update(float fElapsedTime){
|
|||||||
Key Monster::GetFacingDirection(){
|
Key Monster::GetFacingDirection(){
|
||||||
return facingDirection;
|
return facingDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Monster::UpdateFacingDirection(vf2d facingTargetPoint){
|
||||||
|
if(facingTargetPoint.x>GetPos().x){
|
||||||
|
facingDirection=RIGHT;
|
||||||
|
}
|
||||||
|
if(facingTargetPoint.x<GetPos().x){
|
||||||
|
facingDirection=LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
void Monster::Draw(){
|
void Monster::Draw(){
|
||||||
if(GetZ()>0){
|
if(GetZ()>0){
|
||||||
vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24);
|
vf2d shadowScale=vf2d{8*GetSizeMult()/3.f,1}/std::max(1.f,GetZ()/24);
|
||||||
@ -458,6 +467,10 @@ void Monster::AddBuff(BuffType type,float duration,float intensity){
|
|||||||
buffList.push_back(Buff{type,duration,intensity});
|
buffList.push_back(Buff{type,duration,intensity});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Monster::RemoveBuff(BuffType type){
|
||||||
|
std::erase_if(buffList,[&](const Buff&buff){return buff.type==type;});
|
||||||
|
}
|
||||||
|
|
||||||
bool Monster::StartPathfinding(float pathingTime){
|
bool Monster::StartPathfinding(float pathingTime){
|
||||||
SetState(State::PATH_AROUND);
|
SetState(State::PATH_AROUND);
|
||||||
path=game->pathfinder.Solve_WalkPath(pos,target,12,OnUpperLevel());
|
path=game->pathfinder.Solve_WalkPath(pos,target,12,OnUpperLevel());
|
||||||
@ -480,11 +493,7 @@ void Monster::PathAroundBehavior(float fElapsedTime){
|
|||||||
pathIndex=0;
|
pathIndex=0;
|
||||||
targetAcquireTimer=0;
|
targetAcquireTimer=0;
|
||||||
}
|
}
|
||||||
if(moveTowardsLine.vector().x>0){
|
UpdateFacingDirection(moveTowardsLine.end);
|
||||||
facingDirection=RIGHT;
|
|
||||||
} else {
|
|
||||||
facingDirection=LEFT;
|
|
||||||
}
|
|
||||||
}else{
|
}else{
|
||||||
if(pathIndex>=path.points.size()-1){
|
if(pathIndex>=path.points.size()-1){
|
||||||
//We have reached the end of the path!
|
//We have reached the end of the path!
|
||||||
|
@ -133,6 +133,8 @@ public:
|
|||||||
bool IsAlive();
|
bool IsAlive();
|
||||||
vf2d&GetTargetPos();
|
vf2d&GetTargetPos();
|
||||||
Key GetFacingDirection();
|
Key GetFacingDirection();
|
||||||
|
//Will make the monster face in the correct direction relative to a given target point to look at.
|
||||||
|
void UpdateFacingDirection(vf2d facingTargetPoint);
|
||||||
void Draw();
|
void Draw();
|
||||||
void DrawReflection(float drawRatioX,float multiplierX);
|
void DrawReflection(float drawRatioX,float multiplierX);
|
||||||
void Collision(Player*p);
|
void Collision(Player*p);
|
||||||
@ -155,6 +157,8 @@ public:
|
|||||||
void PathAroundBehavior(float fElapsedTime);
|
void PathAroundBehavior(float fElapsedTime);
|
||||||
void AddBuff(BuffType type,float duration,float intensity);
|
void AddBuff(BuffType type,float duration,float intensity);
|
||||||
std::vector<Buff>GetBuffs(BuffType buff);
|
std::vector<Buff>GetBuffs(BuffType buff);
|
||||||
|
//Removes all buffs of a given type.
|
||||||
|
void RemoveBuff(BuffType type);
|
||||||
State::State GetState();
|
State::State GetState();
|
||||||
void SetState(State::State newState);
|
void SetState(State::State newState);
|
||||||
static void InitializeStrategies();
|
static void InitializeStrategies();
|
||||||
|
@ -42,6 +42,7 @@ All rights reserved.
|
|||||||
#define S(attr) GetString(attr)
|
#define S(attr) GetString(attr)
|
||||||
#define B(attr) GetBool(attr)
|
#define B(attr) GetBool(attr)
|
||||||
#define V(attr) GetVf2d(attr)
|
#define V(attr) GetVf2d(attr)
|
||||||
|
#define VEC(attr) GetVec(attr)
|
||||||
|
|
||||||
enum class Attribute{
|
enum class Attribute{
|
||||||
IFRAME_TIME_UPON_HIT, //When this is set, the monster gains iframes if they take damage based on the value this is set to.
|
IFRAME_TIME_UPON_HIT, //When this is set, the monster gains iframes if they take damage based on the value this is set to.
|
||||||
@ -79,4 +80,9 @@ enum class Attribute{
|
|||||||
PHASE,
|
PHASE,
|
||||||
LOCKON_WAITTIME,
|
LOCKON_WAITTIME,
|
||||||
LOCKON_POS,
|
LOCKON_POS,
|
||||||
|
TARGET_TIMER,
|
||||||
|
DISENGAGE_PATH,
|
||||||
|
PATH_INDEX,
|
||||||
|
PATH_DIR,
|
||||||
|
PREV_POS,
|
||||||
};
|
};
|
@ -63,13 +63,13 @@ void Pathfinding::Initialize(){
|
|||||||
node.x = x; // ...because we give each node its own coordinates
|
node.x = x; // ...because we give each node its own coordinates
|
||||||
node.y = y; // ...because we give each node its own coordinates
|
node.y = y; // ...because we give each node its own coordinates
|
||||||
geom2d::rect<float>tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)});
|
geom2d::rect<float>tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)});
|
||||||
if(tile.pos==game->NO_COLLISION.pos&&tile.size==game->NO_COLLISION.size){
|
if(tile==game->NO_COLLISION){
|
||||||
node.bObstacle=false;
|
node.bObstacle=false;
|
||||||
}else{
|
}else{
|
||||||
node.bObstacle=geom2d::overlaps(vf2d{fmodf(x+gridSpacing.x/2,24),fmodf(y+gridSpacing.y/2,24)},tile);
|
node.bObstacle=geom2d::overlaps(vf2d{fmodf(x+gridSpacing.x/2,24),fmodf(y+gridSpacing.y/2,24)},tile);
|
||||||
}
|
}
|
||||||
tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)},true);
|
tile=game->GetTileCollision(game->GetCurrentLevel(),{float(x),float(y)},true);
|
||||||
if(tile.pos==game->NO_COLLISION.pos&&tile.size==game->NO_COLLISION.size){
|
if(tile==game->NO_COLLISION){
|
||||||
node.bObstacleUpper=false;
|
node.bObstacleUpper=false;
|
||||||
}else{
|
}else{
|
||||||
node.bObstacleUpper=geom2d::overlaps(vf2d{fmodf(x,24),fmodf(y,24)},tile);
|
node.bObstacleUpper=geom2d::overlaps(vf2d{fmodf(x,24),fmodf(y,24)},tile);
|
||||||
|
@ -110,7 +110,7 @@ bool Player::_SetX(float x,const bool playerInvoked){
|
|||||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||||
#pragma region lambdas
|
#pragma region lambdas
|
||||||
auto NoTileCollisionExistsHere=[&](){return collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size;};
|
auto NoTileCollisionExistsHere=[&](){return collisionRect==game->NO_COLLISION;};
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
if(NoTileCollisionExistsHere()){
|
if(NoTileCollisionExistsHere()){
|
||||||
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
pos.x=std::clamp(x,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().width*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
||||||
@ -143,7 +143,7 @@ bool Player::_SetY(float y,const bool playerInvoked){
|
|||||||
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(newPos/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),newPos,upperLevel);
|
||||||
#pragma region lambdas
|
#pragma region lambdas
|
||||||
auto NoTileCollisionExistsHere=[&](){return collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size;};
|
auto NoTileCollisionExistsHere=[&](){return collisionRect==game->NO_COLLISION;};
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
if(NoTileCollisionExistsHere()){
|
if(NoTileCollisionExistsHere()){
|
||||||
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
pos.y=std::clamp(y,game->GetCurrentMapData().tilewidth/2.f*GetSizeMult(),float(game->GetCurrentMapData().height*game->GetCurrentMapData().tilewidth-game->GetCurrentMapData().tilewidth/2.f*GetSizeMult()));
|
||||||
|
@ -159,11 +159,15 @@ public:
|
|||||||
void AddBuff(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr);
|
void AddBuff(BuffType type,float duration,float intensity,std::set<ItemAttribute>attr);
|
||||||
void AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr);
|
void AddBuff(BuffType type,float duration,float intensity,std::set<std::string>attr);
|
||||||
void AddBuff(BuffType type,float duration,float intensity,float timeBetweenTicks,std::function<void(AiL*,int)>repeatAction);
|
void AddBuff(BuffType type,float duration,float intensity,float timeBetweenTicks,std::function<void(AiL*,int)>repeatAction);
|
||||||
|
|
||||||
const std::vector<Buff>GetBuffs(BuffType buff)const;
|
const std::vector<Buff>GetBuffs(BuffType buff)const;
|
||||||
const std::vector<Buff>GetStatBuffs(const std::vector<std::string>&attr)const;
|
const std::vector<Buff>GetStatBuffs(const std::vector<std::string>&attr)const;
|
||||||
void RemoveBuff(BuffType type); //Removes the first buff found.
|
//Removes the first buff found.
|
||||||
void RemoveAllBuffs(BuffType type); //Removes all buffs of a certain type.
|
void RemoveBuff(BuffType type);
|
||||||
void RemoveAllBuffs(); //Remove every buff.
|
//Removes all buffs of a certain type.
|
||||||
|
void RemoveAllBuffs(BuffType type);
|
||||||
|
//Remove every buff.
|
||||||
|
void RemoveAllBuffs();
|
||||||
|
|
||||||
void RecalculateEquipStats();
|
void RecalculateEquipStats();
|
||||||
|
|
||||||
|
@ -58,6 +58,9 @@ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,std::string str
|
|||||||
}
|
}
|
||||||
m.SetState(State::MOVE_TOWARDS);
|
m.SetState(State::MOVE_TOWARDS);
|
||||||
}
|
}
|
||||||
|
if(geom2d::line(m.pos,m.target).length()>4.f){
|
||||||
|
m.UpdateFacingDirection(m.target);
|
||||||
|
}
|
||||||
switch(m.state){
|
switch(m.state){
|
||||||
case State::MOVE_TOWARDS:{
|
case State::MOVE_TOWARDS:{
|
||||||
if(geom2d::line(m.pos,m.target).length()>100*fElapsedTime*m.GetMoveSpdMult()){
|
if(geom2d::line(m.pos,m.target).length()>100*fElapsedTime*m.GetMoveSpdMult()){
|
||||||
|
@ -101,11 +101,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,std::string stra
|
|||||||
if(line.length()<=24.f*ConfigInt("CloseInRange")/100.0f){
|
if(line.length()<=24.f*ConfigInt("CloseInRange")/100.0f){
|
||||||
m.SetState(State::NORMAL);
|
m.SetState(State::NORMAL);
|
||||||
}
|
}
|
||||||
if(moveTowardsLine.vector().x>0){
|
m.UpdateFacingDirection(moveTowardsLine.end);
|
||||||
m.facingDirection=RIGHT;
|
|
||||||
} else {
|
|
||||||
m.facingDirection=LEFT;
|
|
||||||
}
|
|
||||||
m.PerformJumpAnimation();
|
m.PerformJumpAnimation();
|
||||||
}break;
|
}break;
|
||||||
case State::MOVE_AWAY:{
|
case State::MOVE_AWAY:{
|
||||||
@ -129,11 +125,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,std::string stra
|
|||||||
if((m.path.points.size()==0&&!m.canMove)||line.length()>=24.f*ConfigInt("Range")/100.f){
|
if((m.path.points.size()==0&&!m.canMove)||line.length()>=24.f*ConfigInt("Range")/100.f){
|
||||||
m.SetState(State::NORMAL);
|
m.SetState(State::NORMAL);
|
||||||
}
|
}
|
||||||
if(moveTowardsLine.vector().x>0){
|
m.UpdateFacingDirection(moveTowardsLine.end);
|
||||||
m.facingDirection=RIGHT;
|
|
||||||
} else {
|
|
||||||
m.facingDirection=LEFT;
|
|
||||||
}
|
|
||||||
m.PerformJumpAnimation();
|
m.PerformJumpAnimation();
|
||||||
}break;
|
}break;
|
||||||
case State::PATH_AROUND:{
|
case State::PATH_AROUND:{
|
||||||
|
@ -12,6 +12,8 @@ Settings Menu
|
|||||||
|
|
||||||
January 31st
|
January 31st
|
||||||
============
|
============
|
||||||
|
Make new unlocked nodes more obvious, made neighboring nodes more obvious
|
||||||
|
|
||||||
Implement the rest of the enemy types:
|
Implement the rest of the enemy types:
|
||||||
- Baby Wolf
|
- Baby Wolf
|
||||||
- Wolf
|
- Wolf
|
||||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 2
|
||||||
#define VERSION_PATCH 1
|
#define VERSION_PATCH 1
|
||||||
#define VERSION_BUILD 5761
|
#define VERSION_BUILD 5794
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -124,7 +124,7 @@ void Wizard::InitializeClassAbilities(){
|
|||||||
vi2d tilePos=vi2d(teleportPoint/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
vi2d tilePos=vi2d(teleportPoint/float(game->GetCurrentMapData().tilewidth))*game->GetCurrentMapData().tilewidth;
|
||||||
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),teleportPoint,p->OnUpperLevel());
|
geom2d::rect<float>collisionRect=game->GetTileCollision(game->GetCurrentLevel(),teleportPoint,p->OnUpperLevel());
|
||||||
#pragma region lambdas
|
#pragma region lambdas
|
||||||
auto NoTileCollisionExistsHere=[&](){return collisionRect.pos==game->NO_COLLISION.pos&&collisionRect.size==game->NO_COLLISION.size;};
|
auto NoTileCollisionExistsHere=[&](){return collisionRect==game->NO_COLLISION;};
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
collisionRect.pos+=tilePos;
|
collisionRect.pos+=tilePos;
|
||||||
#pragma region lambdas
|
#pragma region lambdas
|
||||||
|
@ -51,20 +51,74 @@ using A=Attribute;
|
|||||||
void Monster::STRATEGY::WOLF(Monster&m,float fElapsedTime,std::string strategy){
|
void Monster::STRATEGY::WOLF(Monster&m,float fElapsedTime,std::string strategy){
|
||||||
switch(m.I(A::PHASE)){
|
switch(m.I(A::PHASE)){
|
||||||
case 0:{ //Run towards the player.
|
case 0:{ //Run towards the player.
|
||||||
float distToPlayer = geom2d::line<float>(game->GetPlayer()->GetPos(),m.GetPos()).length();
|
float distToPlayer=geom2d::line<float>(game->GetPlayer()->GetPos(),m.GetPos()).length();
|
||||||
if(distToPlayer<=ConfigFloat("Lockon Range")){
|
if(distToPlayer<=ConfigFloat("Lockon Range")/100*24.f){
|
||||||
m.I(A::PHASE)=1;
|
m.I(A::PHASE)=1;
|
||||||
m.V(A::LOCKON_POS)=game->GetPlayer()->GetPos();
|
m.V(A::LOCKON_POS)=geom2d::line<float>(m.GetPos(),game->GetPlayer()->GetPos()).upoint(1.2f);
|
||||||
m.AddBuff(BuffType::)
|
m.AddBuff(BuffType::LOCKON_SPEEDBOOST,INFINITE,ConfigFloat("Lockon Speed Boost")/100);
|
||||||
|
m.F(A::TARGET_TIMER)=5.0f;
|
||||||
}
|
}
|
||||||
|
m.target=game->GetPlayer()->GetPos();
|
||||||
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
|
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
|
||||||
}break;
|
}break;
|
||||||
case 1:{ //Charge the player.
|
case 1:{ //Charge the player.
|
||||||
|
m.F(A::TARGET_TIMER)=std::max(0.f,m.F(A::TARGET_TIMER)-fElapsedTime);
|
||||||
|
float distToTarget=geom2d::line<float>(m.GetPos(),m.V(A::LOCKON_POS)).length();
|
||||||
|
if(distToTarget<=12.f||m.F(A::TARGET_TIMER)==0.f){
|
||||||
|
m.I(A::PHASE)=2;
|
||||||
|
m.F(A::RECOVERY_TIME)=ConfigFloat("Charge Recovery Time");
|
||||||
|
m.PerformIdleAnimation();
|
||||||
|
}else{
|
||||||
|
m.target=m.V(A::LOCKON_POS);
|
||||||
|
RUN_TOWARDS(m,fElapsedTime,"Run Towards");
|
||||||
|
}
|
||||||
}break;
|
}break;
|
||||||
case 3:{
|
case 2:{ //Recovery period after charging.
|
||||||
|
m.F(A::RECOVERY_TIME)=std::max(0.f,m.F(A::RECOVERY_TIME)-fElapsedTime);
|
||||||
|
if(m.F(A::RECOVERY_TIME)==0.f){
|
||||||
|
m.RemoveBuff(BuffType::LOCKON_SPEEDBOOST);
|
||||||
|
m.AddBuff(BuffType::SPEEDBOOST,ConfigFloatArr("Disengage Speed Boost",1),ConfigFloatArr("Disengage Speed Boost",0)/100);
|
||||||
|
std::vector<vf2d>disengagePoints;
|
||||||
|
for(float angle=0.f;angle<360.f;angle+=22.5f){
|
||||||
|
float range=50;
|
||||||
|
vf2d checkLoc=vf2d{0,util::degToRad(angle)}.cart();
|
||||||
|
while(range<=ConfigFloat("Disengage Range")){
|
||||||
|
checkLoc=game->GetPlayer()->GetPos()+vf2d{range/100*24.f,util::degToRad(angle)}.cart();
|
||||||
|
if(game->GetTileCollision(game->GetCurrentMapName(),checkLoc,m.OnUpperLevel())!=game->NO_COLLISION){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
range+=50;
|
||||||
|
}
|
||||||
|
disengagePoints.push_back(checkLoc);
|
||||||
|
}
|
||||||
|
m.path.Initialize(disengagePoints);
|
||||||
|
if(disengagePoints.size()!=16)ERR(std::format("Disengage Points size was not equal to 16! Size: {}",disengagePoints.size()));
|
||||||
|
if(m.path.points.size()!=16)ERR(std::format("Path Points size was not equal to 16! Size: {}",m.path.points.size()));
|
||||||
|
m.I(A::PATH_DIR)=util::random()%2;
|
||||||
|
if(m.I(A::PATH_DIR)==0)m.I(A::PATH_DIR)=-1;
|
||||||
|
m.pathIndex=util::random()%disengagePoints.size();
|
||||||
|
m.I(A::PHASE)=3;
|
||||||
|
m.F(A::RUN_AWAY_TIMER)=ConfigFloat("Disengage Duration");
|
||||||
|
m.PerformJumpAnimation();
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case 3:{ //Disengage.
|
||||||
|
m.F(A::RUN_AWAY_TIMER)=std::max(0.f,m.F(A::RUN_AWAY_TIMER)-fElapsedTime);
|
||||||
|
m.pathIndex+=m.I(A::PATH_DIR)*fElapsedTime*1.25f;
|
||||||
|
m.pathIndex=fmod(m.pathIndex,m.path.points.size());
|
||||||
|
if(m.pathIndex<0){ //When the modulus is negative, adding the total number of elements gets us to the correct index.
|
||||||
|
m.pathIndex=m.pathIndex+m.path.points.size();
|
||||||
|
}
|
||||||
|
if(m.F(A::RUN_AWAY_TIMER)==0.f){
|
||||||
|
m.I(A::PHASE)=0;
|
||||||
|
}
|
||||||
|
m.target=m.path.GetSplinePoint(m.pathIndex).pos;
|
||||||
|
geom2d::line<float>moveTowardsLine=geom2d::line(m.pos,m.path.GetSplinePoint(m.pathIndex).pos);
|
||||||
|
|
||||||
|
if(moveTowardsLine.length()>4.f){
|
||||||
|
m.UpdateFacingDirection(moveTowardsLine.end);
|
||||||
|
}
|
||||||
|
m.SetPos(m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult());
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1075,7 +1075,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<object id="4" name="Green Slime" type="Monster" x="1052" y="4304">
|
<object id="4" name="Green Slime" type="Monster" x="1052" y="4304">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Type" propertytype="MonsterName" value="Frog"/>
|
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
|
||||||
<property name="spawner" type="object" value="2"/>
|
<property name="spawner" type="object" value="2"/>
|
||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
@ -1716,14 +1716,14 @@
|
|||||||
</object>
|
</object>
|
||||||
<object id="151" name="Green Slime" type="Monster" x="1056" y="4386">
|
<object id="151" name="Green Slime" type="Monster" x="1056" y="4386">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Type" propertytype="MonsterName" value="Frog"/>
|
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
|
||||||
<property name="spawner" type="object" value="2"/>
|
<property name="spawner" type="object" value="2"/>
|
||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
</object>
|
</object>
|
||||||
<object id="155" name="Green Slime" type="Monster" x="1050" y="4218">
|
<object id="155" name="Green Slime" type="Monster" x="1050" y="4218">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="Type" propertytype="MonsterName" value="Frog"/>
|
<property name="Type" propertytype="MonsterName" value="Green Slime"/>
|
||||||
<property name="spawner" type="object" value="2"/>
|
<property name="spawner" type="object" value="2"/>
|
||||||
</properties>
|
</properties>
|
||||||
<point/>
|
<point/>
|
||||||
|
@ -198,10 +198,16 @@ MonsterStrategy
|
|||||||
# The speed boost percentage to increase by during the charge.
|
# The speed boost percentage to increase by during the charge.
|
||||||
Lockon Speed Boost = 15%
|
Lockon Speed Boost = 15%
|
||||||
|
|
||||||
|
# Time waiting after charging.
|
||||||
|
Charge Recovery Time = 1.0s
|
||||||
|
|
||||||
# The speed boost percentage to increase by and the duration while disengaging.
|
# The speed boost percentage to increase by and the duration while disengaging.
|
||||||
Disengage Speed Boost = 30%, 3s
|
Disengage Speed Boost = 30%, 3s
|
||||||
|
|
||||||
# The distance to disengage the player.
|
# The distance to disengage the player.
|
||||||
Disengage Range = 800
|
Disengage Range = 800
|
||||||
|
|
||||||
|
# The amount of time to spend disengaged.
|
||||||
|
Disengage Duration = 3.0s
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -221,7 +221,7 @@ Monsters
|
|||||||
|
|
||||||
XP = 14
|
XP = 14
|
||||||
|
|
||||||
Strategy = Run Towards
|
Strategy = Wolf
|
||||||
|
|
||||||
#Size of each animation frame
|
#Size of each animation frame
|
||||||
SheetFrameSize = 24,24
|
SheetFrameSize = 24,24
|
||||||
|
@ -2428,6 +2428,11 @@ namespace olc::utils::geom2d
|
|||||||
|
|
||||||
return internal::filter_duplicate_points(intersections);
|
return internal::filter_duplicate_points(intersections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline const bool operator ==(const rect<T>&r1,const rect<T>&r2){
|
||||||
|
return r1.pos==r2.pos&&r1.size==r2.size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace olc;
|
using namespace olc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user