Refactored dynamic variable system, removed _ATTRIBUTE and type dependency, and optional default value issues.

Moved all slime kind related stuff out of global monster update loop.
pull/28/head
sigonasr2 1 year ago
parent ac93b32e8a
commit 54e72d088e
  1. 1
      Crawler/Crawler.vcxproj
  2. 3
      Crawler/Crawler.vcxproj.filters
  3. 57
      Crawler/Monster.cpp
  4. 11
      Crawler/Monster.h
  5. 11
      Crawler/MonsterAttribute.cpp
  6. 36
      Crawler/MonsterAttribute.h
  7. 19
      Crawler/SlimeKing.cpp
  8. 2
      Crawler/Version.h

@ -307,7 +307,6 @@
<ClCompile Include="LightningBoltEmitter.cpp" />
<ClCompile Include="Map.cpp" />
<ClCompile Include="Meteor.cpp" />
<ClCompile Include="MonsterAttribute.cpp" />
<ClCompile Include="RunTowards.cpp" />
<ClCompile Include="Pathfinding.cpp" />
<ClCompile Include="pixelGameEngine.cpp" />

@ -239,9 +239,6 @@
<ClCompile Include="SlimeKing.cpp">
<Filter>Source Files\Monster Strategies</Filter>
</ClCompile>
<ClCompile Include="MonsterAttribute.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />

