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;
|
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_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_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});
|
CreateHorizontalAnimationSequence(game->GFX_Battlecry_Effect,5,{84,84},"BATTLECRY_EFFECT",{0.02,Animate2D::Style::OneShot});
|
||||||
|
@ -94,7 +94,6 @@ bool Crawler::OnUserCreate(){
|
|||||||
|
|
||||||
//Graphics
|
//Graphics
|
||||||
LOADIMG(GFX_Warrior_Sheet)
|
LOADIMG(GFX_Warrior_Sheet)
|
||||||
LOADIMG(GFX_Slime_Sheet)
|
|
||||||
LOADIMG(GFX_Circle)
|
LOADIMG(GFX_Circle)
|
||||||
LOADIMG(GFX_Effect_GroundSlam_Back)
|
LOADIMG(GFX_Effect_GroundSlam_Back)
|
||||||
LOADIMG(GFX_Effect_GroundSlam_Front)
|
LOADIMG(GFX_Effect_GroundSlam_Front)
|
||||||
@ -904,14 +903,12 @@ void Crawler::LoadLevel(MapName map){
|
|||||||
|
|
||||||
for(auto key:MAP_DATA[map].SpawnerData){
|
for(auto key:MAP_DATA[map].SpawnerData){
|
||||||
SpawnerTag&spawnData=MAP_DATA[map].SpawnerData[key.first];
|
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;
|
vf2d spawnerRadius=vf2d{spawnData.ObjectData.GetFloat("width"),spawnData.ObjectData.GetFloat("height")}/2;
|
||||||
for(XMLTag&monster:spawnData.monsters){
|
for(XMLTag&monster:spawnData.monsters){
|
||||||
int monsterTypeID=monster.GetInteger("value")-1;
|
int monsterTypeID=monster.GetInteger("value")-1;
|
||||||
if(monsterTypeID>=0&&monsterTypeID<MonsterName::END){
|
monster_list.push_back({monsterTypeID,{monster.GetInteger("x")-spawnData.ObjectData.GetFloat("x"),monster.GetInteger("y")-spawnData.ObjectData.GetFloat("y")}});
|
||||||
monster_list.push_back({MonsterName(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});
|
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;
|
friend class sig::Animation;
|
||||||
Camera2D camera;
|
Camera2D camera;
|
||||||
std::unique_ptr<Player>player;
|
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_Effect_GroundSlam_Back,GFX_Effect_GroundSlam_Front,
|
||||||
GFX_Heart,GFX_BLOCK_BUBBLE,GFX_Ranger_Sheet,GFX_Wizard_Sheet,
|
GFX_Heart,GFX_BLOCK_BUBBLE,GFX_Ranger_Sheet,GFX_Wizard_Sheet,
|
||||||
GFX_Battlecry_Effect,GFX_Mana,GFX_SonicSlash,GFX_EnergyParticle,
|
GFX_Battlecry_Effect,GFX_Mana,GFX_SonicSlash,GFX_EnergyParticle,
|
||||||
|
@ -305,6 +305,7 @@
|
|||||||
<ClCompile Include="LightningBoltEmitter.cpp" />
|
<ClCompile Include="LightningBoltEmitter.cpp" />
|
||||||
<ClCompile Include="Map.cpp" />
|
<ClCompile Include="Map.cpp" />
|
||||||
<ClCompile Include="Meteor.cpp" />
|
<ClCompile Include="Meteor.cpp" />
|
||||||
|
<ClCompile Include="RunTowards.cpp" />
|
||||||
<ClCompile Include="Pathfinding.cpp" />
|
<ClCompile Include="Pathfinding.cpp" />
|
||||||
<ClCompile Include="pixelGameEngine.cpp" />
|
<ClCompile Include="pixelGameEngine.cpp" />
|
||||||
<ClCompile Include="Player.cpp" />
|
<ClCompile Include="Player.cpp" />
|
||||||
@ -312,8 +313,11 @@
|
|||||||
<ClCompile Include="MonsterData.cpp" />
|
<ClCompile Include="MonsterData.cpp" />
|
||||||
<ClCompile Include="PulsatingFire.cpp" />
|
<ClCompile Include="PulsatingFire.cpp" />
|
||||||
<ClCompile Include="Ranger.cpp" />
|
<ClCompile Include="Ranger.cpp" />
|
||||||
|
<ClCompile Include="RUN_STRATEGY.cpp" />
|
||||||
|
<ClCompile Include="ShootAfar.cpp" />
|
||||||
<ClCompile Include="Thief.cpp" />
|
<ClCompile Include="Thief.cpp" />
|
||||||
<ClCompile Include="Trapper.cpp" />
|
<ClCompile Include="Trapper.cpp" />
|
||||||
|
<ClCompile Include="Turret.cpp" />
|
||||||
<ClCompile Include="Warrior.cpp" />
|
<ClCompile Include="Warrior.cpp" />
|
||||||
<ClCompile Include="utils.cpp" />
|
<ClCompile Include="utils.cpp" />
|
||||||
<ClCompile Include="Witch.cpp" />
|
<ClCompile Include="Witch.cpp" />
|
||||||
|
@ -37,6 +37,9 @@
|
|||||||
<Filter Include="Configurations\Classes">
|
<Filter Include="Configurations\Classes">
|
||||||
<UniqueIdentifier>{fd547111-0670-4be5-85cf-28fbd92c765f}</UniqueIdentifier>
|
<UniqueIdentifier>{fd547111-0670-4be5-85cf-28fbd92c765f}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Source Files\Monster Strategies">
|
||||||
|
<UniqueIdentifier>{3d2f7a3f-5781-45ab-a66d-c6d57d9de13c}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="olcPixelGameEngine.h">
|
<ClInclude Include="olcPixelGameEngine.h">
|
||||||
@ -215,6 +218,18 @@
|
|||||||
<ClCompile Include="ChargedArrow.cpp">
|
<ClCompile Include="ChargedArrow.cpp">
|
||||||
<Filter>Source Files\Bullet Types</Filter>
|
<Filter>Source Files\Bullet Types</Filter>
|
||||||
</ClCompile>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="cpp.hint" />
|
<None Include="cpp.hint" />
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
#define INCLUDE_SPAWNER_LIST extern std::vector<MonsterSpawner>SPAWNER_LIST;
|
#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_DAMAGENUMBER_LIST extern std::vector<std::shared_ptr<DamageNumber>>DAMAGENUMBER_LIST;
|
||||||
#define INCLUDE_game extern Crawler*game;
|
#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_BULLET_LIST extern std::vector<std::unique_ptr<Bullet>>BULLET_LIST;
|
||||||
#define INCLUDE_PARTICLE_LIST extern std::vector<Particle>PARTICLE_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_EMITTER_LIST extern std::vector<std::unique_ptr<Emitter>>EMITTER_LIST;
|
||||||
#define INCLUDE_DATA extern utils::datafile DATA;
|
#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();
|
#define ACCESS_PLAYER Player*p=game->GetPlayer();
|
||||||
|
|
||||||
|
@ -15,10 +15,11 @@ INCLUDE_BULLET_LIST
|
|||||||
INCLUDE_DATA
|
INCLUDE_DATA
|
||||||
INCLUDE_STRATEGY_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):
|
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;
|
bool firstAnimation=true;
|
||||||
for(std::string&anim:data.GetAnimations()){
|
for(std::string&anim:data.GetAnimations()){
|
||||||
animation.AddState(anim,ANIMATION_DATA[anim]);
|
animation.AddState(anim,ANIMATION_DATA[anim]);
|
||||||
@ -59,10 +60,13 @@ void Monster::UpdateAnimation(std::string state){
|
|||||||
animation.ChangeState(internal_animState,state);
|
animation.ChangeState(internal_animState,state);
|
||||||
}
|
}
|
||||||
void Monster::PerformJumpAnimation(){
|
void Monster::PerformJumpAnimation(){
|
||||||
animation.ChangeState(internal_animState,MONSTER_DATA[type].GetJumpAnimation());
|
animation.ChangeState(internal_animState,MONSTER_DATA[id].GetJumpAnimation());
|
||||||
}
|
}
|
||||||
void Monster::PerformShootAnimation(){
|
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){
|
bool Monster::SetX(float x){
|
||||||
vf2d newPos={x,pos.y};
|
vf2d newPos={x,pos.y};
|
||||||
@ -138,124 +142,7 @@ bool Monster::Update(float fElapsedTime){
|
|||||||
facingDirection=LEFT;
|
facingDirection=LEFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch(strategy){
|
Monster::STRATEGY::RUN_STRATEGY(*this,fElapsedTime);
|
||||||
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;
|
|
||||||
}
|
|
||||||
if(vel.x>0){
|
if(vel.x>0){
|
||||||
vel.x=std::max(0.f,vel.x-friction*fElapsedTime);
|
vel.x=std::max(0.f,vel.x-friction*fElapsedTime);
|
||||||
} else {
|
} else {
|
||||||
@ -292,9 +179,9 @@ void Monster::Draw(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Monster::Collision(Player*p){
|
void Monster::Collision(Player*p){
|
||||||
if(MONSTER_DATA[type].GetCollisionDmg()>0&&!hasHitPlayer){
|
if(MONSTER_DATA[id].GetCollisionDmg()>0&&!hasHitPlayer){
|
||||||
hasHitPlayer=true;
|
hasHitPlayer=true;
|
||||||
p->Hurt(MONSTER_DATA[type].GetCollisionDmg(),OnUpperLevel());
|
p->Hurt(MONSTER_DATA[id].GetCollisionDmg(),OnUpperLevel());
|
||||||
}
|
}
|
||||||
Collision();
|
Collision();
|
||||||
}
|
}
|
||||||
@ -302,7 +189,7 @@ void Monster::Collision(Monster&m){
|
|||||||
Collision();
|
Collision();
|
||||||
}
|
}
|
||||||
void Monster::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);
|
SetState(NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,7 +218,7 @@ void Monster::Moved(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::string Monster::GetDeathAnimationName(){
|
std::string Monster::GetDeathAnimationName(){
|
||||||
return MONSTER_DATA[type].GetDeathAnimation();
|
return MONSTER_DATA[id].GetDeathAnimation();
|
||||||
}
|
}
|
||||||
bool Monster::Hurt(int damage,bool onUpperLevel){
|
bool Monster::Hurt(int damage,bool onUpperLevel){
|
||||||
if(hp<=0||onUpperLevel!=OnUpperLevel()) return false;
|
if(hp<=0||onUpperLevel!=OnUpperLevel()) return false;
|
||||||
@ -363,7 +250,7 @@ vf2d&Monster::GetTargetPos(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
MonsterSpawner::MonsterSpawner(){}
|
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){
|
pos(pos),range(range),monsters(monsters),upperLevel(upperLevel){
|
||||||
}
|
}
|
||||||
bool MonsterSpawner::SpawnTriggered(){
|
bool MonsterSpawner::SpawnTriggered(){
|
||||||
@ -378,7 +265,7 @@ vf2d MonsterSpawner::GetPos(){
|
|||||||
void MonsterSpawner::SetTriggered(bool trigger,bool spawnMonsters){
|
void MonsterSpawner::SetTriggered(bool trigger,bool spawnMonsters){
|
||||||
triggered=trigger;
|
triggered=trigger;
|
||||||
if(spawnMonsters){
|
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()));
|
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(){
|
void Monster::InitializeStrategies(){
|
||||||
int readCounter=0;
|
int readCounter=0;
|
||||||
while(DATA["MonsterStrategy"].HasProperty(std::to_string(readCounter))){
|
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++;
|
readCounter++;
|
||||||
}
|
}
|
||||||
STRATEGY_DATA.SetInitialized();
|
STRATEGY_DATA.SetInitialized();
|
||||||
|
@ -8,52 +8,38 @@
|
|||||||
|
|
||||||
struct Player;
|
struct Player;
|
||||||
|
|
||||||
enum MonsterStrategy{
|
enum MonsterAnimation{
|
||||||
/// <summary>
|
IDLE,
|
||||||
/// NOTE: When adding a new strategy, update MonsterStrategies.txt!!
|
JUMP,
|
||||||
/// </summary>
|
SHOOT,
|
||||||
RUN_TOWARDS,
|
DEATH
|
||||||
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//*//*/
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MonsterData{
|
struct MonsterData{
|
||||||
private:
|
private:
|
||||||
|
int id;
|
||||||
|
std::string name;
|
||||||
int hp;
|
int hp;
|
||||||
int atk;
|
int atk;
|
||||||
float moveSpd;//1.0=100%
|
float moveSpd;//1.0=100%
|
||||||
float size;
|
float size;
|
||||||
std::vector<std::string> animations;
|
std::vector<std::string> animations;
|
||||||
MonsterStrategy strategy;
|
int strategy;
|
||||||
MonsterName type;
|
|
||||||
int collisionDmg;
|
int collisionDmg;
|
||||||
std::string jumpAnimation="WARRIOR_IDLE_S";
|
std::string jumpAnimation="WARRIOR_IDLE_S";
|
||||||
std::string shootAnimation="WARRIOR_IDLE_S";
|
std::string shootAnimation="WARRIOR_IDLE_S";
|
||||||
std::string deathAnimation="WARRIOR_IDLE_S";
|
std::string deathAnimation="WARRIOR_IDLE_S";
|
||||||
public:
|
public:
|
||||||
MonsterData();
|
MonsterData();
|
||||||
//When specifying animations, the first one will become the default animation. The last becomes the death animation.
|
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);
|
||||||
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);
|
|
||||||
int GetHealth();
|
int GetHealth();
|
||||||
int GetAttack();
|
int GetAttack();
|
||||||
float GetMoveSpdMult();
|
float GetMoveSpdMult();
|
||||||
float GetSizeMult();
|
float GetSizeMult();
|
||||||
MonsterName GetType();
|
int GetAIStrategy();
|
||||||
MonsterStrategy GetAIStrategy();
|
|
||||||
int GetCollisionDmg();
|
int GetCollisionDmg();
|
||||||
|
int GetID();
|
||||||
|
std::string GetIdleAnimation();
|
||||||
std::string GetJumpAnimation();
|
std::string GetJumpAnimation();
|
||||||
std::string GetShootAnimation();
|
std::string GetShootAnimation();
|
||||||
std::string GetDeathAnimation();
|
std::string GetDeathAnimation();
|
||||||
@ -61,10 +47,13 @@ struct MonsterData{
|
|||||||
return animations;
|
return animations;
|
||||||
}
|
}
|
||||||
static void InitializeMonsterData();
|
static void InitializeMonsterData();
|
||||||
|
static std::map<int,Renderable*>imgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Monster{
|
struct Monster{
|
||||||
|
friend struct STRATEGY;
|
||||||
private:
|
private:
|
||||||
|
int id=0;
|
||||||
vf2d pos;
|
vf2d pos;
|
||||||
vf2d vel={0,0};
|
vf2d vel={0,0};
|
||||||
float friction=400;
|
float friction=400;
|
||||||
@ -77,13 +66,12 @@ struct Monster{
|
|||||||
float attackCooldownTimer=0;
|
float attackCooldownTimer=0;
|
||||||
float queueShotTimer=0;
|
float queueShotTimer=0;
|
||||||
Key facingDirection;
|
Key facingDirection;
|
||||||
MonsterStrategy strategy;
|
int strategy;
|
||||||
State state=State::NORMAL;
|
State state=State::NORMAL;
|
||||||
Animate2D::Animation<std::string>animation;
|
Animate2D::Animation<std::string>animation;
|
||||||
Animate2D::AnimationState internal_animState;
|
Animate2D::AnimationState internal_animState;
|
||||||
float randomFrameOffset=0.f;
|
float randomFrameOffset=0.f;
|
||||||
float deathTimer=0.f;
|
float deathTimer=0.f;
|
||||||
MonsterName type;
|
|
||||||
std::vector<Buff>buffList;
|
std::vector<Buff>buffList;
|
||||||
std::string GetDeathAnimationName();
|
std::string GetDeathAnimationName();
|
||||||
bool hasHitPlayer=false;
|
bool hasHitPlayer=false;
|
||||||
@ -125,6 +113,7 @@ public:
|
|||||||
bool SetY(float y);
|
bool SetY(float y);
|
||||||
void PerformJumpAnimation();
|
void PerformJumpAnimation();
|
||||||
void PerformShootAnimation();
|
void PerformShootAnimation();
|
||||||
|
void PerformIdleAnimation();
|
||||||
bool OnUpperLevel();
|
bool OnUpperLevel();
|
||||||
void Moved();
|
void Moved();
|
||||||
void StartPathfinding(float pathingTime);
|
void StartPathfinding(float pathingTime);
|
||||||
@ -134,19 +123,27 @@ public:
|
|||||||
State GetState();
|
State GetState();
|
||||||
void SetState(State newState);
|
void SetState(State newState);
|
||||||
static void InitializeStrategies();
|
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{
|
struct MonsterSpawner{
|
||||||
private:
|
private:
|
||||||
vf2d pos;
|
vf2d pos;
|
||||||
vf2d range;
|
vf2d range;
|
||||||
std::vector<std::pair<MonsterName,vf2d>>monsters;
|
std::vector<std::pair<int,vf2d>>monsters;
|
||||||
bool triggered=false;
|
bool triggered=false;
|
||||||
bool upperLevel=false;
|
bool upperLevel=false;
|
||||||
public:
|
public:
|
||||||
MonsterSpawner();
|
MonsterSpawner();
|
||||||
//For the monster list, the second pair item is the position relative to the spawner to spawn the monster.
|
//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();
|
bool SpawnTriggered();
|
||||||
vf2d GetRange();
|
vf2d GetRange();
|
||||||
vf2d GetPos();
|
vf2d GetPos();
|
||||||
|
@ -7,47 +7,98 @@
|
|||||||
|
|
||||||
INCLUDE_DATA
|
INCLUDE_DATA
|
||||||
INCLUDE_STRATEGY_DATA
|
INCLUDE_STRATEGY_DATA
|
||||||
|
INCLUDE_ANIMATION_DATA
|
||||||
|
|
||||||
std::map<MonsterName,MonsterData>MONSTER_DATA;
|
std::map<int,MonsterData>MONSTER_DATA;
|
||||||
|
|
||||||
MonsterData::MonsterData(){}
|
MonsterData::MonsterData(){}
|
||||||
MonsterData::MonsterData(MonsterName type,int hp,int atk,std::vector<std::string>animations,std::string jumpAnimation,std::string shootAnimation,std::string 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):
|
||||||
,float moveSpd,float size,MonsterStrategy strategy,int collisionDmg):
|
id(id),name(name),hp(hp),atk(atk),moveSpd(moveSpd),size(size),strategy(strategy),animations(animations),collisionDmg(collisionDmg){}
|
||||||
type(type),hp(hp),atk(atk),moveSpd(moveSpd),size(size),strategy(strategy),animations(animations),collisionDmg(collisionDmg)
|
|
||||||
,jumpAnimation(jumpAnimation),shootAnimation(shootAnimation),deathAnimation(deathAnimation){
|
|
||||||
}
|
|
||||||
void MonsterData::InitializeMonsterData(){
|
void MonsterData::InitializeMonsterData(){
|
||||||
for(int i=0;i<MonsterName::END;i++){
|
int id=0;
|
||||||
std::string ID=DATA["Monsters"][std::to_string(i)]["DisplayName"].GetString(1);
|
while(DATA["Monsters"].HasProperty(std::to_string(id))){
|
||||||
|
std::string MonsterName=DATA["Monsters"][std::to_string(id)]["DisplayName"].GetString();
|
||||||
std::vector<std::string>animations{
|
std::vector<std::string>animations{
|
||||||
ID+"_JUMP",
|
MonsterName+"_IDLE",
|
||||||
ID+"_SPIT",
|
MonsterName+"_JUMP",
|
||||||
ID+"_DIE",
|
MonsterName+"_SPIT",
|
||||||
ID+"_IDLE",
|
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.
|
//Add additional custom animations defined in the config.
|
||||||
int animationCounter=0;
|
int animationCounter=0;
|
||||||
while(DATA["Monsters"][std::to_string(i)].HasProperty("ANIMATION["+std::to_string(animationCounter)+"]")){
|
while(DATA["Monsters"][std::to_string(id)].HasProperty("ANIMATION["+std::to_string(animationCounter)+"]")){
|
||||||
animations.push_back(DATA["Monsters"][std::to_string(i)]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString());
|
animations.push_back(DATA["Monsters"][std::to_string(id)]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString());
|
||||||
animationCounter++;
|
animationCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
MonsterData monster(
|
MonsterData monster(
|
||||||
MonsterName(i),
|
id,
|
||||||
DATA["Monsters"][std::to_string(i)]["Health"].GetInt(),
|
MonsterName,
|
||||||
DATA["Monsters"][std::to_string(i)]["Attack"].GetInt(),
|
DATA["Monsters"][std::to_string(id)]["Health"].GetInt(),
|
||||||
|
DATA["Monsters"][std::to_string(id)]["Attack"].GetInt(),
|
||||||
animations,
|
animations,
|
||||||
ID+"_JUMP",
|
DATA["Monsters"][std::to_string(id)]["MoveSpd"].GetReal()/100,
|
||||||
ID+"_SPIT",
|
DATA["Monsters"][std::to_string(id)]["Size"].GetReal()/100,
|
||||||
ID+"_DIE",
|
STRATEGY_DATA[DATA["Monsters"][std::to_string(id)]["Strategy"].GetString()],
|
||||||
DATA["Monsters"][std::to_string(i)]["MoveSpd"].GetReal()/100,
|
DATA["Monsters"][std::to_string(id)]["CollisionDmg"].GetInt()
|
||||||
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()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
MONSTER_DATA[MonsterName(i)]=monster;
|
MONSTER_DATA[id]=monster;
|
||||||
|
|
||||||
|
id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int MonsterData::GetHealth(){
|
int MonsterData::GetHealth(){
|
||||||
@ -65,21 +116,22 @@ float MonsterData::GetSizeMult(){
|
|||||||
int MonsterData::GetCollisionDmg(){
|
int MonsterData::GetCollisionDmg(){
|
||||||
return collisionDmg;
|
return collisionDmg;
|
||||||
}
|
}
|
||||||
MonsterName MonsterData::GetType(){
|
int MonsterData::GetID(){
|
||||||
return type;
|
return id;
|
||||||
}
|
}
|
||||||
MonsterStrategy MonsterData::GetAIStrategy(){
|
int MonsterData::GetAIStrategy(){
|
||||||
return strategy;
|
return strategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MonsterData::GetIdleAnimation(){
|
||||||
|
return animations[IDLE];
|
||||||
|
}
|
||||||
std::string MonsterData::GetJumpAnimation(){
|
std::string MonsterData::GetJumpAnimation(){
|
||||||
return jumpAnimation;
|
return animations[JUMP];
|
||||||
}
|
}
|
||||||
std::string MonsterData::GetShootAnimation(){
|
std::string MonsterData::GetShootAnimation(){
|
||||||
return shootAnimation;
|
return animations[SHOOT];
|
||||||
}
|
}
|
||||||
|
std::string MonsterData::GetDeathAnimation(){
|
||||||
std::string MonsterData::GetDeathAnimation()
|
return animations[DEATH];
|
||||||
{
|
|
||||||
return deathAnimation;
|
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,7 @@ void Player::Knockback(vf2d vel){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Player::Update(float fElapsedTime){
|
void Player::Update(float fElapsedTime){
|
||||||
|
|
||||||
Ability&rightClickAbility=GetRightClickAbility(),
|
Ability&rightClickAbility=GetRightClickAbility(),
|
||||||
&ability=GetAbility1(),
|
&ability=GetAbility1(),
|
||||||
&ability2=GetAbility2(),
|
&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 monsterTag;
|
||||||
XMLTag spawnerLinkTag;
|
XMLTag spawnerLinkTag;
|
||||||
std::vector<XMLTag>accumulatedMonsterTags;
|
std::vector<XMLTag>accumulatedMonsterTags;
|
||||||
|
bool infiniteMap=false;
|
||||||
public:
|
public:
|
||||||
TMXParser(std::string file);
|
TMXParser(std::string file);
|
||||||
};
|
};
|
||||||
@ -209,6 +210,10 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
|
|||||||
XMLTag newTag=ReadNextTag();
|
XMLTag newTag=ReadNextTag();
|
||||||
|
|
||||||
if (newTag.tag=="map") {
|
if (newTag.tag=="map") {
|
||||||
|
if(stoi(newTag.data["infinite"])==1){
|
||||||
|
infiniteMap=true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
parsedMapInfo.MapData={stoi(newTag.data["width"]),stoi(newTag.data["height"])};
|
parsedMapInfo.MapData={stoi(newTag.data["width"]),stoi(newTag.data["height"])};
|
||||||
} else
|
} else
|
||||||
if (newTag.tag=="tileset") {
|
if (newTag.tag=="tileset") {
|
||||||
@ -269,7 +274,7 @@ typedef std::map<std::string,std::vector<geom2d::rect<int>>> ZoneData;
|
|||||||
|
|
||||||
std::string accumulator="";
|
std::string accumulator="";
|
||||||
|
|
||||||
while (f.good()) {
|
while (f.good()&&!infiniteMap) {
|
||||||
std::string data;
|
std::string data;
|
||||||
f>>data;
|
f>>data;
|
||||||
if (data.empty()) continue;
|
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){
|
for(XMLTag&monster:accumulatedMonsterTags){
|
||||||
parsedMapInfo.SpawnerData[monster.GetInteger("spawnerLink")].monsters.push_back(monster);
|
parsedMapInfo.SpawnerData[monster.GetInteger("spawnerLink")].monsters.push_back(monster);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout<<"Parsed Map Data:\n"<<parsedMapInfo<<"\n";
|
std::cout<<"Parsed Map Data:\n"<<parsedMapInfo<<"\n";
|
||||||
}
|
}
|
||||||
#endif
|
#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_MAJOR 0
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 2
|
||||||
#define VERSION_PATCH 0
|
#define VERSION_PATCH 0
|
||||||
#define VERSION_BUILD 976
|
#define VERSION_BUILD 988
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# ==========================================
|
# ==========================================
|
||||||
# ==========================================
|
# ==========================================
|
||||||
#
|
#
|
||||||
# Monster0
|
# 0
|
||||||
# {
|
# {
|
||||||
# Name = Green Slime
|
# Name = Green Slime
|
||||||
# Health = 10
|
# Health = 10
|
||||||
@ -23,7 +23,7 @@
|
|||||||
# MoveSpd = 110
|
# MoveSpd = 110
|
||||||
# Size = 80
|
# Size = 80
|
||||||
#
|
#
|
||||||
# Strategy = RUN_TOWARDS
|
# Strategy = Run Towards
|
||||||
# WaitTime = 5
|
# WaitTime = 5
|
||||||
#
|
#
|
||||||
# [....Cut for length purposes]
|
# [....Cut for length purposes]
|
||||||
@ -38,7 +38,7 @@ MonsterStrategy
|
|||||||
{
|
{
|
||||||
0
|
0
|
||||||
{
|
{
|
||||||
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 = 2
|
||||||
# How far the monster will travel before reassessing for a new path.
|
# How far the monster will travel before reassessing for a new path.
|
||||||
@ -46,7 +46,7 @@ MonsterStrategy
|
|||||||
}
|
}
|
||||||
1
|
1
|
||||||
{
|
{
|
||||||
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 = 800
|
||||||
# How often the enemy shoots.
|
# How often the enemy shoots.
|
||||||
@ -57,8 +57,8 @@ MonsterStrategy
|
|||||||
}
|
}
|
||||||
2
|
2
|
||||||
{
|
{
|
||||||
Name = TURRET
|
Name = Turret
|
||||||
# How far away the monster starts from shooting from
|
# How far away the monster starts shooting from
|
||||||
Range = 800
|
Range = 800
|
||||||
# How often the enemy shoots.
|
# How often the enemy shoots.
|
||||||
ShootingSpeed = 1
|
ShootingSpeed = 1
|
||||||
|
@ -2,7 +2,7 @@ Monsters
|
|||||||
{
|
{
|
||||||
0
|
0
|
||||||
{
|
{
|
||||||
DisplayName = Green Slime, GREEN_SLIME
|
DisplayName = Green Slime
|
||||||
Health = 10
|
Health = 10
|
||||||
Attack = 5
|
Attack = 5
|
||||||
|
|
||||||
@ -11,14 +11,23 @@ Monsters
|
|||||||
MoveSpd = 110
|
MoveSpd = 110
|
||||||
Size = 80
|
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]
|
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||||
}
|
}
|
||||||
1
|
1
|
||||||
{
|
{
|
||||||
DisplayName = Blue Slime, BLUE_SLIME
|
DisplayName = Blue Slime
|
||||||
Health = 30
|
Health = 30
|
||||||
Attack = 10
|
Attack = 10
|
||||||
|
|
||||||
@ -27,14 +36,23 @@ Monsters
|
|||||||
MoveSpd = 80
|
MoveSpd = 80
|
||||||
Size = 100
|
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]
|
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||||
}
|
}
|
||||||
2
|
2
|
||||||
{
|
{
|
||||||
DisplayName = Red Slime, RED_SLIME
|
DisplayName = Red Slime
|
||||||
Health = 25
|
Health = 25
|
||||||
Attack = 10
|
Attack = 10
|
||||||
|
|
||||||
@ -43,14 +61,23 @@ Monsters
|
|||||||
MoveSpd = 95
|
MoveSpd = 95
|
||||||
Size = 120
|
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]
|
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||||
}
|
}
|
||||||
3
|
3
|
||||||
{
|
{
|
||||||
DisplayName = Yellow Slime, YELLOW_SLIME
|
DisplayName = Yellow Slime
|
||||||
Health = 175
|
Health = 175
|
||||||
Attack = 10
|
Attack = 10
|
||||||
|
|
||||||
@ -59,14 +86,23 @@ Monsters
|
|||||||
MoveSpd = 40
|
MoveSpd = 40
|
||||||
Size = 160
|
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]
|
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||||
}
|
}
|
||||||
4
|
4
|
||||||
{
|
{
|
||||||
DisplayName = Flower Turret, FLOWER_TURRET
|
DisplayName = Flower Turret
|
||||||
Health = 40
|
Health = 40
|
||||||
Attack = 10
|
Attack = 10
|
||||||
|
|
||||||
@ -75,7 +111,16 @@ Monsters
|
|||||||
MoveSpd = 0
|
MoveSpd = 0
|
||||||
Size = 100
|
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]
|
#Additional custom animations go down below. Start with ANIMATION[0]
|
||||||
#ANIMATION[0] = MY_NEW_ANIMATION
|
#ANIMATION[0] = MY_NEW_ANIMATION
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Player
|
Player
|
||||||
{
|
{
|
||||||
BaseHealth = 1000
|
BaseHealth = 100
|
||||||
BaseMana = 100
|
BaseMana = 100
|
||||||
MoveSpd = 100
|
MoveSpd = 100
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ GFX_Prefix = assets/
|
|||||||
Images
|
Images
|
||||||
{
|
{
|
||||||
GFX_Warrior_Sheet = nico-warrior.png
|
GFX_Warrior_Sheet = nico-warrior.png
|
||||||
GFX_Slime_Sheet = slime.png
|
|
||||||
GFX_Circle = circle.png
|
GFX_Circle = circle.png
|
||||||
GFX_Effect_GroundSlam_Back = ground-slam-attack-back.png
|
GFX_Effect_GroundSlam_Back = ground-slam-attack-back.png
|
||||||
GFX_Effect_GroundSlam_Front = ground-slam-attack-front.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