Moved all enemy reading over to purely using config files. Removed all enemy enum dependencies. Removed bugs involving loading infinite maps by accident.
This commit is contained in:
parent
13eff22485
commit
6a12a45cb2
@ -171,55 +171,6 @@ void sig::Animation::InitializeAnimations(){
|
||||
}
|
||||
ANIMATION_DATA["WIZARD_CAST_W"]=pl_wizard_cast_w;
|
||||
|
||||
//Load slime animations.
|
||||
for(int slime=0;slime<4;slime++){
|
||||
std::string colorName="";
|
||||
switch(slime){
|
||||
case 0:{
|
||||
colorName="GREEN";
|
||||
}break;
|
||||
case 1:{
|
||||
colorName="BLUE";
|
||||
}break;
|
||||
case 2:{
|
||||
colorName="RED";
|
||||
}break;
|
||||
case 3:{
|
||||
colorName="YELLOW";
|
||||
}break;
|
||||
}
|
||||
for(int state=0;state<5;state++){
|
||||
Animate2D::FrameSequence anim;
|
||||
if(state==4){//These are death animations.
|
||||
anim=Animate2D::FrameSequence(0.1f,Animate2D::Style::OneShot);
|
||||
}
|
||||
if(state==2){//These are death animations.
|
||||
anim=Animate2D::FrameSequence(0.06f);
|
||||
}
|
||||
for (int frame=0;frame<10;frame++){
|
||||
anim.AddFrame({&game->GFX_Slime_Sheet,{vi2d{frame,state+5*slime}*24,{24,24}}});
|
||||
}
|
||||
std::string stateName="";
|
||||
switch(state){
|
||||
case 0:{
|
||||
stateName="IDLE";
|
||||
}break;
|
||||
case 1:{
|
||||
stateName="ROLL";
|
||||
}break;
|
||||
case 2:{
|
||||
stateName="JUMP";
|
||||
}break;
|
||||
case 3:{
|
||||
stateName="SPIT";
|
||||
}break;
|
||||
case 4:{
|
||||
stateName="DIE";
|
||||
}break;
|
||||
}
|
||||
ANIMATION_DATA[colorName+"_SLIME_"+stateName]=anim;
|
||||
}
|
||||
}
|
||||
CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Back,5,{64,64},"GROUND_SLAM_ATTACK_BACK",{0.02,Animate2D::Style::OneShot});
|
||||
CreateHorizontalAnimationSequence(game->GFX_Effect_GroundSlam_Front,5,{64,64},"GROUND_SLAM_ATTACK_FRONT",{0.02,Animate2D::Style::OneShot});
|
||||
CreateHorizontalAnimationSequence(game->GFX_Battlecry_Effect,5,{84,84},"BATTLECRY_EFFECT",{0.02,Animate2D::Style::OneShot});
|
||||
|
@ -94,7 +94,6 @@ bool Crawler::OnUserCreate(){
|
||||
|
||||
//Graphics
|
||||
LOADIMG(GFX_Warrior_Sheet)
|
||||
LOADIMG(GFX_Slime_Sheet)
|
||||
LOADIMG(GFX_Circle)
|
||||
LOADIMG(GFX_Effect_GroundSlam_Back)
|
||||
LOADIMG(GFX_Effect_GroundSlam_Front)
|
||||
@ -904,14 +903,12 @@ void Crawler::LoadLevel(MapName map){
|
||||
|
||||
for(auto key:MAP_DATA[map].SpawnerData){
|
||||
SpawnerTag&spawnData=MAP_DATA[map].SpawnerData[key.first];
|
||||
std::vector<std::pair<MonsterName,vf2d>>monster_list;
|
||||
std::vector<std::pair<int,vf2d>>monster_list;
|
||||
|
||||
vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2;
|
||||
for(XMLTag&monster:spawnData.monsters){
|
||||
int monsterTypeID=monster.GetInteger("value")-1;
|
||||
if(monsterTypeID>=0&&monsterTypeID<MonsterName::END){
|
||||
monster_list.push_back({MonsterName(monsterTypeID),{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}});
|
||||
}
|
||||
monster_list.push_back({monsterTypeID,{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}});
|
||||
}
|
||||
SPAWNER_LIST.push_back(MonsterSpawner{{spawnData.ObjectData.GetFloat("x"),spawnData.ObjectData.GetFloat("y")},spawnerRadius*2,monster_list,spawnData.upperLevel});
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class Crawler : public olc::PixelGameEngine
|
||||
friend class sig::Animation;
|
||||
Camera2D camera;
|
||||
std::unique_ptr<Player>player;
|
||||
Renderable GFX_Warrior_Sheet,GFX_Slime_Sheet,
|
||||
Renderable GFX_Warrior_Sheet,
|
||||
GFX_Effect_GroundSlam_Back,GFX_Effect_GroundSlam_Front,
|
||||
GFX_Heart,GFX_BLOCK_BUBBLE,GFX_Ranger_Sheet,GFX_Wizard_Sheet,
|
||||
GFX_Battlecry_Effect,GFX_Mana,GFX_SonicSlash,GFX_EnergyParticle,
|
||||
|
@ -305,6 +305,7 @@
|
||||
<ClCompile Include="LightningBoltEmitter.cpp" />
|
||||
<ClCompile Include="Map.cpp" />
|
||||
<ClCompile Include="Meteor.cpp" />
|
||||
<ClCompile Include="RunTowards.cpp" />
|
||||
<ClCompile Include="Pathfinding.cpp" />
|
||||
<ClCompile Include="pixelGameEngine.cpp" />
|
||||
<ClCompile Include="Player.cpp" />
|
||||
@ -312,8 +313,11 @@
|
||||
<ClCompile Include="MonsterData.cpp" />
|
||||
<ClCompile Include="PulsatingFire.cpp" />
|
||||
<ClCompile Include="Ranger.cpp" />
|
||||
<ClCompile Include="RUN_STRATEGY.cpp" />
|
||||
<ClCompile Include="ShootAfar.cpp" />
|
||||
<ClCompile Include="Thief.cpp" />
|
||||
<ClCompile Include="Trapper.cpp" />
|
||||
<ClCompile Include="Turret.cpp" />
|
||||
<ClCompile Include="Warrior.cpp" />
|
||||
<ClCompile Include="utils.cpp" />
|
||||
<ClCompile Include="Witch.cpp" />
|
||||
|
@ -37,6 +37,9 @@
|
||||
<Filter Include="Configurations\Classes">
|
||||
<UniqueIdentifier>{fd547111-0670-4be5-85cf-28fbd92c765f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Monster Strategies">
|
||||
<UniqueIdentifier>{3d2f7a3f-5781-45ab-a66d-c6d57d9de13c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="olcPixelGameEngine.h">
|
||||
@ -215,6 +218,18 @@
|
||||
<ClCompile Include="ChargedArrow.cpp">
|
||||
<Filter>Source Files\Bullet Types</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RunTowards.cpp">
|
||||
<Filter>Source Files\Monster Strategies</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ShootAfar.cpp">
|
||||
<Filter>Source Files\Monster Strategies</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Turret.cpp">
|
||||
<Filter>Source Files\Monster Strategies</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RUN_STRATEGY.cpp">
|
||||
<Filter>Source Files\Monster Strategies</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
|
@ -4,12 +4,12 @@
|
||||
#define INCLUDE_SPAWNER_LIST extern std::vector<MonsterSpawner>SPAWNER_LIST;
|
||||
#define INCLUDE_DAMAGENUMBER_LIST extern std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
|
||||
#define INCLUDE_game extern Crawler*game;
|
||||
#define INCLUDE_MONSTER_DATA extern std::map<MonsterName,MonsterData>MONSTER_DATA;
|
||||
#define INCLUDE_MONSTER_DATA extern std::map<int,MonsterData>MONSTER_DATA;
|
||||
#define INCLUDE_BULLET_LIST extern std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
|
||||
#define INCLUDE_PARTICLE_LIST extern std::vector<Particle>PARTICLE_LIST;
|
||||
#define INCLUDE_EMITTER_LIST extern std::vector<std::unique_ptr<Emitter>>EMITTER_LIST;
|
||||
#define INCLUDE_DATA extern utils::datafile DATA;
|
||||
#define INCLUDE_STRATEGY_DATA extern safemap<std::string,MonsterStrategy>STRATEGY_DATA;
|
||||
#define INCLUDE_STRATEGY_DATA extern safemap<std::string,int>STRATEGY_DATA;
|
||||
|
||||
#define ACCESS_PLAYER Player*p=game->GetPlayer();
|
||||
|
||||
|
@ -15,10 +15,11 @@ INCLUDE_BULLET_LIST
|
||||
INCLUDE_DATA
|
||||
INCLUDE_STRATEGY_DATA
|
||||
|
||||
safemap<std::string,MonsterStrategy>STRATEGY_DATA;
|
||||
safemap<std::string,int>STRATEGY_DATA;
|
||||
std::map<int,Renderable*>MonsterData::imgs;
|
||||
|
||||
Monster::Monster(vf2d pos,MonsterData data,bool upperLevel):
|
||||
pos(pos),hp(data.GetHealth()),maxhp(data.GetHealth()),atk(data.GetAttack()),moveSpd(data.GetMoveSpdMult()),size(data.GetSizeMult()),strategy(data.GetAIStrategy()),type(data.GetType()),upperLevel(upperLevel){
|
||||
pos(pos),hp(data.GetHealth()),maxhp(data.GetHealth()),atk(data.GetAttack()),moveSpd(data.GetMoveSpdMult()),size(data.GetSizeMult()),strategy(data.GetAIStrategy()),id(data.GetID()),upperLevel(upperLevel){
|
||||
bool firstAnimation=true;
|
||||
for(std::string&anim:data.GetAnimations()){
|
||||
animation.AddState(anim,ANIMATION_DATA[anim]);
|
||||
@ -59,10 +60,13 @@ void Monster::UpdateAnimation(std::string state){
|
||||
animation.ChangeState(internal_animState,state);
|
||||
}
|
||||
void Monster::PerformJumpAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[type].GetJumpAnimation());
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[id].GetJumpAnimation());
|
||||
}
|
||||
void Monster::PerformShootAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[type].GetShootAnimation());
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[id].GetShootAnimation());
|
||||
}
|
||||
void Monster::PerformIdleAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[id].GetIdleAnimation());
|
||||
}
|
||||
bool Monster::SetX(float x){
|
||||
vf2d newPos={x,pos.y};
|
||||
@ -138,124 +142,7 @@ bool Monster::Update(float fElapsedTime){
|
||||
facingDirection=LEFT;
|
||||
}
|
||||
}
|
||||
switch(strategy){
|
||||
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);
|
||||
SetState(MOVE_TOWARDS);
|
||||
hasHitPlayer=false;
|
||||
}
|
||||
switch(state){
|
||||
case MOVE_TOWARDS:{
|
||||
if(geom2d::line(pos,target).length()>100*fElapsedTime*GetMoveSpdMult()){
|
||||
vf2d newPos=pos+geom2d::line(pos,target).vector().norm()*100*fElapsedTime*GetMoveSpdMult();
|
||||
if(!SetX(newPos.x)||!SetY(newPos.y)){
|
||||
StartPathfinding(4);
|
||||
}
|
||||
PerformJumpAnimation();
|
||||
} else {
|
||||
SetState(NORMAL);//Revert state once we've finished moving towards target.
|
||||
UpdateAnimation(MONSTER_DATA[type].GetAnimations()[0]);
|
||||
}
|
||||
}break;
|
||||
case PATH_AROUND:{
|
||||
PathAroundBehavior(fElapsedTime);
|
||||
}break;
|
||||
default:{
|
||||
}
|
||||
}
|
||||
}break;
|
||||
case SHOOT_AFAR:{
|
||||
targetAcquireTimer=std::max(0.f,targetAcquireTimer-fElapsedTime);
|
||||
attackCooldownTimer=std::max(0.f,attackCooldownTimer-fElapsedTime);
|
||||
if(queueShotTimer>0){
|
||||
queueShotTimer-=fElapsedTime;
|
||||
if(queueShotTimer<0){
|
||||
queueShotTimer=0;
|
||||
{
|
||||
BULLET_LIST.push_back(std::make_unique<Bullet>(Bullet(pos + vf2d{ 0,-4 }, geom2d::line(pos + vf2d{ 0,-4 }, game->GetPlayer()->GetPos()).vector().norm() * 24 * 3.f, 2, GetAttack(),upperLevel,false, { 75 / 2,162 / 2,225 / 2 })));
|
||||
}
|
||||
}
|
||||
}
|
||||
geom2d::line line(pos,game->GetPlayer()->GetPos());
|
||||
if(targetAcquireTimer==0&&queueShotTimer==0){
|
||||
targetAcquireTimer=1;
|
||||
if(line.length()<24*6){
|
||||
target=line.upoint(-1.2);
|
||||
if(canMove){
|
||||
SetState(MOVE_AWAY);
|
||||
} else {
|
||||
SetState(NORMAL);
|
||||
}
|
||||
} else
|
||||
if(line.length()>24*7){
|
||||
target=line.upoint(1.2);
|
||||
SetState(MOVE_TOWARDS);
|
||||
} else {
|
||||
SetState(NORMAL);
|
||||
}
|
||||
}
|
||||
canMove=true;
|
||||
geom2d::line moveTowardsLine=geom2d::line(pos,target);
|
||||
bool pathfindingDecision=false;
|
||||
switch(state){
|
||||
case MOVE_TOWARDS:{
|
||||
if(moveTowardsLine.length()>1){
|
||||
vf2d newPos=pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult();
|
||||
bool movedX=SetX(newPos.x);
|
||||
bool movedY=SetY(newPos.y);
|
||||
pathfindingDecision=movedX|movedY;
|
||||
canMove=movedX&&movedY;
|
||||
}
|
||||
if(!pathfindingDecision){
|
||||
StartPathfinding(2.5);
|
||||
}else
|
||||
if(line.length()<=24*7){
|
||||
SetState(NORMAL);
|
||||
}
|
||||
if(moveTowardsLine.vector().x>0){
|
||||
facingDirection=RIGHT;
|
||||
} else {
|
||||
facingDirection=LEFT;
|
||||
}
|
||||
PerformJumpAnimation();
|
||||
}break;
|
||||
case MOVE_AWAY:{
|
||||
if(moveTowardsLine.length()>1){
|
||||
vf2d newPos=pos+moveTowardsLine.vector().norm()*100*fElapsedTime*GetMoveSpdMult();
|
||||
bool movedX=SetX(newPos.x);
|
||||
bool movedY=SetY(newPos.y);
|
||||
pathfindingDecision=movedX|movedY;
|
||||
canMove=movedX&&movedY;
|
||||
}
|
||||
if(!pathfindingDecision){
|
||||
StartPathfinding(2.5);
|
||||
}else
|
||||
if(line.length()>=24*6){
|
||||
SetState(NORMAL);
|
||||
}
|
||||
if(moveTowardsLine.vector().x>0){
|
||||
facingDirection=RIGHT;
|
||||
} else {
|
||||
facingDirection=LEFT;
|
||||
}
|
||||
PerformJumpAnimation();
|
||||
}break;
|
||||
case PATH_AROUND:{
|
||||
PathAroundBehavior(fElapsedTime);
|
||||
}break;
|
||||
default:{
|
||||
if(attackCooldownTimer==0){
|
||||
attackCooldownTimer=1;
|
||||
queueShotTimer=0.7;
|
||||
PerformShootAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
Monster::STRATEGY::RUN_STRATEGY(*this,fElapsedTime);
|
||||
if(vel.x>0){
|
||||
vel.x=std::max(0.f,vel.x-friction*fElapsedTime);
|
||||
} else {
|
||||
@ -292,9 +179,9 @@ void Monster::Draw(){
|
||||
}
|
||||
}
|
||||
void Monster::Collision(Player*p){
|
||||
if(MONSTER_DATA[type].GetCollisionDmg()>0&&!hasHitPlayer){
|
||||
if(MONSTER_DATA[id].GetCollisionDmg()>0&&!hasHitPlayer){
|
||||
hasHitPlayer=true;
|
||||
p->Hurt(MONSTER_DATA[type].GetCollisionDmg(),OnUpperLevel());
|
||||
p->Hurt(MONSTER_DATA[id].GetCollisionDmg(),OnUpperLevel());
|
||||
}
|
||||
Collision();
|
||||
}
|
||||
@ -302,7 +189,7 @@ void Monster::Collision(Monster&m){
|
||||
Collision();
|
||||
}
|
||||
void Monster::Collision(){
|
||||
if(strategy==RUN_TOWARDS&&GetState()==MOVE_TOWARDS){
|
||||
if(strategy==0&&GetState()==MOVE_TOWARDS){//The run towards strategy causes state to return to normal upon a collision.
|
||||
SetState(NORMAL);
|
||||
}
|
||||
}
|
||||
@ -331,7 +218,7 @@ void Monster::Moved(){
|
||||
}
|
||||
}
|
||||
std::string Monster::GetDeathAnimationName(){
|
||||
return MONSTER_DATA[type].GetDeathAnimation();
|
||||
return MONSTER_DATA[id].GetDeathAnimation();
|
||||
}
|
||||
bool Monster::Hurt(int damage,bool onUpperLevel){
|
||||
if(hp<=0||onUpperLevel!=OnUpperLevel()) return false;
|
||||
@ -363,7 +250,7 @@ vf2d&Monster::GetTargetPos(){
|
||||
}
|
||||
|
||||
MonsterSpawner::MonsterSpawner(){}
|
||||
MonsterSpawner::MonsterSpawner(vf2d pos,vf2d range,std::vector<std::pair<MonsterName,vf2d>>monsters,bool upperLevel):
|
||||
MonsterSpawner::MonsterSpawner(vf2d pos,vf2d range,std::vector<std::pair<int,vf2d>>monsters,bool upperLevel):
|
||||
pos(pos),range(range),monsters(monsters),upperLevel(upperLevel){
|
||||
}
|
||||
bool MonsterSpawner::SpawnTriggered(){
|
||||
@ -378,7 +265,7 @@ vf2d MonsterSpawner::GetPos(){
|
||||
void MonsterSpawner::SetTriggered(bool trigger,bool spawnMonsters){
|
||||
triggered=trigger;
|
||||
if(spawnMonsters){
|
||||
for(std::pair<MonsterName,vf2d>&monsterInfo:monsters){
|
||||
for(std::pair<int,vf2d>&monsterInfo:monsters){
|
||||
MONSTER_LIST.push_back(Monster(pos+monsterInfo.second,MONSTER_DATA[monsterInfo.first],DoesUpperLevelSpawning()));
|
||||
}
|
||||
}
|
||||
@ -448,7 +335,7 @@ void Monster::SetState(State newState){
|
||||
void Monster::InitializeStrategies(){
|
||||
int readCounter=0;
|
||||
while(DATA["MonsterStrategy"].HasProperty(std::to_string(readCounter))){
|
||||
STRATEGY_DATA[DATA["MonsterStrategy"][std::to_string(readCounter)]["Name"].GetString()]=MonsterStrategy(readCounter);
|
||||
STRATEGY_DATA[DATA["MonsterStrategy"][std::to_string(readCounter)]["Name"].GetString()]=readCounter;
|
||||
readCounter++;
|
||||
}
|
||||
STRATEGY_DATA.SetInitialized();
|
||||
|
@ -8,52 +8,38 @@
|
||||
|
||||
struct Player;
|
||||
|
||||
enum MonsterStrategy{
|
||||
/// <summary>
|
||||
/// NOTE: When adding a new strategy, update MonsterStrategies.txt!!
|
||||
/// </summary>
|
||||
RUN_TOWARDS,
|
||||
SHOOT_AFAR,
|
||||
TURRET
|
||||
};
|
||||
|
||||
enum MonsterName{
|
||||
SLIME_GREEN,
|
||||
SLIME_BLUE,
|
||||
SLIME_RED,
|
||||
SLIME_YELLOW,
|
||||
FLOWER_TURRET,
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*//*/END,//Used for detecting the end of the list, DO NOT USE OR TOUCH. Add all monsters above this//*//*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
enum MonsterAnimation{
|
||||
IDLE,
|
||||
JUMP,
|
||||
SHOOT,
|
||||
DEATH
|
||||
};
|
||||
|
||||
struct MonsterData{
|
||||
private:
|
||||
int id;
|
||||
std::string name;
|
||||
int hp;
|
||||
int atk;
|
||||
float moveSpd;//1.0=100%
|
||||
float size;
|
||||
std::vector<std::string> animations;
|
||||
MonsterStrategy strategy;
|
||||
MonsterName type;
|
||||
int strategy;
|
||||
int collisionDmg;
|
||||
std::string jumpAnimation="WARRIOR_IDLE_S";
|
||||
std::string shootAnimation="WARRIOR_IDLE_S";
|
||||
std::string deathAnimation="WARRIOR_IDLE_S";
|
||||
public:
|
||||
MonsterData();
|
||||
//When specifying animations, the first one will become the default animation. The last becomes the death animation.
|
||||
MonsterData(MonsterName type,int hp,int atk,std::vector<std::string>animations,std::string jumpAnimation,std::string shootAnimation,std::string deathAnimation,float moveSpd=1.0f,float size=1.0f,MonsterStrategy strategy=RUN_TOWARDS,int collisionDmg=0);
|
||||
MonsterData(int id,std::string name,int hp,int atk,std::vector<std::string>animations,float moveSpd=1.0f,float size=1.0f,int strategy=0,int collisionDmg=0);
|
||||
int GetHealth();
|
||||
int GetAttack();
|
||||
float GetMoveSpdMult();
|
||||
float GetSizeMult();
|
||||
MonsterName GetType();
|
||||
MonsterStrategy GetAIStrategy();
|
||||
int GetAIStrategy();
|
||||
int GetCollisionDmg();
|
||||
int GetID();
|
||||
std::string GetIdleAnimation();
|
||||
std::string GetJumpAnimation();
|
||||
std::string GetShootAnimation();
|
||||
std::string GetDeathAnimation();
|
||||
@ -61,10 +47,13 @@ struct MonsterData{
|
||||
return animations;
|
||||
}
|
||||
static void InitializeMonsterData();
|
||||
static std::map<int,Renderable*>imgs;
|
||||
};
|
||||
|
||||
struct Monster{
|
||||
friend struct STRATEGY;
|
||||
private:
|
||||
int id=0;
|
||||
vf2d pos;
|
||||
vf2d vel={0,0};
|
||||
float friction=400;
|
||||
@ -77,13 +66,12 @@ struct Monster{
|
||||
float attackCooldownTimer=0;
|
||||
float queueShotTimer=0;
|
||||
Key facingDirection;
|
||||
MonsterStrategy strategy;
|
||||
int strategy;
|
||||
State state=State::NORMAL;
|
||||
Animate2D::Animation<std::string>animation;
|
||||
Animate2D::AnimationState internal_animState;
|
||||
float randomFrameOffset=0.f;
|
||||
float deathTimer=0.f;
|
||||
MonsterName type;
|
||||
std::vector<Buff>buffList;
|
||||
std::string GetDeathAnimationName();
|
||||
bool hasHitPlayer=false;
|
||||
@ -125,6 +113,7 @@ public:
|
||||
bool SetY(float y);
|
||||
void PerformJumpAnimation();
|
||||
void PerformShootAnimation();
|
||||
void PerformIdleAnimation();
|
||||
bool OnUpperLevel();
|
||||
void Moved();
|
||||
void StartPathfinding(float pathingTime);
|
||||
@ -134,19 +123,27 @@ public:
|
||||
State GetState();
|
||||
void SetState(State newState);
|
||||
static void InitializeStrategies();
|
||||
private:
|
||||
static struct STRATEGY{
|
||||
static void RUN_STRATEGY(Monster&m,float fElapsedTime);
|
||||
|
||||
static void RUN_TOWARDS(Monster&m,float fElapsedTime);
|
||||
static void SHOOT_AFAR(Monster&m,float fElapsedTime);
|
||||
static void TURRET(Monster&m,float fElapsedTime);
|
||||
};
|
||||
};
|
||||
|
||||
struct MonsterSpawner{
|
||||
private:
|
||||
vf2d pos;
|
||||
vf2d range;
|
||||
std::vector<std::pair<MonsterName,vf2d>>monsters;
|
||||
std::vector<std::pair<int,vf2d>>monsters;
|
||||
bool triggered=false;
|
||||
bool upperLevel=false;
|
||||
public:
|
||||
MonsterSpawner();
|
||||
//For the monster list, the second pair item is the position relative to the spawner to spawn the monster.
|
||||
MonsterSpawner(vf2d pos,vf2d range,std::vector<std::pair<MonsterName,vf2d>>MONSTER_LIST,bool upperLevel=false);
|
||||
MonsterSpawner(vf2d pos,vf2d range,std::vector<std::pair<int,vf2d>>MONSTER_LIST,bool upperLevel=false);
|
||||
bool SpawnTriggered();
|
||||
vf2d GetRange();
|
||||
vf2d GetPos();
|
||||
|
@ -7,47 +7,98 @@
|
||||
|
||||
INCLUDE_DATA
|
||||
INCLUDE_STRATEGY_DATA
|
||||
INCLUDE_ANIMATION_DATA
|
||||
|
||||
std::map<MonsterName,MonsterData>MONSTER_DATA;
|
||||
std::map<int,MonsterData>MONSTER_DATA;
|
||||
|
||||
MonsterData::MonsterData(){}
|
||||
MonsterData::MonsterData(MonsterName type,int hp,int atk,std::vector<std::string>animations,std::string jumpAnimation,std::string shootAnimation,std::string deathAnimation
|
||||
,float moveSpd,float size,MonsterStrategy strategy,int collisionDmg):
|
||||
type(type),hp(hp),atk(atk),moveSpd(moveSpd),size(size),strategy(strategy),animations(animations),collisionDmg(collisionDmg)
|
||||
,jumpAnimation(jumpAnimation),shootAnimation(shootAnimation),deathAnimation(deathAnimation){
|
||||
}
|
||||
MonsterData::MonsterData(int id,std::string name,int hp,int atk,std::vector<std::string>animations,float moveSpd,float size,int strategy,int collisionDmg):
|
||||
id(id),name(name),hp(hp),atk(atk),moveSpd(moveSpd),size(size),strategy(strategy),animations(animations),collisionDmg(collisionDmg){}
|
||||
|
||||
void MonsterData::InitializeMonsterData(){
|
||||
for(int i=0;i<MonsterName::END;i++){
|
||||
std::string ID=DATA["Monsters"][std::to_string(i)]["DisplayName"].GetString(1);
|
||||
int id=0;
|
||||
while(DATA["Monsters"].HasProperty(std::to_string(id))){
|
||||
std::string MonsterName=DATA["Monsters"][std::to_string(id)]["DisplayName"].GetString();
|
||||
std::vector<std::string>animations{
|
||||
ID+"_JUMP",
|
||||
ID+"_SPIT",
|
||||
ID+"_DIE",
|
||||
ID+"_IDLE",
|
||||
MonsterName+"_IDLE",
|
||||
MonsterName+"_JUMP",
|
||||
MonsterName+"_SPIT",
|
||||
MonsterName+"_DIE",
|
||||
};
|
||||
|
||||
MonsterData::imgs[id]=new Renderable();
|
||||
MonsterData::imgs[id]->Load("assets/monsters/"+MonsterName+".png");
|
||||
|
||||
for(int i=0;i<animations.size();i++){
|
||||
std::string animationConfigName="";
|
||||
std::string imgName="";
|
||||
switch(i){
|
||||
case 0:{
|
||||
animationConfigName="Idle";
|
||||
imgName="_IDLE";
|
||||
}break;
|
||||
case 1:{
|
||||
animationConfigName="Jump";
|
||||
imgName="_JUMP";
|
||||
}break;
|
||||
case 2:{
|
||||
animationConfigName="Shoot";
|
||||
imgName="_SPIT";
|
||||
}break;
|
||||
case 3:{
|
||||
animationConfigName="Death";
|
||||
imgName="_DIE";
|
||||
}break;
|
||||
}
|
||||
Animate2D::Style style=Animate2D::Style::Repeat;
|
||||
if(DATA["Monsters"][std::to_string(id)][animationConfigName+"Animation"].GetString(2)=="Repeat"){
|
||||
style=Animate2D::Style::Repeat;
|
||||
} else
|
||||
if(DATA["Monsters"][std::to_string(id)][animationConfigName+"Animation"].GetString(2)=="OneShot"){
|
||||
style=Animate2D::Style::OneShot;
|
||||
} else
|
||||
if(DATA["Monsters"][std::to_string(id)][animationConfigName+"Animation"].GetString(2)=="PingPong"){
|
||||
style=Animate2D::Style::PingPong;
|
||||
} else
|
||||
if(DATA["Monsters"][std::to_string(id)][animationConfigName+"Animation"].GetString(2)=="Reverse"){
|
||||
style=Animate2D::Style::Reverse;
|
||||
}
|
||||
|
||||
auto CreateHorizontalAnimationSequence=[&](Renderable&img,int frameCount,vf2d size,std::string state,int row,AnimationData data={}){
|
||||
Animate2D::FrameSequence anim(data.frameDuration,data.style);
|
||||
for(int i=0;i<frameCount;i++){
|
||||
anim.AddFrame({&img,{{int(i*size.x),int(row*size.y)},size}});
|
||||
}
|
||||
ANIMATION_DATA[state]=anim;
|
||||
};
|
||||
|
||||
int frameCount = DATA["Monsters"][std::to_string(id)][animationConfigName+"Animation"].GetInt(0);
|
||||
vf2d frameSize = vf2d{float(DATA["Monsters"][std::to_string(id)]["SheetFrameSize"].GetInt(0)),float(DATA["Monsters"][std::to_string(id)]["SheetFrameSize"].GetInt(1))};
|
||||
CreateHorizontalAnimationSequence(*MonsterData::imgs[id],frameCount,frameSize,MonsterName+imgName,i,AnimationData{float(DATA["Monsters"][std::to_string(id)][animationConfigName+"Animation"].GetReal(1)),style});
|
||||
}
|
||||
|
||||
//Add additional custom animations defined in the config.
|
||||
int animationCounter=0;
|
||||
while(DATA["Monsters"][std::to_string(i)].HasProperty("ANIMATION["+std::to_string(animationCounter)+"]")){
|
||||
animations.push_back(DATA["Monsters"][std::to_string(i)]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString());
|
||||
while(DATA["Monsters"][std::to_string(id)].HasProperty("ANIMATION["+std::to_string(animationCounter)+"]")){
|
||||
animations.push_back(DATA["Monsters"][std::to_string(id)]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString());
|
||||
animationCounter++;
|
||||
}
|
||||
|
||||
MonsterData monster(
|
||||
MonsterName(i),
|
||||
DATA["Monsters"][std::to_string(i)]["Health"].GetInt(),
|
||||
DATA["Monsters"][std::to_string(i)]["Attack"].GetInt(),
|
||||
id,
|
||||
MonsterName,
|
||||
DATA["Monsters"][std::to_string(id)]["Health"].GetInt(),
|
||||
DATA["Monsters"][std::to_string(id)]["Attack"].GetInt(),
|
||||
animations,
|
||||
ID+"_JUMP",
|
||||
ID+"_SPIT",
|
||||
ID+"_DIE",
|
||||
DATA["Monsters"][std::to_string(i)]["MoveSpd"].GetReal()/100,
|
||||
DATA["Monsters"][std::to_string(i)]["Size"].GetReal()/100,
|
||||
STRATEGY_DATA[DATA["Monsters"][std::to_string(i)]["Strategy"].GetString()],
|
||||
DATA["Monsters"][std::to_string(i)]["CollisionDmg"].GetInt()
|
||||
DATA["Monsters"][std::to_string(id)]["MoveSpd"].GetReal()/100,
|
||||
DATA["Monsters"][std::to_string(id)]["Size"].GetReal()/100,
|
||||
STRATEGY_DATA[DATA["Monsters"][std::to_string(id)]["Strategy"].GetString()],
|
||||
DATA["Monsters"][std::to_string(id)]["CollisionDmg"].GetInt()
|
||||
);
|
||||
|
||||
MONSTER_DATA[MonsterName(i)]=monster;
|
||||
MONSTER_DATA[id]=monster;
|
||||
|
||||
id++;
|
||||
}
|
||||
}
|
||||
int MonsterData::GetHealth(){
|
||||
@ -65,21 +116,22 @@ float MonsterData::GetSizeMult(){
|
||||
int MonsterData::GetCollisionDmg(){
|
||||
return collisionDmg;
|
||||
}
|
||||
MonsterName MonsterData::GetType(){
|
||||
return type;
|
||||
int MonsterData::GetID(){
|
||||
return id;
|
||||
}
|
||||
MonsterStrategy MonsterData::GetAIStrategy(){
|
||||
int MonsterData::GetAIStrategy(){
|
||||
return strategy;
|
||||
}
|
||||
|
||||
std::string MonsterData::GetIdleAnimation(){
|
||||
return animations[IDLE];
|
||||
}
|
||||
std::string MonsterData::GetJumpAnimation(){
|
||||
return jumpAnimation;
|
||||
return animations[JUMP];
|
||||
}
|
||||
std::string MonsterData::GetShootAnimation(){
|
||||
return shootAnimation;
|
||||
return animations[SHOOT];
|
||||
}
|
||||
|
||||
std::string MonsterData::GetDeathAnimation()
|
||||
{
|
||||
return deathAnimation;
|
||||
std::string MonsterData::GetDeathAnimation(){
|
||||
return animations[DEATH];
|
||||
}
|
||||
|
@ -169,6 +169,7 @@ void Player::Knockback(vf2d vel){
|
||||
}
|
||||
|
||||
void Player::Update(float fElapsedTime){
|
||||
|
||||
Ability&rightClickAbility=GetRightClickAbility(),
|
||||
&ability=GetAbility1(),
|
||||
&ability2=GetAbility2(),
|
||||
|
15
Crawler/RUN_STRATEGY.cpp
Normal file
15
Crawler/RUN_STRATEGY.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "Monster.h"
|
||||
|
||||
void Monster::STRATEGY::RUN_STRATEGY(Monster&m,float fElapsedTime){
|
||||
switch(m.strategy){
|
||||
case 0:{//Run Towards
|
||||
Monster::STRATEGY::RUN_TOWARDS(m,fElapsedTime);
|
||||
}break;
|
||||
case 1:{//Shoot Afar
|
||||
Monster::STRATEGY::SHOOT_AFAR(m,fElapsedTime);
|
||||
}break;
|
||||
case 2:{//Turret.
|
||||
Monster::STRATEGY::TURRET(m,fElapsedTime);
|
||||
}break;
|
||||
}
|
||||
}
|
35
Crawler/RunTowards.cpp
Normal file
35
Crawler/RunTowards.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include "Monster.h"
|
||||
#include "DEFINES.h"
|
||||
#include "Crawler.h"
|
||||
|
||||
INCLUDE_game
|
||||
INCLUDE_MONSTER_DATA
|
||||
|
||||
void Monster::STRATEGY::RUN_TOWARDS(Monster&m,float fElapsedTime){
|
||||
m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime);
|
||||
if(m.targetAcquireTimer==0){
|
||||
m.targetAcquireTimer=3;
|
||||
m.target=geom2d::line(m.pos,game->GetPlayer()->GetPos()).upoint(1.2);
|
||||
m.SetState(MOVE_TOWARDS);
|
||||
m.hasHitPlayer=false;
|
||||
}
|
||||
switch(m.state){
|
||||
case MOVE_TOWARDS:{
|
||||
if(geom2d::line(m.pos,m.target).length()>100*fElapsedTime*m.GetMoveSpdMult()){
|
||||
vf2d newPos=m.pos+geom2d::line(m.pos,m.target).vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
|
||||
if(!m.SetX(newPos.x)||!m.SetY(newPos.y)){
|
||||
m.StartPathfinding(4);
|
||||
}
|
||||
m.PerformJumpAnimation();
|
||||
} else {
|
||||
m.SetState(NORMAL);//Revert state once we've finished moving towards target.
|
||||
m.UpdateAnimation(MONSTER_DATA[m.id].GetIdleAnimation());
|
||||
}
|
||||
}break;
|
||||
case PATH_AROUND:{
|
||||
m.PathAroundBehavior(fElapsedTime);
|
||||
}break;
|
||||
default:{
|
||||
}
|
||||
}
|
||||
}
|
95
Crawler/ShootAfar.cpp
Normal file
95
Crawler/ShootAfar.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include "Monster.h"
|
||||
#include "DEFINES.h"
|
||||
#include "Crawler.h"
|
||||
|
||||
INCLUDE_BULLET_LIST
|
||||
INCLUDE_game
|
||||
|
||||
void Monster::STRATEGY::SHOOT_AFAR(Monster&m,float fElapsedTime){
|
||||
m.targetAcquireTimer=std::max(0.f,m.targetAcquireTimer-fElapsedTime);
|
||||
m.attackCooldownTimer=std::max(0.f,m.attackCooldownTimer-fElapsedTime);
|
||||
if(m.queueShotTimer>0){
|
||||
m.queueShotTimer-=fElapsedTime;
|
||||
if(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 })));
|
||||
}
|
||||
}
|
||||
}
|
||||
geom2d::line line(m.pos,game->GetPlayer()->GetPos());
|
||||
if(m.targetAcquireTimer==0&&m.queueShotTimer==0){
|
||||
m.targetAcquireTimer=1;
|
||||
if(line.length()<24*6){
|
||||
m.target=line.upoint(-1.2);
|
||||
if(m.canMove){
|
||||
m.SetState(MOVE_AWAY);
|
||||
} else {
|
||||
m.SetState(NORMAL);
|
||||
}
|
||||
} else
|
||||
if(line.length()>24*7){
|
||||
m.target=line.upoint(1.2);
|
||||
m.SetState(MOVE_TOWARDS);
|
||||
} else {
|
||||
m.SetState(NORMAL);
|
||||
}
|
||||
}
|
||||
m.canMove=true;
|
||||
geom2d::line moveTowardsLine=geom2d::line(m.pos,m.target);
|
||||
bool pathfindingDecision=false;
|
||||
switch(m.state){
|
||||
case MOVE_TOWARDS:{
|
||||
if(moveTowardsLine.length()>1){
|
||||
vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
|
||||
bool movedX=m.SetX(newPos.x);
|
||||
bool movedY=m.SetY(newPos.y);
|
||||
pathfindingDecision=movedX|movedY;
|
||||
m.canMove=movedX&&movedY;
|
||||
}
|
||||
if(!pathfindingDecision){
|
||||
m.StartPathfinding(2.5);
|
||||
}else
|
||||
if(line.length()<=24*7){
|
||||
m.SetState(NORMAL);
|
||||
}
|
||||
if(moveTowardsLine.vector().x>0){
|
||||
m.facingDirection=RIGHT;
|
||||
} else {
|
||||
m.facingDirection=LEFT;
|
||||
}
|
||||
m.PerformJumpAnimation();
|
||||
}break;
|
||||
case MOVE_AWAY:{
|
||||
if(moveTowardsLine.length()>1){
|
||||
vf2d newPos=m.pos+moveTowardsLine.vector().norm()*100*fElapsedTime*m.GetMoveSpdMult();
|
||||
bool movedX=m.SetX(newPos.x);
|
||||
bool movedY=m.SetY(newPos.y);
|
||||
pathfindingDecision=movedX|movedY;
|
||||
m.canMove=movedX&&movedY;
|
||||
}
|
||||
if(!pathfindingDecision){
|
||||
m.StartPathfinding(2.5);
|
||||
}else
|
||||
if(line.length()>=24*6){
|
||||
m.SetState(NORMAL);
|
||||
}
|
||||
if(moveTowardsLine.vector().x>0){
|
||||
m.facingDirection=RIGHT;
|
||||
} else {
|
||||
m.facingDirection=LEFT;
|
||||
}
|
||||
m.PerformJumpAnimation();
|
||||
}break;
|
||||
case PATH_AROUND:{
|
||||
m.PathAroundBehavior(fElapsedTime);
|
||||
}break;
|
||||
default:{
|
||||
if(m.attackCooldownTimer==0){
|
||||
m.attackCooldownTimer=1;
|
||||
m.queueShotTimer=0.7;
|
||||
m.PerformShootAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -61,6 +61,7 @@ class TMXParser{
|
||||
XMLTag monsterTag;
|
||||
XMLTag spawnerLinkTag;
|
||||
std::vector<XMLTag>accumulatedMonsterTags;
|
||||
bool infiniteMap=false;
|
||||
public:
|
||||
TMXParser(std::string file);
|
||||
};
|
||||
@ -209,6 +210,10 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
|
||||
XMLTag newTag=ReadNextTag();
|
||||
|
||||
if (newTag.tag=="map") {
|
||||
if(stoi(newTag.data["infinite"])==1){
|
||||
infiniteMap=true;
|
||||
return;
|
||||
}
|
||||
parsedMapInfo.MapData={stoi(newTag.data["width"]),stoi(newTag.data["height"])};
|
||||
} else
|
||||
if (newTag.tag=="tileset") {
|
||||
@ -269,7 +274,7 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
|
||||
|
||||
std::string accumulator="";
|
||||
|
||||
while (f.good()) {
|
||||
while (f.good()&&!infiniteMap) {
|
||||
std::string data;
|
||||
f>>data;
|
||||
if (data.empty()) continue;
|
||||
@ -306,10 +311,13 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
|
||||
}
|
||||
}
|
||||
|
||||
if(infiniteMap){
|
||||
std::cout<<"Infinite map detected. Parsing stopped early."<<std::endl;
|
||||
}
|
||||
|
||||
for(XMLTag&monster:accumulatedMonsterTags){
|
||||
parsedMapInfo.SpawnerData[monster.GetInteger("spawnerLink")].monsters.push_back(monster);
|
||||
}
|
||||
|
||||
std::cout<<"Parsed Map Data:\n"<<parsedMapInfo<<"\n";
|
||||
}
|
||||
#endif
|
5
Crawler/Turret.cpp
Normal file
5
Crawler/Turret.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "Monster.h"
|
||||
|
||||
void Monster::STRATEGY::TURRET(Monster&m,float fElapsedTime){
|
||||
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 976
|
||||
#define VERSION_BUILD 988
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -12,7 +12,7 @@
|
||||
# ==========================================
|
||||
# ==========================================
|
||||
#
|
||||
# Monster0
|
||||
# 0
|
||||
# {
|
||||
# Name = Green Slime
|
||||
# Health = 10
|
||||
@ -23,7 +23,7 @@
|
||||
# MoveSpd = 110
|
||||
# Size = 80
|
||||
#
|
||||
# Strategy = RUN_TOWARDS
|
||||
# Strategy = Run Towards
|
||||
# WaitTime = 5
|
||||
#
|
||||
# [....Cut for length purposes]
|
||||
@ -38,7 +38,7 @@ MonsterStrategy
|
||||
{
|
||||
0
|
||||
{
|
||||
Name = RUN_TOWARDS
|
||||
Name = Run Towards
|
||||
# How long to wait before attempting to path again.
|
||||
WaitTime = 2
|
||||
# How far the monster will travel before reassessing for a new path.
|
||||
@ -46,7 +46,7 @@ MonsterStrategy
|
||||
}
|
||||
1
|
||||
{
|
||||
Name = SHOOT_AFAR
|
||||
Name = Shoot Afar
|
||||
# How far away the monster attempts to distance itself from the player
|
||||
Range = 800
|
||||
# How often the enemy shoots.
|
||||
@ -57,8 +57,8 @@ MonsterStrategy
|
||||
}
|
||||
2
|
||||
{
|
||||
Name = TURRET
|
||||
# How far away the monster starts from shooting from
|
||||
Name = Turret
|
||||
# How far away the monster starts shooting from
|
||||
Range = 800
|
||||
# How often the enemy shoots.
|
||||
ShootingSpeed = 1
|
||||
|
@ -2,7 +2,7 @@ Monsters
|
||||
{
|
||||
0
|
||||
{
|
||||
DisplayName = Green Slime, GREEN_SLIME
|
||||
DisplayName = Green Slime
|
||||
Health = 10
|
||||
Attack = 5
|
||||
|
||||
@ -11,14 +11,23 @@ Monsters
|
||||
MoveSpd = 110
|
||||
Size = 80
|
||||
|
||||
Strategy = RUN_TOWARDS
|
||||
Strategy = Run Towards
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
IdleAnimation = 10, 0.1, Repeat
|
||||
JumpAnimation = 10, 0.06, Repeat
|
||||
ShootAnimation = 10, 0.1, OneShot
|
||||
DeathAnimation = 10, 0.1, OneShot
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||
}
|
||||
1
|
||||
{
|
||||
DisplayName = Blue Slime, BLUE_SLIME
|
||||
DisplayName = Blue Slime
|
||||
Health = 30
|
||||
Attack = 10
|
||||
|
||||
@ -27,14 +36,23 @@ Monsters
|
||||
MoveSpd = 80
|
||||
Size = 100
|
||||
|
||||
Strategy = SHOOT_AFAR
|
||||
Strategy = Shoot Afar
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
IdleAnimation = 10, 0.1, Repeat
|
||||
JumpAnimation = 10, 0.06, Repeat
|
||||
ShootAnimation = 10, 0.1, OneShot
|
||||
DeathAnimation = 10, 0.1, OneShot
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||
}
|
||||
2
|
||||
{
|
||||
DisplayName = Red Slime, RED_SLIME
|
||||
DisplayName = Red Slime
|
||||
Health = 25
|
||||
Attack = 10
|
||||
|
||||
@ -43,14 +61,23 @@ Monsters
|
||||
MoveSpd = 95
|
||||
Size = 120
|
||||
|
||||
Strategy = RUN_TOWARDS
|
||||
Strategy = Run Towards
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
IdleAnimation = 10, 0.1, Repeat
|
||||
JumpAnimation = 10, 0.06, Repeat
|
||||
ShootAnimation = 10, 0.1, OneShot
|
||||
DeathAnimation = 10, 0.1, OneShot
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||
}
|
||||
3
|
||||
{
|
||||
DisplayName = Yellow Slime, YELLOW_SLIME
|
||||
DisplayName = Yellow Slime
|
||||
Health = 175
|
||||
Attack = 10
|
||||
|
||||
@ -59,14 +86,23 @@ Monsters
|
||||
MoveSpd = 40
|
||||
Size = 160
|
||||
|
||||
Strategy = RUN_TOWARDS
|
||||
Strategy = Run Towards
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
IdleAnimation = 10, 0.1, Repeat
|
||||
JumpAnimation = 10, 0.06, Repeat
|
||||
ShootAnimation = 10, 0.1, OneShot
|
||||
DeathAnimation = 10, 0.1, OneShot
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||
}
|
||||
4
|
||||
{
|
||||
DisplayName = Flower Turret, FLOWER_TURRET
|
||||
DisplayName = Flower Turret
|
||||
Health = 40
|
||||
Attack = 10
|
||||
|
||||
@ -75,7 +111,16 @@ Monsters
|
||||
MoveSpd = 0
|
||||
Size = 100
|
||||
|
||||
Strategy = TURRET
|
||||
Strategy = Turret
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
IdleAnimation = 7, 0.1, PingPong
|
||||
JumpAnimation = 1, 0.1, OneShot
|
||||
ShootAnimation = 5, 0.1, OneShot
|
||||
DeathAnimation = 5, 0.2, OneShot
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||
|
@ -1,6 +1,6 @@
|
||||
Player
|
||||
{
|
||||
BaseHealth = 1000
|
||||
BaseHealth = 100
|
||||
BaseMana = 100
|
||||
MoveSpd = 100
|
||||
|
||||
|
@ -3,7 +3,6 @@ GFX_Prefix = assets/
|
||||
Images
|
||||
{
|
||||
GFX_Warrior_Sheet = nico-warrior.png
|
||||
GFX_Slime_Sheet = slime.png
|
||||
GFX_Circle = circle.png
|
||||
GFX_Effect_GroundSlam_Back = ground-slam-attack-back.png
|
||||
GFX_Effect_GroundSlam_Front = ground-slam-attack-front.png
|
||||
|
BIN
Crawler/assets/monsters/Blue Slime.png
Normal file
BIN
Crawler/assets/monsters/Blue Slime.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
Crawler/assets/monsters/Flower Turret.png
Normal file
BIN
Crawler/assets/monsters/Flower Turret.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
Crawler/assets/monsters/Flower Turret.xcf
Normal file
BIN
Crawler/assets/monsters/Flower Turret.xcf
Normal file
Binary file not shown.
BIN
Crawler/assets/monsters/Green Slime.png
Normal file
BIN
Crawler/assets/monsters/Green Slime.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
Crawler/assets/monsters/Red Slime.png
Normal file
BIN
Crawler/assets/monsters/Red Slime.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
BIN
Crawler/assets/monsters/Yellow Slime.png
Normal file
BIN
Crawler/assets/monsters/Yellow Slime.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
Loading…
x
Reference in New Issue
Block a user