Add custom monster strategy properties for monster config files.

pull/28/head
sigonasr2 1 year ago
parent b6d914151f
commit 6cfb40d642
  1. 1
      Crawler/Crawler.vcxproj
  2. 3
      Crawler/Crawler.vcxproj.filters
  3. 10
      Crawler/Monster.h
  4. 7
      Crawler/MonsterStrategyHelpers.h
  5. 32
      Crawler/RUN_STRATEGY.cpp
  6. 14
      Crawler/RunTowards.cpp
  7. 17
      Crawler/ShootAfar.cpp
  8. 3
      Crawler/Turret.cpp
  9. 2
      Crawler/Version.h
  10. 12
      Crawler/assets/config/MonsterStrategies.txt
  11. 2
      Crawler/assets/config/Monsters.txt

@ -272,6 +272,7 @@
<ClInclude Include="Emitter.h" /> <ClInclude Include="Emitter.h" />
<ClInclude Include="Map.h" /> <ClInclude Include="Map.h" />
<ClInclude Include="Monster.h" /> <ClInclude Include="Monster.h" />
<ClInclude Include="MonsterStrategyHelpers.h" />
<ClInclude Include="olcPGEX_TransformedView.h" /> <ClInclude Include="olcPGEX_TransformedView.h" />
<ClInclude Include="olcPixelGameEngine.h" /> <ClInclude Include="olcPixelGameEngine.h" />
<ClInclude Include="olcUTIL_Animate2D.h" /> <ClInclude Include="olcUTIL_Animate2D.h" />

@ -132,6 +132,9 @@
<ClInclude Include="safemap.h"> <ClInclude Include="safemap.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="MonsterStrategyHelpers.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Player.cpp"> <ClCompile Include="Player.cpp">

@ -125,11 +125,13 @@ public:
static void InitializeStrategies(); static void InitializeStrategies();
private: private:
struct STRATEGY{ struct STRATEGY{
static int _GetInt(Monster&m,std::string param,int strategyNumber,int index=0);
static float _GetFloat(Monster&m,std::string param,int strategyNumber,int index=0);
static std::string _GetString(Monster&m,std::string param,int strategyNumber,int index=0);
static void RUN_STRATEGY(Monster&m,float fElapsedTime); static void RUN_STRATEGY(Monster&m,float fElapsedTime);
static void RUN_TOWARDS(Monster&m,float fElapsedTime,int strategyNumber);
static void RUN_TOWARDS(Monster&m,float fElapsedTime); static void SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumber);
static void SHOOT_AFAR(Monster&m,float fElapsedTime); static void TURRET(Monster&m,float fElapsedTime,int strategyNumber);
static void TURRET(Monster&m,float fElapsedTime);
}; };
}; };

@ -0,0 +1,7 @@
#pragma once
#define GetInt(param) _GetInt(m,param,strategyNumber)
#define GetFloat(param) _GetFloat(m,param,strategyNumber)
#define GetString(param) _GetString(m,param,strategyNumber)
#define GetIntArr(param,ind) _GetInt(m,param,strategyNumber,ind)
#define GetFloatArr(param,ind) _GetFloat(m,param,strategyNumber,ind)
#define GetStringArr(param,ind) _GetString(m,param,strategyNumber,ind)

