Added NPC structures and new NPCs to the hub map.
This commit is contained in:
parent
51e838de24
commit
ebf7fcf395
@ -15,8 +15,6 @@ Global
|
||||
Emscripten|x86 = Emscripten|x86
|
||||
Release Desktop|x64 = Release Desktop|x64
|
||||
Release Desktop|x86 = Release Desktop|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@ -35,10 +33,6 @@ Global
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release Desktop|x64.Build.0 = Release Desktop|x64
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release Desktop|x86.ActiveCfg = Release Desktop|Win32
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release Desktop|x86.Build.0 = Release Desktop|Win32
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release|x64.ActiveCfg = Release|x64
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release|x64.Build.0 = Release|x64
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release|x86.ActiveCfg = Release|Win32
|
||||
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -216,7 +216,7 @@
|
||||
"STORY_1_2",
|
||||
"STORY_1_3",
|
||||
"BOSS_1",
|
||||
"BLACKSMITH",
|
||||
"HUB",
|
||||
"CAMPAIGN_1_B1",
|
||||
"BOSS_1_B"
|
||||
],
|
||||
@ -507,7 +507,7 @@
|
||||
"DUNGEON",
|
||||
"BOSS",
|
||||
"STORY",
|
||||
"SHOP"
|
||||
"HUB"
|
||||
],
|
||||
"valuesAsFlags": false
|
||||
},
|
||||
|
@ -29,18 +29,10 @@
|
||||
<Configuration>Release Desktop</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
@ -57,13 +49,6 @@
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Desktop|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
@ -77,13 +62,6 @@
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Desktop|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
@ -111,18 +89,12 @@
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Desktop|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Desktop|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
@ -160,29 +132,6 @@
|
||||
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Desktop|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
@ -231,32 +180,6 @@
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File emscripten_build.ps1</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Desktop|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||
@ -701,6 +624,10 @@
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Meteor.cpp" />
|
||||
<ClCompile Include="NPC.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OverworldMapLevelWindow.cpp" />
|
||||
<ClCompile Include="OverworldMenuWindow.cpp">
|
||||
<SubType>
|
||||
@ -812,6 +739,7 @@
|
||||
<Text Include="assets\config\levels.txt" />
|
||||
<Text Include="assets\config\Monsters.txt" />
|
||||
<Text Include="assets\config\MonsterStrategies.txt" />
|
||||
<Text Include="assets\config\NPCs.txt" />
|
||||
<Text Include="assets\config\Player.txt" />
|
||||
<Text Include="assets\config\shops\Chapter 1 Merchants.txt" />
|
||||
<Text Include="assets\config\shops\Chapter 2 Merchants.txt" />
|
||||
|
@ -770,6 +770,9 @@
|
||||
<ClCompile Include="State_GameHub.cpp">
|
||||
<Filter>Source Files\Game States</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NPC.cpp">
|
||||
<Filter>Source Files\Monster Strategies</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
@ -918,6 +921,9 @@
|
||||
<Text Include="characters.txt">
|
||||
<Filter>Documentation</Filter>
|
||||
</Text>
|
||||
<Text Include="assets\config\NPCs.txt">
|
||||
<Filter>Configurations</Filter>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="assets\heart.ico">
|
||||
|
@ -143,6 +143,9 @@ AiL::AiL()
|
||||
std::string MONSTERS_CONFIG = CONFIG_PATH + "monsters_config"_S;
|
||||
utils::datafile::Read(DATA,MONSTERS_CONFIG);
|
||||
|
||||
std::string NPC_CONFIG = CONFIG_PATH + "npc_config"_S;
|
||||
utils::datafile::Read(DATA,NPC_CONFIG);
|
||||
|
||||
std::string MONSTERSTRATEGIES_CONFIG = CONFIG_PATH + "monsterstrategies_config"_S;
|
||||
utils::datafile::Read(DATA,MONSTERSTRATEGIES_CONFIG);
|
||||
|
||||
@ -233,6 +236,7 @@ bool AiL::OnUserCreate(){
|
||||
//Animations
|
||||
sig::Animation::InitializeAnimations();
|
||||
MonsterData::InitializeMonsterData();
|
||||
MonsterData::InitializeNPCData();
|
||||
|
||||
sig::Animation::SetupPlayerAnimations();
|
||||
view=TileTransformedView{GetScreenSize(),{1,1}};
|
||||
@ -1982,11 +1986,19 @@ void AiL::LoadLevel(MapName map){
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
for(NPCData data:game->MAP_DATA[game->GetCurrentLevel()].npcs){
|
||||
MONSTER_LIST.push_back(Monster{data.spawnPos,MONSTER_DATA[data.name]});
|
||||
MONSTER_LIST.back().iframe_timer=INFINITE;
|
||||
}
|
||||
|
||||
player->GetAbility1().cooldown=0.f;
|
||||
player->GetAbility2().cooldown=0.f;
|
||||
player->GetAbility3().cooldown=0.f;
|
||||
player->GetAbility4().cooldown=0.f;
|
||||
player->GetRightClickAbility().cooldown=0.f;
|
||||
player->useItem1.cooldown=0.f;
|
||||
player->useItem2.cooldown=0.f;
|
||||
player->useItem3.cooldown=0.f;
|
||||
|
||||
player->upperLevel=false; //Assume player starts on lower level.
|
||||
player->ForceSetPos(MAP_DATA[map].MapData.playerSpawnLocation); //Normal set pos does one axis and then the other, so this will make sure that we actually end up at the right spot and ignore collision rules.
|
||||
|
@ -126,6 +126,18 @@ void Monster::PerformShootAnimation(){
|
||||
void Monster::PerformIdleAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[name].GetIdleAnimation());
|
||||
}
|
||||
void Monster::PerformNPCDownAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[name].GetIdleAnimation());
|
||||
}
|
||||
void Monster::PerformNPCUpAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[name].GetJumpAnimation());
|
||||
}
|
||||
void Monster::PerformNPCLeftAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[name].GetShootAnimation());
|
||||
}
|
||||
void Monster::PerformNPCRightAnimation(){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[name].GetDeathAnimation());
|
||||
}
|
||||
void Monster::PerformOtherAnimation(const uint8_t otherInd){
|
||||
animation.ChangeState(internal_animState,MONSTER_DATA[name].GetAnimations()[4+otherInd]);
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ struct MonsterData{
|
||||
const std::vector<MonsterDropData>&GetDropData();
|
||||
std::string GetDisplayName();
|
||||
static void InitializeMonsterData();
|
||||
static void InitializeNPCData();
|
||||
static std::map<std::string,Renderable*>imgs;
|
||||
};
|
||||
|
||||
@ -154,6 +155,10 @@ public:
|
||||
void PerformJumpAnimation();
|
||||
void PerformShootAnimation();
|
||||
void PerformIdleAnimation();
|
||||
void PerformNPCDownAnimation();
|
||||
void PerformNPCUpAnimation();
|
||||
void PerformNPCLeftAnimation();
|
||||
void PerformNPCRightAnimation();
|
||||
void PerformOtherAnimation(const uint8_t otherInd);
|
||||
bool OnUpperLevel();
|
||||
void Moved();
|
||||
@ -267,6 +272,7 @@ private:
|
||||
static void WOLF(Monster&m,float fElapsedTime,std::string strategy);
|
||||
static void BEAR(Monster&m,float fElapsedTime,std::string strategy);
|
||||
static void URSULE(Monster&m,float fElapsedTime,std::string strategy);
|
||||
static void NPC(Monster&m,float fElapsedTime,std::string strategy);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -206,6 +206,161 @@ void MonsterData::InitializeMonsterData(){
|
||||
MONSTER_DATA[MonsterName]=monster;
|
||||
}
|
||||
}
|
||||
void MonsterData::InitializeNPCData(){
|
||||
for(auto&[key,size]:DATA["NPCs"].GetKeys()){
|
||||
std::string NPCName=key;
|
||||
if(MONSTER_DATA.count(key)){
|
||||
ERR("WARNING! A monster with the name "<<key<<" already exists in the database! Duplicates are not allowed.")
|
||||
}
|
||||
std::vector<std::string>animations{
|
||||
NPCName+"_IDLE",
|
||||
NPCName+"_JUMP",
|
||||
NPCName+"_SPIT",
|
||||
NPCName+"_DIE",
|
||||
};
|
||||
|
||||
MonsterData::imgs[NPCName]=NEW Renderable();
|
||||
const rcode imgLoadResult=MonsterData::imgs[NPCName]->Load("assets/npcs/"+NPCName+".png");
|
||||
if(imgLoadResult!=OK)ERR(std::format("WARNING! Image loading for NPC {} failed with result {}",NPCName,int(imgLoadResult)));
|
||||
|
||||
|
||||
EventName hurtSound="";
|
||||
EventName deathSound="";
|
||||
EventName walkSound="";
|
||||
|
||||
int health=100;
|
||||
int attack=0;
|
||||
int xp=0;
|
||||
float moveSpd=100.f;
|
||||
float size=100.f;
|
||||
int collisionDmg=0;
|
||||
|
||||
if(DATA["NPCs"][NPCName].HasProperty("Health"))health=DATA["NPCs"][NPCName]["Health"].GetInt();
|
||||
if(DATA["NPCs"][NPCName].HasProperty("Attack"))attack=DATA["NPCs"][NPCName]["Attack"].GetInt();
|
||||
if(DATA["NPCs"][NPCName].HasProperty("XP"))xp=DATA["NPCs"][NPCName]["XP"].GetInt();
|
||||
if(DATA["NPCs"][NPCName].HasProperty("MoveSpd"))moveSpd=DATA["NPCs"][NPCName]["MoveSpd"].GetReal();
|
||||
if(DATA["NPCs"][NPCName].HasProperty("Size"))moveSpd=DATA["NPCs"][NPCName]["Size"].GetReal();
|
||||
if(DATA["NPCs"][NPCName].HasProperty("CollisionDmg"))collisionDmg=DATA["NPCs"][NPCName]["CollisionDmg"].GetInt();
|
||||
|
||||
if(DATA["NPCs"][NPCName].HasProperty("Hurt Sound")){
|
||||
hurtSound=DATA["NPCs"][NPCName]["Hurt Sound"].GetString();
|
||||
}
|
||||
if(DATA["NPCs"][NPCName].HasProperty("Death Sound")){
|
||||
deathSound=DATA["NPCs"][NPCName]["Death Sound"].GetString();
|
||||
}
|
||||
if(DATA["NPCs"][NPCName].HasProperty("Walk Sound")){
|
||||
walkSound=DATA["NPCs"][NPCName]["Walk Sound"].GetString();
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
for(int i=0;i<animations.size();i++){
|
||||
std::string animationConfigName="";
|
||||
std::string imgName="";
|
||||
switch(i){
|
||||
case 0:{
|
||||
animationConfigName="Down";
|
||||
imgName="_IDLE";
|
||||
}break;
|
||||
case 1:{
|
||||
animationConfigName="Up";
|
||||
imgName="_JUMP";
|
||||
}break;
|
||||
case 2:{
|
||||
animationConfigName="Left";
|
||||
imgName="_SPIT";
|
||||
}break;
|
||||
case 3:{
|
||||
animationConfigName="Right";
|
||||
imgName="_DIE";
|
||||
}break;
|
||||
}
|
||||
Animate2D::Style style=Animate2D::Style::Repeat;
|
||||
if(DATA["NPCs"][NPCName][animationConfigName+"Animation"].GetString(2)=="Repeat"){
|
||||
style=Animate2D::Style::Repeat;
|
||||
}else
|
||||
if(DATA["NPCs"][NPCName][animationConfigName+"Animation"].GetString(2)=="OneShot"){
|
||||
style=Animate2D::Style::OneShot;
|
||||
}else
|
||||
if(DATA["NPCs"][NPCName][animationConfigName+"Animation"].GetString(2)=="PingPong"){
|
||||
style=Animate2D::Style::PingPong;
|
||||
}else
|
||||
if(DATA["NPCs"][NPCName][animationConfigName+"Animation"].GetString(2)=="Reverse"){
|
||||
style=Animate2D::Style::Reverse;
|
||||
}else{
|
||||
ERR(std::format("WARNING! Invalid Animation Style specified: {}",int(style)));
|
||||
}
|
||||
|
||||
int frameCount=DATA["NPCs"][NPCName][animationConfigName+"Animation"].GetInt(0);
|
||||
vf2d frameSize=vf2d{float(DATA["NPCs"][NPCName]["SheetFrameSize"].GetInt(0)),float(DATA["NPCs"][NPCName]["SheetFrameSize"].GetInt(1))};
|
||||
CreateHorizontalAnimationSequence(*MonsterData::imgs[NPCName],frameCount,frameSize,NPCName+imgName,i,AnimationData{float(DATA["NPCs"][NPCName][animationConfigName+"Animation"].GetReal(1)),style});
|
||||
}
|
||||
|
||||
//Add additional custom animations defined in the config.
|
||||
int animationCounter=0;
|
||||
int row=4;
|
||||
while(DATA["NPCs"][NPCName].HasProperty("ANIMATION["+std::to_string(animationCounter)+"]")){
|
||||
animations.push_back(NPCName+"ANIMATION["+std::to_string(animationCounter)+"]");
|
||||
|
||||
#pragma region Parse Animation Data
|
||||
Animate2D::Style style;
|
||||
if(DATA["NPCs"][NPCName]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString(2)=="Repeat"){
|
||||
style=Animate2D::Style::Repeat;
|
||||
}else
|
||||
if(DATA["NPCs"][NPCName]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString(2)=="OneShot"){
|
||||
style=Animate2D::Style::OneShot;
|
||||
}else
|
||||
if(DATA["NPCs"][NPCName]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString(2)=="PingPong"){
|
||||
style=Animate2D::Style::PingPong;
|
||||
}else
|
||||
if(DATA["NPCs"][NPCName]["ANIMATION["+std::to_string(animationCounter)+"]"].GetString(2)=="Reverse"){
|
||||
style=Animate2D::Style::Reverse;
|
||||
}else{
|
||||
ERR(std::format("WARNING! Invalid Animation Style specified: {}",int(style)));
|
||||
}
|
||||
|
||||
int frameCount=DATA["NPCs"][NPCName]["ANIMATION["+std::to_string(animationCounter)+"]"].GetInt(0);
|
||||
vf2d frameSize=vf2d{float(DATA["NPCs"][NPCName]["SheetFrameSize"].GetInt(0)),float(DATA["NPCs"][NPCName]["SheetFrameSize"].GetInt(1))};
|
||||
CreateHorizontalAnimationSequence(*MonsterData::imgs[NPCName],frameCount,frameSize,NPCName+"ANIMATION["+std::to_string(animationCounter)+"]",row,AnimationData{float(DATA["NPCs"][NPCName]["ANIMATION["+std::to_string(animationCounter)+"]"].GetReal(1)),style});
|
||||
#pragma endregion
|
||||
|
||||
row++;
|
||||
animationCounter++;
|
||||
}
|
||||
|
||||
std::vector<MonsterDropData>drops;
|
||||
|
||||
//Add drop items to monster data from the config.
|
||||
int dropDataCounter=0;
|
||||
while(DATA["NPCs"][NPCName].HasProperty("DROP["+std::to_string(dropDataCounter)+"]")){
|
||||
datafile drop=DATA["NPCs"][NPCName]["DROP["+std::to_string(dropDataCounter)+"]"];
|
||||
if(!ITEM_DATA.count(drop.GetString(0))){
|
||||
ERR("Could not add drop "<<drop.GetString(0)<<" to "<<NPCName<<"'s drop table! Item does not exist!");
|
||||
}
|
||||
drops.push_back(MonsterDropData{drop.GetString(0),float(drop.GetReal(1)),drop.GetInt(2),drop.GetInt(3)});
|
||||
dropDataCounter++;
|
||||
}
|
||||
|
||||
const std::string&strategyName=DATA["NPCs"][NPCName]["Strategy"].GetString();
|
||||
if(!STRATEGY_DATA.count(strategyName)){
|
||||
ERR("WARNING! Strategy for "<<NPCName<<" does not exist in strategy database!");
|
||||
}
|
||||
|
||||
MonsterData monster(NPCName,health,attack,xp,animations,drops,moveSpd,size/100,strategyName,collisionDmg);
|
||||
|
||||
monster.hurtSound=hurtSound;
|
||||
monster.deathSound=deathSound;
|
||||
monster.walkSound=walkSound;
|
||||
|
||||
MONSTER_DATA[NPCName]=monster;
|
||||
}
|
||||
}
|
||||
int MonsterData::GetHealth(){
|
||||
return hp;
|
||||
}
|
||||
|
45
Adventures in Lestoria/NPC.cpp
Normal file
45
Adventures in Lestoria/NPC.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2024 Joshua Sigona <sigonasr2@gmail.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.
|
||||
|
||||
Portions of this software are copyright © 2023 The FreeType
|
||||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
|
||||
#include "Monster.h"
|
||||
|
||||
using A=Attribute;
|
||||
|
||||
void Monster::STRATEGY::NPC(Monster&m,float fElapsedTime,std::string strategy){
|
||||
|
||||
}
|
@ -52,6 +52,7 @@ void Monster::InitializeStrategies(){
|
||||
STRATEGY_DATA.insert("Wolf",Monster::STRATEGY::WOLF);
|
||||
STRATEGY_DATA.insert("Bear",Monster::STRATEGY::BEAR);
|
||||
STRATEGY_DATA.insert("Ursule",Monster::STRATEGY::URSULE);
|
||||
STRATEGY_DATA.insert("NPC",Monster::STRATEGY::NPC);
|
||||
|
||||
STRATEGY_DATA.SetInitialized();
|
||||
}
|
||||
|
@ -94,6 +94,16 @@ struct ZoneData{
|
||||
bool isUpper=false;
|
||||
};
|
||||
|
||||
struct NPCData{
|
||||
std::string function="";
|
||||
std::string name="";
|
||||
std::string sprite="";
|
||||
std::string spawnFlag="";
|
||||
uint32_t roamingRange=0;
|
||||
vf2d spawnPos;
|
||||
NPCData(XMLTag npcTag);
|
||||
};
|
||||
|
||||
struct Map{
|
||||
friend class AiL;
|
||||
friend class TMXParser;
|
||||
@ -105,6 +115,7 @@ private:
|
||||
std::vector<LayerTag> LayerData;
|
||||
std::vector<EnvironmentalAudio>environmentalAudioData;
|
||||
std::vector<ItemMapData>stageLoot;
|
||||
std::vector<NPCData>npcs;
|
||||
std::string mapType="";
|
||||
std::string bgmSongName="";
|
||||
BackdropName backdrop="";
|
||||
@ -153,7 +164,9 @@ class TMXParser{
|
||||
EnvironmentalAudio*prevAudioData=nullptr;
|
||||
void ParseTag(std::string tag);
|
||||
int monsterPropertyTagCount=-1;
|
||||
bool inNPCTag=false;
|
||||
XMLTag monsterTag;
|
||||
XMLTag npcTag;
|
||||
XMLTag spawnerLinkTag;
|
||||
StagePlate*currentStagePlate;
|
||||
std::vector<XMLTag>accumulatedMonsterTags;
|
||||
@ -283,6 +296,37 @@ class TMXParser{
|
||||
const std::string_view Map::GetMapDisplayName()const{
|
||||
return name;
|
||||
}
|
||||
NPCData::NPCData(XMLTag npcTag){
|
||||
const std::array<std::string,7>tags={"Function","NPC Name","Roaming Range","Spawn Flag","Spritesheet","x","y"};
|
||||
|
||||
for(int i=0;i<tags.size();i++){
|
||||
if(npcTag.data.contains(tags[i])){
|
||||
switch(i){
|
||||
case 0:{ //Function
|
||||
function=npcTag.GetString(tags[i]);
|
||||
}break;
|
||||
case 1:{ //NPC Name
|
||||
name=npcTag.GetString(tags[i]);
|
||||
}break;
|
||||
case 2:{ //Roaming Range
|
||||
roamingRange=npcTag.GetInteger(tags[i]);
|
||||
}break;
|
||||
case 3:{ //Spawn Flag
|
||||
spawnFlag=npcTag.GetString(tags[i]);
|
||||
}break;
|
||||
case 4:{ //Spritesheet
|
||||
sprite=npcTag.GetString(tags[i]);
|
||||
}break;
|
||||
case 5:{ //X
|
||||
spawnPos.x=npcTag.GetFloat(tags[i]);
|
||||
}break;
|
||||
case 6:{ //Y
|
||||
spawnPos.y=npcTag.GetFloat(tags[i]);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::ostream& operator <<(std::ostream& os, std::vector<XMLTag>& rhs) {
|
||||
for(XMLTag&tag:rhs){
|
||||
os <<
|
||||
@ -360,6 +404,10 @@ class TMXParser{
|
||||
if (newTag.tag=="object"&&newTag.data["type"]!="StagePlate"){
|
||||
currentStagePlate=nullptr;
|
||||
}
|
||||
if (newTag.tag=="object"&&newTag.data["type"]!="NPC"&&inNPCTag){
|
||||
inNPCTag=false;
|
||||
parsedMapInfo.npcs.push_back(NPCData{npcTag});
|
||||
}
|
||||
|
||||
if (newTag.tag=="map"){
|
||||
if(stoi(newTag.data["infinite"])==1){
|
||||
@ -419,10 +467,18 @@ class TMXParser{
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="PlayerSpawnLocation") {
|
||||
parsedMapInfo.MapData.playerSpawnLocation={newTag.GetInteger("x")-newTag.GetInteger("width")/2,newTag.GetInteger("y")-newTag.GetInteger("height")/2};
|
||||
} else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="NPC") {
|
||||
if(inNPCTag)parsedMapInfo.npcs.push_back(NPCData{npcTag});
|
||||
npcTag=newTag;
|
||||
inNPCTag=true;
|
||||
} else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="Monster") {
|
||||
monsterTag=newTag;
|
||||
monsterPropertyTagCount=0;
|
||||
} else
|
||||
if (newTag.tag=="property"&&inNPCTag) {
|
||||
npcTag.data[newTag.data["name"]]=newTag.data["value"];
|
||||
}
|
||||
if (newTag.tag=="property"&&monsterPropertyTagCount==0) {
|
||||
if(newTag.data["value"]=="None")ERR(std::format("WARNING! Invalid monster type provided: {} in map {}",newTag.data["value"],fileName));
|
||||
monsterTag.data["value"]=newTag.data["value"];
|
||||
@ -515,6 +571,10 @@ class TMXParser{
|
||||
}
|
||||
}
|
||||
|
||||
if(inNPCTag){
|
||||
parsedMapInfo.npcs.push_back(NPCData{npcTag});
|
||||
}
|
||||
|
||||
if(infiniteMap){
|
||||
#if _DEBUG
|
||||
if(_DEBUG_MAP_LOAD_INFO)std::cout<<"Infinite map detected. Parsing stopped early."<<std::endl;
|
||||
|
@ -26,7 +26,7 @@ Settings Menu
|
||||
- If you leave a stage, the stage complete window still shows up, showing only the loot you obtained that session.
|
||||
|
||||
- No equip sounds for weapons?
|
||||
|
||||
- Large numbers when dealing normal damage?
|
||||
- When setting loadout items while loading the game it should highlight the correct item in the consumables inventory as well.
|
||||
|
||||
January 31st
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 6517
|
||||
#define VERSION_BUILD 6529
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -2,7 +2,7 @@
|
||||
<map version="1.10" tiledversion="1.10.1" class="Map" orientation="orthogonal" renderorder="left-down" width="250" height="177" tilewidth="4" tileheight="4" infinite="0" nextlayerid="5" nextobjectid="19">
|
||||
<properties>
|
||||
<property name="Background Music" propertytype="BGM" value="overworld"/>
|
||||
<property name="Level Type" propertytype="LevelType" value="World Map"/>
|
||||
<property name="Level Type" propertytype="LevelType" value="Hub"/>
|
||||
<property name="Optimize" type="bool" value="true"/>
|
||||
</properties>
|
||||
<tileset firstgid="1" source="../maps/Minifantasy_TinyOverworldAllTiles.tsx"/>
|
||||
@ -601,11 +601,11 @@
|
||||
<property name="Unlock Condition" propertytype="Level" value="CAMPAIGN_1_2"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="8" name="Blacksmith I" type="StagePlate" x="416" y="416" width="20" height="24">
|
||||
<object id="8" name="Base" type="StagePlate" x="416" y="416" width="20" height="24">
|
||||
<properties>
|
||||
<property name="Map" propertytype="Level" value="BLACKSMITH"/>
|
||||
<property name="Type" propertytype="StageType" value="SHOP"/>
|
||||
<property name="Unlock Condition" propertytype="Level" value="STORY_1_2"/>
|
||||
<property name="Map" propertytype="Level" value="HUB"/>
|
||||
<property name="Type" propertytype="StageType" value="HUB"/>
|
||||
<property name="Unlock Condition" propertytype="Level" value="STORY_1_1"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="9" name="Stage IV" type="StagePlate" x="172" y="580" width="44" height="16">
|
||||
|
@ -489,4 +489,7 @@ MonsterStrategy
|
||||
End Wisp Fadeout Time = 0.4s
|
||||
}
|
||||
}
|
||||
NPC
|
||||
{
|
||||
}
|
||||
}
|
69
Adventures in Lestoria/assets/config/NPCs.txt
Normal file
69
Adventures in Lestoria/assets/config/NPCs.txt
Normal file
@ -0,0 +1,69 @@
|
||||
NPCs
|
||||
{
|
||||
Greg
|
||||
{
|
||||
Strategy = NPC
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
DownAnimation = 1, 0.1, OneShot
|
||||
UpAnimation = 1, 0.1, OneShot
|
||||
LeftAnimation = 1, 0.1, OneShot
|
||||
RightAnimation = 1, 0.1, OneShot
|
||||
|
||||
Hurt Sound = Monster Hurt
|
||||
Death Sound = Slime Dead
|
||||
Walk Sound = Slime Walk
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0] Order is:
|
||||
# File name, Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
# NOTE: ANIMATION[0] will always be row 5 of an animation sheet, all numbers that follow are each below each other.
|
||||
#ANIMATION[0] = 6, 0.1, Repeat
|
||||
}
|
||||
Sherman
|
||||
{
|
||||
Strategy = NPC
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
DownAnimation = 1, 0.1, OneShot
|
||||
UpAnimation = 1, 0.1, OneShot
|
||||
LeftAnimation = 1, 0.1, OneShot
|
||||
RightAnimation = 1, 0.1, OneShot
|
||||
|
||||
Hurt Sound = Monster Hurt
|
||||
Death Sound = Slime Dead
|
||||
Walk Sound = Slime Walk
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0] Order is:
|
||||
# File name, Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
# NOTE: ANIMATION[0] will always be row 5 of an animation sheet, all numbers that follow are each below each other.
|
||||
#ANIMATION[0] = 6, 0.1, Repeat
|
||||
}
|
||||
Traveling Merchant
|
||||
{
|
||||
Strategy = NPC
|
||||
|
||||
#Size of each animation frame
|
||||
SheetFrameSize = 24,24
|
||||
|
||||
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
DownAnimation = 1, 0.1, OneShot
|
||||
UpAnimation = 1, 0.1, OneShot
|
||||
LeftAnimation = 1, 0.1, OneShot
|
||||
RightAnimation = 1, 0.1, OneShot
|
||||
|
||||
Hurt Sound = Monster Hurt
|
||||
Death Sound = Slime Dead
|
||||
Walk Sound = Slime Walk
|
||||
|
||||
#Additional custom animations go down below. Start with ANIMATION[0] Order is:
|
||||
# File name, Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
|
||||
# NOTE: ANIMATION[0] will always be row 5 of an animation sheet, all numbers that follow are each below each other.
|
||||
#ANIMATION[0] = 6, 0.1, Repeat
|
||||
}
|
||||
}
|
@ -23,6 +23,9 @@ player_config = Player.txt
|
||||
# Monster Properties Loading Config
|
||||
monsters_config = Monsters.txt
|
||||
|
||||
# NPC Loading Config
|
||||
npc_config = NPCs.txt
|
||||
|
||||
# Monster Strategy Config
|
||||
monsterstrategies_config = MonsterStrategies.txt
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Loading…
x
Reference in New Issue
Block a user