@ -110,9 +110,6 @@ bool Monster::SetY(float y){
bool Monster::Update(float fElapsedTime){
lastHitTimer=std::max(0.f,lastHitTimer-fElapsedTime);
iframe_timer=std::max(0.f,iframe_timer-fElapsedTime);
Set(Attribute::SHOOT_RING_TIMER,std::max(0.f,GetFloat(Attribute::SHOOT_RING_TIMER)-fElapsedTime));
Set(Attribute::SHOOT_RING_DELAY,std::max(0.f,GetFloat(Attribute::SHOOT_RING_DELAY)-fElapsedTime));
Set(Attribute::SHOOT_RING_COUNTER,std::max(0.f,GetFloat(Attribute::SHOOT_RING_COUNTER)-fElapsedTime));
if(size!=targetSize){
if(size>targetSize){
size=std::max(targetSize,size-Crawler::SIZE_CHANGE_SPEED*fElapsedTime);
@ -384,54 +381,30 @@ void Monster::SetSize(float newSize,bool immediate){
}
}
void Monster::Set(_ATTRIBUTE a,std::variant<VARIANTS>val){
attributes[a]=val;
//Error handling below!
//The idea is if we cannot retrieve the value, the program errors out.
switch(a.type){
case ATTRIBUTE_TYPE::FLOAT:{
GetFloat(a);
}break;
case ATTRIBUTE_TYPE::INT:{
GetInt(a);
}break;
case ATTRIBUTE_TYPE::STRING:{
GetString(a);
}break;
case ATTRIBUTE_TYPE::BOOL:{
GetBool(a);
}break;
float&Monster::GetFloat(Attribute a){
if(attributes.count(a)==0){
attributes[a]=0.f;
}
}
float Monster::GetFloat(_ATTRIBUTE a){
if(attributes.count(a)>0){
return std::get<float>(attributes[a]);
}else{
return 0;
}
}
int Monster::GetInt(_ATTRIBUTE a){
if(attributes.count(a)>0){
return std::get<int>(attributes[a]);
}else{
return 0;
int&Monster::GetInt(Attribute a){
if(attributes.count(a)==0){
attributes[a]=0;
}
return std::get<int>(attributes[a]);
}
std::string Monster::GetString(_ATTRIBUTE a){
if(attributes.count(a)>0){
return std::get<std::string>(attributes[a]);
}else{
return 0;
std::string&Monster::GetString(Attribute a){
if(attributes.count(a)==0){
attributes[a]="";
}
return std::get<std::string>(attributes[a]);
}
bool Monster::GetBool(_ATTRIBUTE a){
if(attributes.count(a)>0){
return std::get<bool>(attributes[a]);
}else{
return 0;
bool&Monster::GetBool(Attribute a){
if(attributes.count(a)==0){
attributes[a]=false;
}
return std::get<bool>(attributes[a]);
}

@ -90,7 +90,7 @@ private:
int phase=0;
bool diesNormally=true; //If set to false, the monster death is handled in a special way. Set it to true when it's time to die.
float targetSize=0;
std::map<_ATTRIBUTE,std::variant<VARIANTS>>attributes;
std::map<Attribute,std::variant<VARIANTS>>attributes;
protected:
public:
Monster()=delete;
@ -136,11 +136,10 @@ public:
float GetZ();
std::string GetStrategy();
void SetSize(float newSize,bool immediate=true);
void Set(_ATTRIBUTE a,std::variant<VARIANTS>val);
float GetFloat(_ATTRIBUTE a);
int GetInt(_ATTRIBUTE a);
std::string GetString(_ATTRIBUTE a);
bool GetBool(_ATTRIBUTE a);
float&GetFloat(Attribute a);
int&GetInt(Attribute a);
std::string&GetString(Attribute a);
bool&GetBool(Attribute a);
private:
struct STRATEGY{
static int _GetInt(Monster&m,std::string param,int strategyNumber,int index=0);

@ -1,11 +0,0 @@
#include "MonsterAttribute.h"
#define SETUP(attribute,type) _ATTRIBUTE attribute{ATTRIBUTE_TYPE::type};
SETUP(Attribute::IFRAME_TIME_UPON_HIT,FLOAT);
SETUP(Attribute::SHOOT_RING_TIMER,FLOAT);
SETUP(Attribute::SHOOT_RING_DELAY,FLOAT);
SETUP(Attribute::SHOOT_RING_COUNTER,FLOAT);
int _ATTRIBUTE::internal_id=0;
_ATTRIBUTE::_ATTRIBUTE(ATTRIBUTE_TYPE type)
:type(type),id(internal_id++){}

@ -1,29 +1,15 @@
#pragma once
#define VARIANTS float,int,std::string,bool
#include <string>
#define F(attr) GetFloat(attr)
#define I(attr) GetInt(attr)
#define S(attr) GetString(attr)
#define B(attr) GetBool(attr)
enum class ATTRIBUTE_TYPE{
FLOAT,
INT,
STRING,
BOOL,
};
struct _ATTRIBUTE{
ATTRIBUTE_TYPE type;
_ATTRIBUTE(ATTRIBUTE_TYPE type);
private:
static int internal_id;
int id;
public:
bool operator<(const _ATTRIBUTE&rhs)const{
return int(id)<int(rhs.id);
}
};
struct Attribute{
#define SETUP(attribute) static _ATTRIBUTE attribute;
SETUP(IFRAME_TIME_UPON_HIT);
SETUP(SHOOT_RING_TIMER);
SETUP(SHOOT_RING_DELAY);
SETUP(SHOOT_RING_COUNTER);
enum class Attribute{
IFRAME_TIME_UPON_HIT,
SHOOT_RING_TIMER,
SHOOT_RING_DELAY,
SHOOT_RING_COUNTER,
SHOOT_RING_RIGHT,
};

@ -7,14 +7,19 @@
INCLUDE_game
INCLUDE_BULLET_LIST
typedef Attribute A;
void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumber){
float bulletSpd=ConfigFloat("BulletSpd")/100*24;
m.F(Attribute::SHOOT_RING_TIMER)=std::max(0.f,m.F(Attribute::SHOOT_RING_TIMER)-fElapsedTime);
m.F(Attribute::SHOOT_RING_DELAY)=std::max(0.f,m.F(Attribute::SHOOT_RING_DELAY)-fElapsedTime);
switch(m.phase){
case 0:{
m.size=ConfigInt("Phase1.Size")/100;
m.diesNormally=false;
m.Set(Attribute::IFRAME_TIME_UPON_HIT,0.f);
m.F(A::IFRAME_TIME_UPON_HIT)=0;
m.iframe_timer=ConfigFloat("Phase5.IframeTimePerHit");
m.phase=1;
}break;
@ -24,12 +29,20 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
m.SetSize(ConfigFloat("Phase2.Size")/100,false);
}
if(m.GetFloat(Attribute::SHOOT_RING_TIMER)==0){
m.I(A::SHOOT_RING_COUNTER)=ConfigInt("Phase1.ShootRingCount")-1;
m.F(A::SHOOT_RING_DELAY)=ConfigFloat("Phase1.ShootRingDelay");
int bulletCount=ConfigInt("Phase1.RingBulletCount");
for(int i=0;i<bulletCount;i++){
float angle=((2*PI)/bulletCount)*i;
BULLET_LIST.emplace_back(std::make_unique<Bullet>(m.GetPos(),vf2d{cos(angle),sin(angle)}*bulletSpd,6,ConfigInt("ProjectileDamage"),m.OnUpperLevel(),false,YELLOW,vf2d{6,6}));
}
m.Set(Attribute::SHOOT_RING_TIMER,ConfigFloat("Phase1.ShootRepeatTime"));
m.F(A::SHOOT_RING_TIMER)=ConfigFloat("Phase1.ShootRepeatTime");
m.B(A::SHOOT_RING_RIGHT)=bool(rand()%2);
}
if(m.GetInt(Attribute::SHOOT_RING_COUNTER)>0){
if(m.GetFloat(Attribute::SHOOT_RING_DELAY)==0){
m.I(A::SHOOT_RING_COUNTER)--;
}
}
}break;
case 2:{
@ -47,7 +60,7 @@ void Monster::STRATEGY::SLIMEKING(Monster&m,float fElapsedTime,int strategyNumbe
case 4:{
if(m.hp<=0){
m.phase=5;
m.Set(Attribute::IFRAME_TIME_UPON_HIT,1.f);
m.F(A::IFRAME_TIME_UPON_HIT)=1;
}
}break;
}

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

Loading…
Cancel
Save