@ -1,15 +1,41 @@
#include "Monster.h" #include "Monster.h"
#include "DEFINES.h"
#include "olcUTIL_DataFile.h"
INCLUDE_DATA
int Monster::STRATEGY::_GetInt(Monster&m,std::string param,int strategyNumber,int index){
if(DATA["Monsters"][std::to_string(m.id)].HasProperty(param)){
return DATA["Monsters"][std::to_string(m.id)][param].GetInt(index);
} else {
return DATA["MonsterStrategy"][std::to_string(strategyNumber)][param].GetInt(index);
}
}
float Monster::STRATEGY::_GetFloat(Monster&m,std::string param,int strategyNumber,int index){
if(DATA["Monsters"][std::to_string(m.id)].HasProperty(param)){
return DATA["Monsters"][std::to_string(m.id)][param].GetReal(index);
} else {
return DATA["MonsterStrategy"][std::to_string(strategyNumber)][param].GetReal(index);
}
}
std::string Monster::STRATEGY::_GetString(Monster&m,std::string param,int strategyNumber,int index){
if(DATA["Monsters"][std::to_string(m.id)].HasProperty(param)){
return DATA["Monsters"][std::to_string(m.id)][param].GetString(index);
} else {
return DATA["MonsterStrategy"][std::to_string(strategyNumber)][param].GetString(index);
}
}
void Monster::STRATEGY::RUN_STRATEGY(Monster&m,float fElapsedTime){ void Monster::STRATEGY::RUN_STRATEGY(Monster&m,float fElapsedTime){
switch(m.strategy){ switch(m.strategy){
case 0:{//Run Towards case 0:{//Run Towards
Monster::STRATEGY::RUN_TOWARDS(m,fElapsedTime); Monster::STRATEGY::RUN_TOWARDS(m,fElapsedTime,m.strategy);
}break; }break;
case 1:{//Shoot Afar case 1:{//Shoot Afar
Monster::STRATEGY::SHOOT_AFAR(m,fElapsedTime); Monster::STRATEGY::SHOOT_AFAR(m,fElapsedTime,m.strategy);
}break; }break;
case 2:{//Turret. case 2:{//Turret.
Monster::STRATEGY::TURRET(m,fElapsedTime); Monster::STRATEGY::TURRET(m,fElapsedTime,m.strategy);
}break; }break;
} }
} }

@ -1,15 +1,23 @@
#include "Monster.h" #include "Monster.h"
#include "DEFINES.h" #include "DEFINES.h"
#include "Crawler.h" #include "Crawler.h"
#include "MonsterStrategyHelpers.h"
INCLUDE_game INCLUDE_game
INCLUDE_MONSTER_DATA INCLUDE_MONSTER_DATA
void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime){ void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime,int strategyNumber){
m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime); m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime);
if(m.targetAcquireTimer==0){ if(m.targetAcquireTimer==0){
m.targetAcquireTimer=3; m.targetAcquireTimer=GetFloat("WaitTime");
m.target=geom2d::line(m.pos,game->GetPlayer()->GetPos()).upoint(1.2);
auto desiredTargetLine = geom2d::line(m.pos,game->GetPlayer()->GetPos());
if(desiredTargetLine.length()>=GetInt("MaxDistance")/100.f*24){
//Trim to max distance desired.
m.target=desiredTargetLine.rpoint(GetInt("MaxDistance")/100.f*24);
} else {
m.target=desiredTargetLine.upoint(1.2);
}
m.SetState(MOVE_TOWARDS); m.SetState(MOVE_TOWARDS);
m.hasHitPlayer=false; m.hasHitPlayer=false;
} }

