Added Merchant config files and parsing of config files to merchant structure.

pull/28/head
sigonasr2 1 year ago
parent f3bfa81198
commit 2b3c1ea1b4
  1. 1
      Crawler/Buff.h
  2. 26
      Crawler/Crawler.cpp
  3. 8
      Crawler/Crawler.vcxproj
  4. 6
      Crawler/Crawler.vcxproj.filters
  5. 28
      Crawler/Item.cpp
  6. 7
      Crawler/Item.h
  7. 98
      Crawler/Merchant.cpp
  8. 56
      Crawler/Merchant.h
  9. 3
      Crawler/Player.cpp
  10. 2
      Crawler/Version.h
  11. 6
      Crawler/assets/config/Monsters.txt
  12. 3
      Crawler/assets/config/configuration.txt
  13. 2
      Crawler/assets/config/items/ItemDatabase.txt
  14. 19
      Crawler/assets/config/items/ItemScript.txt
  15. 45
      Crawler/assets/config/shops/Chapter 1 Merchants.txt
  16. 5
      Crawler/assets/config/shops/Chapter 2 Merchants.txt
  17. 5
      Crawler/assets/config/shops/Chapter 3 Merchants.txt
  18. 5
      Crawler/assets/config/shops/Chapter 4 Merchants.txt
  19. 5
      Crawler/assets/config/shops/Chapter 5 Merchants.txt
  20. 5
      Crawler/assets/config/shops/Chapter 6 Merchants.txt
  21. 13
      Crawler/olcUTIL_DataFile.h

