The open source repository for the action RPG game in development by Sig Productions titled 'Adventures in Lestoria'! https://forums.lestoria.net
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdventuresInLestoria/Crawler/Item.cpp

179 lines
5.3 KiB

#pragma once
#include "Item.h"
#include "safemap.h"
#include "DEFINES.h"
#include "Crawler.h"
INCLUDE_game
INCLUDE_DATA
INCLUDE_GFX
safemap<std::string,ItemInfo>ITEM_DATA;
safemap<std::string,ItemScript>ITEM_SCRIPTS;
safemap<std::string,std::set<std::string>>ITEM_CATEGORIES;
ItemInfo::ItemInfo()
:customProps({nullptr,nullptr}),img(nullptr){}
void ItemInfo::InitializeItems(){
InitializeScripts();
for(auto&key:DATA["ItemCategory"].GetKeys()){
ITEM_CATEGORIES[key.first];
}
for(auto&key:DATA["ItemDatabase"].GetKeys()){
std::string imgPath="assets/"+"item_img_directory"_S+key.first+".png";
Renderable&img=GFX["item_img_directory"_S+key.first+".png"];
img.Load(imgPath);
std::string scriptName="",description="",category="";
for(auto&itemKey:DATA["ItemDatabase"][key.first].GetKeys()){
std::string keyName=itemKey.first;
if(keyName=="Description"){
description=DATA["ItemDatabase"][key.first][keyName].GetString();
}else
if(keyName=="ItemCategory"){
category=DATA["ItemDatabase"][key.first][keyName].GetString();
}else
if(keyName=="ItemScript"){
scriptName=DATA["ItemDatabase"][key.first][keyName].GetString();
}else{ //THis is a custom override modifier for a script. NO-OP
}
}
if(scriptName!=""){
if(!ITEM_SCRIPTS.count(scriptName)){
std::cout<<"Could not load script "<<scriptName<<" for Item "<<key.first<<"!"<<std::endl;
throw;
}
}
ItemInfo&it=ITEM_DATA[key.first];
it.name=key.first;
it.description=description;
it.category=category;
if(!ITEM_CATEGORIES.count(it.category)){
std::cout<<"WARNING! Tried to add item "<<it.name<<" to category "<<it.category<<" which does not exist!"<<std::endl;
throw;
}
ITEM_CATEGORIES.at(it.category).insert(it.name);
it.img=img.Decal();
ItemProps&props=it.customProps;
if(scriptName!=""){
props.scriptProps=&DATA["ItemScript"][scriptName];
props.customProps=&DATA["ItemDatabase"][key.first];
}
it.useFunc=scriptName;
}
ITEM_DATA.SetInitialized();
ITEM_CATEGORIES.SetInitialized();
std::cout<<ITEM_DATA.size()<<" items have been loaded."<<std::endl;
std::cout<<ITEM_CATEGORIES.size()<<" item categories have been loaded."<<std::endl;
}
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();
};
float ItemProps::GetFloatProp(std::string prop){
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetReal();
else return (*scriptProps)[prop].GetReal();
};
std::string ItemProps::GetStringProp(std::string prop){
if(customProps->HasProperty(prop)) return (*customProps)[prop].GetString();
else return (*scriptProps)[prop].GetString();
};
void ItemInfo::InitializeScripts(){
ITEM_SCRIPTS["Restore"]=[](Crawler*game,ItemProps props){
game->GetPlayer()->Heal(props.GetIntProp("HP Restore"));
game->GetPlayer()->Heal(game->GetPlayer()->GetMaxHealth()*props.GetIntProp("HP % Restore")/100.f);
game->GetPlayer()->RestoreMana(props.GetIntProp("MP Restore"));
game->GetPlayer()->RestoreMana(game->GetPlayer()->GetMaxMana()*props.GetIntProp("MP % Restore")/100.f);
return true;
};
ITEM_SCRIPTS.SetInitialized();
std::cout<<ITEM_SCRIPTS.size()<<" item scripts have been loaded."<<std::endl;
}
Item::Item(uint32_t amt,IT item)
:amt(amt),it(&ITEM_DATA.at(item)){}
void Inventory::AddItem(IT it,int amt){
//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};
InsertIntoSortedInv(it);
}else{
_inventory.at(it).amt+=amt;
}
}
uint32_t Inventory::GetItemCount(IT it){
if(!_inventory.count(it)){
return 0;
}else{
return _inventory.at(it).Amt();
}
}
void Inventory::UseItem(IT it,int amt){
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
for(int i=0;i<amt;i++){
if(ExecuteAction(it)){
RemoveItem(it);
}
}
}
void Inventory::RemoveItem(IT it,int amt){
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
if(!_inventory.count(it))return;
if(amt>=_inventory.at(it).Amt()){
int count=0;
std::vector<IT>&sortedList=sortedInv.at(_inventory.at(it).Category());
for(std::string&itemName:sortedList){
if(itemName==it)break;
count++;
}
sortedList.erase(sortedList.begin()+count);
_inventory.erase(it);
}else{
_inventory.at(it).amt-=amt;
}
}
std::vector<IT>&Inventory::get(ITCategory itemCategory){
return sortedInv.at(itemCategory);
}
void Inventory::InsertIntoSortedInv(IT item){
sortedInv.at(ITEM_DATA[item].category).push_back(item);
}
bool Inventory::ExecuteAction(IT item){
return ITEM_SCRIPTS.at(ITEM_DATA.at(item).useFunc)(game,ITEM_DATA[item].customProps);
}
bool Inventory::SwapItems(IT it,IT it2){
ItemInfo&itemInfo1=ITEM_DATA.at(it);
ItemInfo&itemInfo2=ITEM_DATA.at(it2);
if(itemInfo1.category!=itemInfo2.category)return false;
ITCategory category=itemInfo1.category;
Item item1=GetItem(it);
Item item2=GetItem(it2);
if(item1.Amt()<=0&&item2.Amt()<=0)return false;
std::vector<IT>inv=sortedInv.at(category);
auto index1=std::find(inv.begin(),inv.end(),it);
auto index2=std::find(inv.begin(),inv.end(),it2);
std::swap(*index1,*index2);
return true;
}