|
|
|
#pragma region License
|
|
|
|
/*
|
|
|
|
License (OLC-3)
|
|
|
|
~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
Copyright 2018 - 2023 OneLoneCoder.com
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
are permitted provided that the following conditions are met:
|
|
|
|
|
|
|
|
1. Redistributions or derivations of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
|
|
|
|
2. Redistributions or derivative works in binary form must reproduce the above
|
|
|
|
copyright notice. This list of conditions and the following disclaimer must be
|
|
|
|
reproduced in the documentation and/or other materials provided with the distribution.
|
|
|
|
|
|
|
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
|
|
|
be used to endorse or promote products derived from this software without specific
|
|
|
|
prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
|
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
|
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
|
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
#pragma endregion
|
|
|
|
#include "olcPixelGameEngine.h"
|
|
|
|
#include "Monster.h"
|
|
|
|
#include "Animation.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "DEFINES.h"
|
|
|
|
#include "safemap.h"
|
|
|
|
|
|
|
|
INCLUDE_DATA
|
|
|
|
INCLUDE_STRATEGY_DATA
|
|
|
|
INCLUDE_ANIMATION_DATA
|
|
|
|
|
|
|
|
std::map<int,MonsterData>MONSTER_DATA;
|
|
|
|
safemap<std::string,MonsterData*>MONSTER_NAME_DATA;
|
|
|
|
|
|
|
|
MonsterData::MonsterData()
|
|
|
|
:atk(0),collisionDmg(0),hp(0),id(0),moveSpd(0),size(0),strategy(0){}
|
|
|
|
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(){
|
|
|
|
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{
|
|
|
|
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(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(
|
|
|
|
id,
|
|
|
|
MonsterName,
|
|
|
|
DATA["Monsters"][std::to_string(id)]["Health"].GetInt(),
|
|
|
|
DATA["Monsters"][std::to_string(id)]["Attack"].GetInt(),
|
|
|
|
animations,
|
|
|
|
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[id]=monster;
|
|
|
|
MONSTER_NAME_DATA[MonsterName]=&MONSTER_DATA[id];
|
|
|
|
|
|
|
|
id++;
|
|
|
|
}
|
|
|
|
|
|
|
|
MONSTER_NAME_DATA.SetInitialized();
|
|
|
|
}
|
|
|
|
int MonsterData::GetHealth(){
|
|
|
|
return hp;
|
|
|
|
}
|
|
|
|
int MonsterData::GetAttack(){
|
|
|
|
return atk;
|
|
|
|
}
|
|
|
|
float MonsterData::GetMoveSpdMult(){
|
|
|
|
return moveSpd;
|
|
|
|
}
|
|
|
|
float MonsterData::GetSizeMult(){
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
int MonsterData::GetCollisionDmg(){
|
|
|
|
return collisionDmg;
|
|
|
|
}
|
|
|
|
int MonsterData::GetID(){
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
int MonsterData::GetAIStrategy(){
|
|
|
|
return strategy;
|
|
|
|
}
|
|
|
|
std::string MonsterData::GetDisplayName(){
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string MonsterData::GetIdleAnimation(){
|
|
|
|
return animations[IDLE];
|
|
|
|
}
|
|
|
|
std::string MonsterData::GetJumpAnimation(){
|
|
|
|
return animations[JUMP];
|
|
|
|
}
|
|
|
|
std::string MonsterData::GetShootAnimation(){
|
|
|
|
return animations[SHOOT];
|
|
|
|
}
|
|
|
|
std::string MonsterData::GetDeathAnimation(){
|
|
|
|
return animations[DEATH];
|
|
|
|
}
|