@ -38,6 +38,7 @@ All rights reserved.
#pragma once
enum BuffType{
ATTACK_UP,
ATTACK_PCT_UP,
DAMAGE_REDUCTION,
SLOWDOWN,
BLOCK_SLOWDOWN,

@ -66,6 +66,7 @@ All rights reserved.
#include "util.h"
#include "olcPGEX_TTF.h"
#include "MenuItemItemButton.h"
#include "Merchant.h"
INCLUDE_EMITTER_LIST
@ -134,12 +135,12 @@ Crawler::Crawler()
DEBUG_PATHFINDING="debug_pathfinding"_I;
for(std::string&cl:DATA.GetProperty("class_list").GetValues()){
for(const std::string&cl:DATA.GetProperty("class_list").GetValues()){
std::cout<<cl<<std::endl;
utils::datafile::Read(DATA,CONFIG_PATH + "class_directory"_S + cl + ".txt");
}
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
utils::datafile::INITIAL_SETUP_COMPLETE=true;
}
bool Crawler::OnUserCreate(){
@ -175,22 +176,7 @@ bool Crawler::OnUserCreate(){
Menu::InitializeMenus();
Inventory::AddItem("Small Health Potion",16);
Inventory::AddItem("Large Health Potion",3);
Inventory::AddItem("Medium Mana Potion",1);
Inventory::AddItem("Dummy Item 1",78);
Inventory::AddItem("Dummy Item 2",3);
Inventory::AddItem("Dummy Item 3",5);
Inventory::AddItem("Dummy Item 4",8);
Inventory::AddItem("Dummy Item 5",6);
Inventory::AddItem("Dummy Item 6",3);
Inventory::AddItem("Dummy Item 7",5);
Inventory::AddItem("Dummy Item 8",8);
Inventory::AddItem("Dummy Item 9",3);
Inventory::AddItem("Dummy Item 10",4);
Inventory::AddItem("Dummy Item 11",8);
Inventory::AddItem("Dummy Item 12",3);
Inventory::AddItem("Dummy Item 13",6);
Inventory::AddItem("Minor Health Potion",16);
Inventory::AddItem("Bandages",10);
Inventory::AddItem("Blue Slime Remains",22);
Inventory::AddItem("Copper Armor");
@ -211,6 +197,10 @@ bool Crawler::OnUserCreate(){
Unlock::Initialize();
ItemDrop::Initialize();
Merchant::Initialize();
utils::datafile::INITIAL_SETUP_COMPLETE=true;
ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
return true;

@ -331,6 +331,10 @@
<ClInclude Include="Key.h" />
<ClInclude Include="Map.h" />
<ClInclude Include="Menu.h" />
<ClInclude Include="Merchant.h">
<SubType>
</SubType>
</ClInclude>
<ClInclude Include="miniaudio.h">
<SubType>
</SubType>
@ -444,6 +448,10 @@
<ClCompile Include="Menu.cpp" />
<ClCompile Include="MenuAnimatedIconButton.h" />
<ClCompile Include="MenuComponent.cpp" />
<ClCompile Include="Merchant.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="Meteor.cpp" />
<ClCompile Include="OverworldMapLevelWindow.cpp" />
<ClCompile Include="OverworldMenuWindow.cpp">

@ -306,6 +306,9 @@
<ClInclude Include="RowInventoryScrollableWindowComponent.h">
<Filter>Header Files\Interface</Filter>
</ClInclude>
<ClInclude Include="Merchant.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Player.cpp">
@ -497,6 +500,9 @@
<ClCompile Include="InventoryWindow.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
<ClCompile Include="Merchant.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />

@ -201,17 +201,17 @@ void ItemInfo::InitializeItems(){
ItemProps::ItemProps(utils::datafile*scriptProps,utils::datafile*customProps)
:scriptProps(scriptProps),customProps(customProps){}
int ItemProps::GetIntProp(std::string prop){
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetInt();
else return (*scriptProps)[prop].GetInt();
int ItemProps::GetIntProp(std::string prop,size_t index=0){
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetInt(index);
else return (*scriptProps)[prop].GetInt(index);
};
float ItemProps::GetFloatProp(std::string prop){
if(customProps->HasProperty(prop)) return float((*customProps)[prop].GetReal());
else return float((*scriptProps)[prop].GetReal());
float ItemProps::GetFloatProp(std::string prop,size_t index=0){
if(customProps->HasProperty(prop)) return float((*customProps)[prop].GetReal(index));
else return float((*scriptProps)[prop].GetReal(index));
};
std::string ItemProps::GetStringProp(std::string prop){
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetString();
else return (*scriptProps)[prop].GetString();
std::string ItemProps::GetStringProp(std::string prop,size_t index=0){
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetString(index);
else return (*scriptProps)[prop].GetString(index);
};
void ItemInfo::InitializeScripts(){
@ -222,6 +222,10 @@ void ItemInfo::InitializeScripts(){
game->GetPlayer()->RestoreMana(int(game->GetPlayer()->GetMaxMana()*props.GetIntProp("MP % Restore")/100.f));
return true;
};
ITEM_SCRIPTS["Buff"]=[](Crawler*game,ItemProps props){
game->GetPlayer()->AddBuff(BuffType::ATTACK_PCT_UP,props.GetFloatProp("Attack %",1),props.GetFloatProp("Attack %",0)/100);
return true;
};
ITEM_SCRIPTS.SetInitialized();
std::cout<<ITEM_SCRIPTS.size()<<" item scripts have been loaded."<<std::endl;
@ -234,6 +238,7 @@ Item::Item(uint32_t amt,IT item,uint8_t enhancementLevel)
:amt(amt),it(&ITEM_DATA.at(item)),enhancementLevel(enhancementLevel){}
void Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
if(!ITEM_DATA.count(it))ERR("Item "<<std::quoted(it)<<" does not exist in Item Database!");
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
if(!_inventory.count(it)){
_inventory[it]=Item{amt,it};
@ -654,4 +659,9 @@ const std::string Stats::GetStatsString(CompactText compact)const{
first=false;
}
return description;
}
ItemInfo&ItemInfo::operator[](const IT&item){
if(!ITEM_DATA.count(item))ERR("Item "<<std::quoted(item)<<" does not exist in the item database!");
return ITEM_DATA[item];
}

@ -199,9 +199,9 @@ class ItemProps{
utils::datafile*customProps;
public:
ItemProps(utils::datafile*scriptProps,utils::datafile*customProps);
int GetIntProp(std::string prop);
float GetFloatProp(std::string prop);
std::string GetStringProp(std::string prop);
int GetIntProp(std::string prop,size_t index);
float GetFloatProp(std::string prop,size_t index);
std::string GetStringProp(std::string prop,size_t index);
};
class ItemInfo{
@ -241,6 +241,7 @@ public:
float CooldownTime();
EquipSlot Slot();
const std::optional<const ::ItemSet *const>ItemSet()const;
ItemInfo&operator[](const IT&item);
};
class ItemOverlay{

@ -0,0 +1,98 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 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.
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 "Merchant.h"
std::map<Chapter,std::vector<Merchant>>Merchant::merchants;
const Merchant&Merchant::GetRandomMerchant(Chapter chapter)const{
return merchants[chapter][rand()%(merchants[chapter].size()-1)];
}
const std::string&Merchant::GetDisplayName()const{
return displayName;
}
const std::vector<Item>&Merchant::GetShopItems()const{
return shopItems;
}
Merchant&Merchant::AddMerchant(Chapter chapter){
merchants[chapter].push_back({});
return merchants[chapter].back();
}
void Merchant::AddItem(IT item,uint8_t enhancementLevel){
shopItems.push_back(Item{1,item,enhancementLevel});
}
INCLUDE_DATA
void Merchant::Initialize(){
for(int chapter=1;chapter<=6;chapter++){
std::string merchantChapterFilename="assets/"+"merchant_directory"_S+"Chapter "+std::to_string(chapter)+" Merchants.txt";
if(!std::filesystem::exists(merchantChapterFilename))ERR("WARNING! Could not find file "<<std::quoted(merchantChapterFilename)<<" for merchant reading!");
utils::datafile::Read(DATA,merchantChapterFilename);
}
for(int chapter=1;chapter<=6;chapter++){
int merchantCount=0;
utils::datafile&chapterMerchantInfo=DATA["Merchant"][std::format("Chapter {}",chapter)];
for(auto&[key,size]:chapterMerchantInfo){
utils::datafile&data=chapterMerchantInfo.GetProperty(key);
Merchant&newMerchant=AddMerchant(chapter);
for(int itemNumber=1;auto&[key,size]:data){
if(key=="DisplayName")newMerchant.displayName=data[key].GetString();
else
if(key.starts_with("Item[")){
std::string itemKey=std::format("Item[{}]",itemNumber);
if(data.HasProperty(itemKey)){
IT itemName=data[itemKey].GetString();
newMerchant.AddItem(itemName);
}else{
ERR("Could not find item "<<itemNumber<<" in Merchant "<<merchantCount<<" of Chapter "<<chapter<<"!");
}
itemNumber++;
}else{
ERR("Unhandled key "<<std::quoted(key)<<" inside of Merchant "<<merchantCount<<" of Chapter "<<chapter<<"!");
}
}
merchantCount++;
}
std::cout<<std::format("Added {} merchants to Chapter {}",merchantCount,chapter)<<std::endl;
}
}

@ -0,0 +1,56 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2018 - 2022 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.
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 "Crawler.h"
using Chapter=int;
class Merchant{
public:
const Merchant&GetRandomMerchant(Chapter chapter)const;
const std::string&GetDisplayName()const;
const std::vector<Item>&GetShopItems()const;
void AddItem(IT item,uint8_t enhancementLevel=0U);
public:
static void Initialize();
static Merchant&AddMerchant(Chapter chapter);
private:
static std::map<Chapter,std::vector<Merchant>>merchants;
std::string displayName;
std::vector<Item>shopItems;
};

@ -198,6 +198,9 @@ const int Player::GetAttack(){
for(Buff&b:GetBuffs(BuffType::ATTACK_UP)){
mod_atk+=GetStat(ItemAttribute::attack)*b.intensity;
}
for(Buff&b:GetBuffs(BuffType::ATTACK_PCT_UP)){
mod_atk+=GetStat(ItemAttribute::attack)*b.intensity;
}
return int(mod_atk);
}

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 4059
#define VERSION_BUILD 4086
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -25,7 +25,7 @@ Monsters
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Green Slime Remains,65%,1,2
DROP[1] = Small Health Potion,5%,1,1
DROP[1] = Minor Health Potion,5%,1,1
#Additional custom animations go down below. Start with ANIMATION[0]. Order is:
# Frame Count, Frame Speed (s), Frame Cycling (Repeat,OneShot,PingPong,Reverse)
@ -55,7 +55,7 @@ Monsters
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Blue Slime Remains,65%,1,2
DROP[1] = Small Health Potion,5%,1,1
DROP[1] = Minor Health Potion,5%,1,1
#Additional custom animations go down below. Start with ANIMATION[0]
#ANIMATION[0] = MY_NEW_ANIMATION
@ -84,7 +84,7 @@ Monsters
# Drop Item Name, Drop Percentage(0-100%), Drop Min Quantity, Drop Max Quantity
DROP[0] = Red Slime Remains,65%,1,2
DROP[1] = Small Health Potion,5%,1,1
DROP[1] = Minor Health Potion,5%,1,1
#Additional custom animations go down below. Start with ANIMATION[0]
#ANIMATION[0] = MY_NEW_ANIMATION

@ -63,6 +63,9 @@ story_background_image_location = backgrounds/
# The name substituted for the player in dialogs
story_player_name = You
# The path to the merchant configuration files in the game
merchant_directory = config/shops/
# Dialog font and size.
dialog_font_size = c64esque,12

@ -46,7 +46,7 @@ ItemDatabase
{
ItemScript = Buff
Description = Increase your attack by 15% for 30 seconds.
HP Restore = 15,30
Attack % = 15%,30
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0

@ -4,11 +4,22 @@ ItemScript
# Any of these properties can be overwritten by specifying them in the main item.
# Restores stats.
# Parameter 1: The amount to restore per tick. If parameter 2 is zero, restores this amount instantly.
# (Optional) Parameter 2: If non-zero, specifies the amount of time per tick of restoration.
# (Optional) Parameter 3: If non-zero, specifies the amount of time the restoration lasts.
Restore
{
HP Restore = 0
HP % Restore = 0
MP Restore = 0
MP % Restore = 0
HP Restore = 0,0.0,0.0
HP % Restore = 0,0.0,0.0
MP Restore = 0,0.0,0.0
MP % Restore = 0,0.0,0.0
}
# Provides Temporary Stat Boosts.
# Parameter 1: Amount to increase stat by.
# Parameter 2: Duration that this stat will be increased for.
Buff
{
Attack % = 0,0.0
}
}

@ -1,26 +1,29 @@
Merchant
{
Chapter1_A
Chapter 1
{
DisplayName = Merchant
Item[1] = Minor Health Potion
Item[2] = Minor Mana Potion
}
Chapter1_B
{
DisplayName = Merchant
Item[1] = Minor Health Potion
}
Chapter1_C
{
DisplayName = Merchant
Item[1] = Minor Mana Potion
}
Chapter1_D
{
DisplayName = Merchant
Item[1] = Minor Health Potion
Item[2] = Minor Mana Potion
Item[3] = Bandages
Chapter1_A
{
DisplayName = Merchant
Item[1] = Minor Health Potion
Item[2] = Minor Mana Potion
}
Chapter1_B
{
DisplayName = Merchant
Item[1] = Minor Health Potion
}
Chapter1_C
{
DisplayName = Merchant
Item[1] = Minor Mana Potion
}
Chapter1_D
{
DisplayName = Merchant
Item[1] = Minor Health Potion
Item[2] = Minor Mana Potion
Item[3] = Bandages
}
}
}

@ -130,12 +130,12 @@ namespace olc::utils
return m_vContent.size();
}
inline std::vector<std::string> GetValues() const
inline const std::vector<std::string>&GetValues()
{
return m_vContent;
}
inline std::unordered_map<std::string,size_t> GetKeys() const{
inline const std::unordered_map<std::string,size_t>&GetKeys(){
return m_mapObjects;
}
@ -458,6 +458,13 @@ namespace olc::utils
return m_vecObjects[m_mapObjects[name]].second;
}
inline auto begin(){
return GetKeys().begin();
}
inline auto end(){
return GetKeys().end();
}
private:
// The "list of strings" that make up a property value
std::vector<std::string> m_vContent;
@ -484,7 +491,7 @@ namespace olc::utils
std::string operator[](int index){return data.get().GetProperty(key).GetString(index);};
inline std::string concat(){
std::string finalStr="";
for(std::string&str:data.get().GetProperty(key).GetValues()){
for(const std::string&str:data.get().GetProperty(key).GetValues()){
if(finalStr.length()>0)finalStr+=", ";
finalStr+=str;
}

Loading…
Cancel
Save