@ -1,11 +1,12 @@
#include "Monster.h" #include "Monster.h"
#include "DEFINES.h" #include "DEFINES.h"
#include "Crawler.h" #include "Crawler.h"
#include "MonsterStrategyHelpers.h"
INCLUDE_BULLET_LIST INCLUDE_BULLET_LIST
INCLUDE_game INCLUDE_game
void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime){ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime,int strategyNumber){
m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime); m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime);
m.attackCooldownTimer=std::max(0.f,m.attackCooldownTimer-fElapsedTime); m.attackCooldownTimer=std::max(0.f,m.attackCooldownTimer-fElapsedTime);
if(m.queueShotTimer>0){ if(m.queueShotTimer>0){
@ -13,14 +14,14 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime){
if(m.queueShotTimer<0){ if(m.queueShotTimer<0){
m.queueShotTimer=0; m.queueShotTimer=0;
{ {
BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(m.pos + vf2d{ 0,-4 }, geom2d::line(m.pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24 * 3.f, 2, m.GetAttack(),m.upperLevel,false, { 75 / 2,162 / 2,225 / 2 }))); BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(m.pos + vf2d{ 0,-4 }, geom2d::line(m.pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24 * GetInt("BulletSpeed")/100.f, 24.f*GetInt("BulletSize")/100.f, m.GetAttack(),m.upperLevel,false, { uint8_t(GetIntArr("BulletColor",0)),uint8_t(GetIntArr("BulletColor",1)),uint8_t(GetIntArr("BulletColor",2)),uint8_t(GetIntArr("BulletColor",3) )})));
} }
} }
} }
geom2d::line line(m.pos,game->GetPlayer()->GetPos()); geom2d::line line(m.pos,game->GetPlayer()->GetPos());
if(m.targetAcquireTimer==0&&m.queueShotTimer==0){ if(m.targetAcquireTimer==0&&m.queueShotTimer==0){
m.targetAcquireTimer=1; m.targetAcquireTimer=1;
if(line.length()<24*6){ if(line.length()<24.f*GetInt("Range")/100.f){
m.target=line.upoint(-1.2); m.target=line.upoint(-1.2);
if(m.canMove){ if(m.canMove){
m.SetState(MOVE_AWAY); m.SetState(MOVE_AWAY);
@ -28,7 +29,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime){
m.SetState(NORMAL); m.SetState(NORMAL);
} }
} else } else
if(line.length()>24*7){ if(line.length()>24.f*GetInt("CloseInRange")/100.0f){
m.target=line.upoint(1.2); m.target=line.upoint(1.2);
m.SetState(MOVE_TOWARDS); m.SetState(MOVE_TOWARDS);
} else { } else {
@ -50,7 +51,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime){
if(!pathfindingDecision){ if(!pathfindingDecision){
m.StartPathfinding(2.5); m.StartPathfinding(2.5);
}else }else
if(line.length()<=24*7){ if(line.length()<=24.f*GetInt("CloseInRange")/100.0f){
m.SetState(NORMAL); m.SetState(NORMAL);
} }
if(moveTowardsLine.vector().x>0){ if(moveTowardsLine.vector().x>0){
@ -71,7 +72,7 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime){
if(!pathfindingDecision){ if(!pathfindingDecision){
m.StartPathfinding(2.5); m.StartPathfinding(2.5);
}else }else
if(line.length()>=24*6){ if(line.length()>=24.f*GetInt("Range")/100.f){
m.SetState(NORMAL); m.SetState(NORMAL);
} }
if(moveTowardsLine.vector().x>0){ if(moveTowardsLine.vector().x>0){
@ -86,8 +87,8 @@ void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime){
}break; }break;
default:{ default:{
if(m.attackCooldownTimer==0){ if(m.attackCooldownTimer==0){
m.attackCooldownTimer=1; m.attackCooldownTimer=GetFloat("ShootingSpeed");
m.queueShotTimer=0.7; m.queueShotTimer=std::min(m.attackCooldownTimer-0.001,0.7);
m.PerformShootAnimation(); m.PerformShootAnimation();
} }
} }

@ -1,5 +1,6 @@
#include "Monster.h" #include "Monster.h"
#include "MonsterStrategyHelpers.h"
void Monster::STRATEGY::TURRET(Monster&m,float fElapsedTime){ void Monster::STRATEGY::TURRET(Monster&m,float fElapsedTime,int strategyNumber){
} }

@ -2,7 +2,7 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 0 #define VERSION_PATCH 0
#define VERSION_BUILD 992 #define VERSION_BUILD 999
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -40,7 +40,7 @@ MonsterStrategy
{ {
Name = Run Towards Name = Run Towards
# How long to wait before attempting to path again. # How long to wait before attempting to path again.
WaitTime = 2 WaitTime = 3
# How far the monster will travel before reassessing for a new path. # How far the monster will travel before reassessing for a new path.
MaxDistance = 999999 MaxDistance = 999999
} }
@ -48,12 +48,14 @@ MonsterStrategy
{ {
Name = Shoot Afar Name = Shoot Afar
# How far away the monster attempts to distance itself from the player # How far away the monster attempts to distance itself from the player
Range = 800 Range = 700
# If the player is farther than this distance, close in on them.
CloseInRange = 850
# How often the enemy shoots. # How often the enemy shoots.
ShootingSpeed = 1 ShootingSpeed = 1
BulletSpeed = 100 BulletSpeed = 300
BulletSize = 100 BulletSize = 8
BulletColor = 0, 0, 255, 255 BulletColor = 37, 131, 112, 255
} }
2 2
{ {

@ -44,7 +44,7 @@ Monsters
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse) # Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
IdleAnimation = 10, 0.1, Repeat IdleAnimation = 10, 0.1, Repeat
JumpAnimation = 10, 0.06, Repeat JumpAnimation = 10, 0.06, Repeat
ShootAnimation = 10, 0.1, OneShot ShootAnimation = 10, 0.1, Repeat
DeathAnimation = 10, 0.1, OneShot DeathAnimation = 10, 0.1, OneShot
#Additional custom animations go down below. Start with ANIMATION[0] #Additional custom animations go down below. Start with ANIMATION[0]

Loading…
Cancel
Save