Add player money functions. Implement Merchant transaction functions. Add Function Priming classes.
This commit is contained in:
parent
2b3c1ea1b4
commit
f1aa872717
@ -134,7 +134,7 @@ void Menu::InitializeCharacterMenuWindow(){
|
|||||||
ScrollableWindowComponent*equipList=Component<ScrollableWindowComponent>(data.component->parentMenu,"Equip List");
|
ScrollableWindowComponent*equipList=Component<ScrollableWindowComponent>(data.component->parentMenu,"Equip List");
|
||||||
equipList->RemoveAllComponents();
|
equipList->RemoveAllComponents();
|
||||||
for(int counter=0;Item&it:availableEquipment){
|
for(int counter=0;Item&it:availableEquipment){
|
||||||
Item&itemInvRef=Inventory::GetItem(it.Name());
|
Item&itemInvRef=Inventory::GetItem(it.ActualName());
|
||||||
auto equip=equipList->ADD("Equip Item "+std::to_string(counter),RowItemDisplay)({{2,2+counter*28.f},{120-15,28}},itemInvRef,
|
auto equip=equipList->ADD("Equip Item "+std::to_string(counter),RowItemDisplay)({{2,2+counter*28.f},{120-15,28}},itemInvRef,
|
||||||
[](MenuFuncData data){
|
[](MenuFuncData data){
|
||||||
RowItemDisplay*comp=dynamic_cast<RowItemDisplay*>(data.component);
|
RowItemDisplay*comp=dynamic_cast<RowItemDisplay*>(data.component);
|
||||||
|
@ -202,6 +202,10 @@ bool Crawler::OnUserCreate(){
|
|||||||
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
utils::datafile::INITIAL_SETUP_COMPLETE=true;
|
||||||
|
|
||||||
ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
|
ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
|
||||||
|
|
||||||
|
Merchant::RandomizeTravelingMerchant();
|
||||||
|
Merchant&myMerchant=Merchant::GetCurrentTravelingMerchant();
|
||||||
|
const std::vector<Item>&itemsAvailable=myMerchant.GetShopItems();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1725,6 +1729,7 @@ void Crawler::ChangePlayerClass(Class cl){
|
|||||||
Ability itemAbility1=player->useItem1;
|
Ability itemAbility1=player->useItem1;
|
||||||
Ability itemAbility2=player->useItem2;
|
Ability itemAbility2=player->useItem2;
|
||||||
Ability itemAbility3=player->useItem3;
|
Ability itemAbility3=player->useItem3;
|
||||||
|
uint32_t oldMoney=player->money;
|
||||||
switch(cl){
|
switch(cl){
|
||||||
case WARRIOR:{
|
case WARRIOR:{
|
||||||
player.reset(NEW Warrior(player.get()));
|
player.reset(NEW Warrior(player.get()));
|
||||||
@ -1750,6 +1755,7 @@ void Crawler::ChangePlayerClass(Class cl){
|
|||||||
player->SetBaseStat(ItemAttribute::attack,DATA.GetProperty(player->GetClassName()+".BaseAtk").GetInt());
|
player->SetBaseStat(ItemAttribute::attack,DATA.GetProperty(player->GetClassName()+".BaseAtk").GetInt());
|
||||||
player->hpGrowthRate=float(DATA.GetProperty(player->GetClassName()+".HealthGrowthRate").GetReal());
|
player->hpGrowthRate=float(DATA.GetProperty(player->GetClassName()+".HealthGrowthRate").GetReal());
|
||||||
player->atkGrowthRate=float(DATA.GetProperty(player->GetClassName()+".AtkGrowthRate").GetReal());
|
player->atkGrowthRate=float(DATA.GetProperty(player->GetClassName()+".AtkGrowthRate").GetReal());
|
||||||
|
player->money=oldMoney;
|
||||||
sig::Animation::SetupPlayerAnimations();
|
sig::Animation::SetupPlayerAnimations();
|
||||||
GetPlayer()->UpdateIdleAnimation(DOWN);
|
GetPlayer()->UpdateIdleAnimation(DOWN);
|
||||||
GetPlayer()->SetItem1UseFunc(itemAbility1);
|
GetPlayer()->SetItem1UseFunc(itemAbility1);
|
||||||
@ -2239,7 +2245,7 @@ void Crawler::SetLoadoutItem(int slot,std::string itemName){
|
|||||||
bool Crawler::UseLoadoutItem(int slot){
|
bool Crawler::UseLoadoutItem(int slot){
|
||||||
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
|
if(slot<0||slot>loadout.size()-1)ERR("Invalid inventory slot "+std::to_string(slot)+", please choose a slot in range (0-"+std::to_string(loadout.size()-1)+").");
|
||||||
if(GetLoadoutItem(slot).Amt()>0){
|
if(GetLoadoutItem(slot).Amt()>0){
|
||||||
Inventory::UseItem(loadout[slot].Name());
|
Inventory::UseItem(loadout[slot].ActualName());
|
||||||
GetLoadoutItem(slot).OnUseAction();
|
GetLoadoutItem(slot).OnUseAction();
|
||||||
GetLoadoutItem(slot).amt--;
|
GetLoadoutItem(slot).amt--;
|
||||||
return true;
|
return true;
|
||||||
|
@ -316,6 +316,10 @@
|
|||||||
</SubType>
|
</SubType>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Error.h" />
|
<ClInclude Include="Error.h" />
|
||||||
|
<ClInclude Include="FunctionPriming.h">
|
||||||
|
<SubType>
|
||||||
|
</SubType>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="GameState.h" />
|
<ClInclude Include="GameState.h" />
|
||||||
<ClInclude Include="Item.h" />
|
<ClInclude Include="Item.h" />
|
||||||
<ClInclude Include="ItemDrop.h">
|
<ClInclude Include="ItemDrop.h">
|
||||||
|
@ -309,6 +309,9 @@
|
|||||||
<ClInclude Include="Merchant.h">
|
<ClInclude Include="Merchant.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FunctionPriming.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Player.cpp">
|
<ClCompile Include="Player.cpp">
|
||||||
|
@ -52,7 +52,7 @@ public:
|
|||||||
inline void OnEquipStatsUpdate()override{
|
inline void OnEquipStatsUpdate()override{
|
||||||
Item&equip=*Inventory::GetEquip(slot);
|
Item&equip=*Inventory::GetEquip(slot);
|
||||||
if(!equip.IsBlank()){
|
if(!equip.IsBlank()){
|
||||||
icon=equip.Decal();
|
icon=const_cast<Decal*>(equip.Decal());
|
||||||
SetItem(equip);
|
SetItem(equip);
|
||||||
}else{
|
}else{
|
||||||
icon=nullptr;
|
icon=nullptr;
|
||||||
|
63
Crawler/FunctionPriming.h
Normal file
63
Crawler/FunctionPriming.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#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
|
||||||
|
#pragma once
|
||||||
|
#include "Error.h"
|
||||||
|
#include <format>
|
||||||
|
using IT=std::string;
|
||||||
|
|
||||||
|
struct FunctionPrimingData{
|
||||||
|
bool primed=false;
|
||||||
|
std::string dependentFunction="";
|
||||||
|
inline FunctionPrimingData(std::string dependentFunction)
|
||||||
|
:dependentFunction(dependentFunction){}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MerchantFunctionPrimingData:public FunctionPrimingData{
|
||||||
|
IT item="";
|
||||||
|
uint32_t amt=0;
|
||||||
|
inline MerchantFunctionPrimingData(std::string dependentFunction)
|
||||||
|
:FunctionPrimingData(dependentFunction){}
|
||||||
|
virtual inline void Validate(IT item,uint32_t amt)const{
|
||||||
|
if(!primed)ERR(std::format("WARNING! {} should be called before running this function! Priming Requirement!",dependentFunction));
|
||||||
|
if(this->item!=item)ERR(std::format("WARNING! Primed items are not matching! {}!={}",this->item,item));
|
||||||
|
if(this->amt!=amt)ERR(std::format("WARNING! Primed amounts are not matching! {}!={}",this->amt,amt));
|
||||||
|
}
|
||||||
|
inline bool operator=(bool rhs){
|
||||||
|
return primed=rhs;
|
||||||
|
}
|
||||||
|
};
|
@ -75,7 +75,7 @@ void Menu::InitializeConsumableInventoryWindow(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
button->selected=data.menu.I(A::LOADOUT_SLOT);
|
button->selected=data.menu.I(A::LOADOUT_SLOT);
|
||||||
data.game->SetLoadoutItem(button->selected,button->GetItem().Name());
|
data.game->SetLoadoutItem(button->selected,button->GetItem().ActualName());
|
||||||
return true;
|
return true;
|
||||||
})END;
|
})END;
|
||||||
|
|
||||||
|
111
Crawler/Item.cpp
111
Crawler/Item.cpp
@ -102,6 +102,8 @@ void ItemInfo::InitializeItems(){
|
|||||||
std::vector<std::string> slot;
|
std::vector<std::string> slot;
|
||||||
float cooldownTime="Item.Item Cooldown Time"_F;
|
float cooldownTime="Item.Item Cooldown Time"_F;
|
||||||
std::vector<ItemAttribute>statValueList;
|
std::vector<ItemAttribute>statValueList;
|
||||||
|
uint32_t sellValue=0;
|
||||||
|
uint32_t buyValue=0;
|
||||||
for(auto&[itemKey,itemValue]:data[key].GetKeys()){
|
for(auto&[itemKey,itemValue]:data[key].GetKeys()){
|
||||||
std::string keyName=itemKey;
|
std::string keyName=itemKey;
|
||||||
if(keyName=="Description"){
|
if(keyName=="Description"){
|
||||||
@ -131,6 +133,12 @@ void ItemInfo::InitializeItems(){
|
|||||||
}else
|
}else
|
||||||
if(keyName=="PartofSet"){
|
if(keyName=="PartofSet"){
|
||||||
setName=data[key][keyName].GetString();
|
setName=data[key][keyName].GetString();
|
||||||
|
}
|
||||||
|
if(keyName=="BuyValue"){
|
||||||
|
buyValue=data[key][keyName].GetInt();
|
||||||
|
}else
|
||||||
|
if(keyName=="SellValue"){
|
||||||
|
sellValue=data[key][keyName].GetInt();
|
||||||
}else{ //THis is a custom override modifier for a script. NO-OP
|
}else{ //THis is a custom override modifier for a script. NO-OP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,6 +170,8 @@ void ItemInfo::InitializeItems(){
|
|||||||
it.cooldownTime=cooldownTime;
|
it.cooldownTime=cooldownTime;
|
||||||
it.slot=EquipSlot::NONE;
|
it.slot=EquipSlot::NONE;
|
||||||
it.set=setName;
|
it.set=setName;
|
||||||
|
it.buyValue=buyValue;
|
||||||
|
it.sellValue=sellValue;
|
||||||
if(slot.size()>0){
|
if(slot.size()>0){
|
||||||
for(std::string&s:slot){
|
for(std::string&s:slot){
|
||||||
if(!nameToEquipSlot.count(s))ERR("WARNING! Tried to add item "<<it.name<<" to slot "<<s<<" which doesn't exist!");
|
if(!nameToEquipSlot.count(s))ERR("WARNING! Tried to add item "<<it.name<<" to slot "<<s<<" which doesn't exist!");
|
||||||
@ -294,7 +304,7 @@ bool Inventory::RemoveItem(IT it,ITCategory inventory,uint32_t amt){
|
|||||||
}
|
}
|
||||||
int count=0;
|
int count=0;
|
||||||
for(Item&item:inv){
|
for(Item&item:inv){
|
||||||
if(item.Name()==it)break;
|
if(item==it)break;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
@ -376,27 +386,31 @@ bool Inventory::SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Item::Amt(){
|
uint32_t Item::Amt()const{
|
||||||
return amt;
|
return amt;
|
||||||
};
|
};
|
||||||
std::string Item::Name(){
|
const std::string&Item::ActualName()const{
|
||||||
if(IsBlank())return "";
|
if(IsBlank())return "";
|
||||||
std::string name=it->Name();
|
return it->Name();
|
||||||
|
};
|
||||||
|
const std::string Item::DisplayName()const{
|
||||||
|
if(IsBlank())return "";
|
||||||
|
std::string name=ActualName();
|
||||||
if(IsEquippable()&&EnhancementLevel()>0){
|
if(IsEquippable()&&EnhancementLevel()>0){
|
||||||
name+=" [+"+std::to_string(EnhancementLevel())+"]";
|
name+=" [+"+std::to_string(EnhancementLevel())+"]";
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
};
|
}
|
||||||
bool Item::IsEquippable()const{
|
const bool Item::IsEquippable()const{
|
||||||
return Category()=="Equipment"||Category()=="Accessories";
|
return Category()=="Equipment"||Category()=="Accessories";
|
||||||
}
|
}
|
||||||
std::string Item::Description(CompactText compact){
|
const std::string Item::Description(CompactText compact)const{
|
||||||
std::string description=it->Description();
|
std::string description=it->Description();
|
||||||
if(IsEquippable()){
|
if(IsEquippable()){
|
||||||
description+='\n';
|
description+='\n';
|
||||||
description+=GetStats().GetStatsString(compact);
|
description+=GetStats().GetStatsString(compact);
|
||||||
if(ItemSet()){
|
if(ItemSet()){
|
||||||
const ::ItemSet*const set=ItemSet().value();
|
const::ItemSet*const set=ItemSet().value();
|
||||||
if(compact==COMPACT){
|
if(compact==COMPACT){
|
||||||
description+="\n"+set->GetSetName()+" Set - ";
|
description+="\n"+set->GetSetName()+" Set - ";
|
||||||
}else{
|
}else{
|
||||||
@ -424,48 +438,52 @@ std::string Item::Description(CompactText compact){
|
|||||||
const ITCategory Item::Category()const{
|
const ITCategory Item::Category()const{
|
||||||
return it->Category();
|
return it->Category();
|
||||||
};
|
};
|
||||||
::Decal*Item::Decal(){
|
const::Decal*const Item::Decal()const{
|
||||||
return it->Decal();
|
return it->Decal();
|
||||||
};
|
};
|
||||||
ItemScript&Item::OnUseAction(){
|
const ItemScript&Item::OnUseAction()const{
|
||||||
return it->OnUseAction();
|
return it->OnUseAction();
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string ItemInfo::Name(){
|
const std::string&ItemInfo::Name()const{
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
std::string ItemInfo::Description(){
|
const std::string&ItemInfo::Description()const{
|
||||||
return description;
|
return description;
|
||||||
};
|
};
|
||||||
ITCategory ItemInfo::Category(){
|
const ITCategory ItemInfo::Category()const{
|
||||||
return category;
|
return category;
|
||||||
};
|
};
|
||||||
::Decal*ItemInfo::Decal(){
|
const::Decal*const ItemInfo::Decal()const{
|
||||||
return img;
|
return img;
|
||||||
};
|
};
|
||||||
ItemScript&ItemInfo::OnUseAction(){
|
const ItemScript&ItemInfo::OnUseAction()const{
|
||||||
return ITEM_SCRIPTS.at(useFunc);
|
return ITEM_SCRIPTS.at(useFunc);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Item::IsBlank(){
|
const bool Item::IsBlank()const{
|
||||||
return amt==0||it==nullptr;
|
return amt==0||it==nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inventory::Clear(ITCategory itemCategory){
|
void Inventory::Clear(ITCategory itemCategory){
|
||||||
std::vector<Item>itemList=get(itemCategory); //We have to make a copy here because RemoveItem() will modify the list provided by get() inline.
|
std::vector<Item>itemList=get(itemCategory); //We have to make a copy here because RemoveItem() will modify the list provided by get() inline.
|
||||||
for(Item&item:itemList){
|
for(Item&item:itemList){
|
||||||
size_t itemQuantity=GetItemCount(item.Name());//Normally we want to clear all the items that are actually in our inventory...But...
|
size_t itemQuantity=GetItemCount(item.ActualName());//Normally we want to clear all the items that are actually in our inventory...But...
|
||||||
if(itemCategory=="Monster Loot"||itemCategory=="Stage Loot"){//These do not affect the actual inventory, we just clear the lists.
|
if(itemCategory=="Monster Loot"||itemCategory=="Stage Loot"){//These do not affect the actual inventory, we just clear the lists.
|
||||||
itemQuantity=item.Amt();
|
itemQuantity=item.Amt();
|
||||||
}
|
}
|
||||||
RemoveItem(item.Name(),itemCategory,uint32_t(itemQuantity));
|
RemoveItem(item.ActualName(),itemCategory,uint32_t(itemQuantity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Item::operator==(const Item&rhs)const{
|
const bool Item::operator==(const Item&rhs)const{
|
||||||
return it==rhs.it;
|
return it==rhs.it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool Item::operator==(const IT&rhs)const{
|
||||||
|
return it->Name()==rhs;
|
||||||
|
}
|
||||||
|
|
||||||
ItemOverlay::ItemOverlay(ItemInfo item)
|
ItemOverlay::ItemOverlay(ItemInfo item)
|
||||||
:it(item),width("ItemDrop.Item Drop Scale"_F*24+4+game->GetTextSizeProp(item.Name()).x*0.5f){
|
:it(item),width("ItemDrop.Item Drop Scale"_F*24+4+game->GetTextSizeProp(item.Name()).x*0.5f){
|
||||||
xOffset=-width;
|
xOffset=-width;
|
||||||
@ -487,7 +505,7 @@ void ItemOverlay::Draw(){
|
|||||||
Pixel lightCol=Menu::GetCurrentTheme().GetButtonCol()*1.2f;
|
Pixel lightCol=Menu::GetCurrentTheme().GetButtonCol()*1.2f;
|
||||||
game->GradientFillRectDecal(pos,{item.width,8},darkCol,darkCol,darkCol,lightCol);
|
game->GradientFillRectDecal(pos,{item.width,8},darkCol,darkCol,darkCol,lightCol);
|
||||||
game->DrawRectDecal(pos,{item.width,8},Menu::GetCurrentTheme().GetHighlightCol());
|
game->DrawRectDecal(pos,{item.width,8},Menu::GetCurrentTheme().GetHighlightCol());
|
||||||
game->DrawDecal(pos,item.it.Decal(),{itemScale,itemScale});
|
game->DrawDecal(pos,const_cast<Decal*>(item.it.Decal()),{itemScale,itemScale});
|
||||||
game->DrawShadowStringPropDecal(pos+vf2d{itemScale*24+2,2},item.it.Name(),WHITE,BLACK,{0.5f,0.7f});
|
game->DrawShadowStringPropDecal(pos+vf2d{itemScale*24+2,2},item.it.Name(),WHITE,BLACK,{0.5f,0.7f});
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
@ -498,11 +516,11 @@ void ItemOverlay::AddToItemOverlay(const ItemInfo&it){
|
|||||||
std::for_each(items.begin(),items.end(),[](ItemOverlay&it){it.ResetTimer();});
|
std::for_each(items.begin(),items.end(),[](ItemOverlay&it){it.ResetTimer();});
|
||||||
}
|
}
|
||||||
|
|
||||||
float ItemInfo::CastTime(){
|
const float ItemInfo::CastTime()const{
|
||||||
return castTime;
|
return castTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
float ItemInfo::CooldownTime(){
|
const float ItemInfo::CooldownTime()const{
|
||||||
return cooldownTime;
|
return cooldownTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,11 +528,11 @@ void ItemOverlay::ResetTimer(){
|
|||||||
timer=0;
|
timer=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Item::CastTime(){
|
const float Item::CastTime()const{
|
||||||
return it->CastTime();
|
return it->CastTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Item::CooldownTime(){
|
const float Item::CooldownTime()const{
|
||||||
return it->CooldownTime();
|
return it->CooldownTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +542,7 @@ const Stats&EnhancementInfo::operator[](int level)const{
|
|||||||
|
|
||||||
const std::optional<const ItemSet *const>ItemInfo::ItemSet()const{
|
const std::optional<const ItemSet *const>ItemInfo::ItemSet()const{
|
||||||
if(ItemSet::sets.count(set)){
|
if(ItemSet::sets.count(set)){
|
||||||
return &ItemSet::sets[set];
|
return &ItemSet::sets.at(set);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
@ -560,17 +578,17 @@ EquipSlot Inventory::GetSlotEquippedIn(Item&it){
|
|||||||
EquipSlot slot=EquipSlot(i);
|
EquipSlot slot=EquipSlot(i);
|
||||||
Item*equip=GetEquip(slot);
|
Item*equip=GetEquip(slot);
|
||||||
if(equip==nullptr)continue;
|
if(equip==nullptr)continue;
|
||||||
if(equip->Name()==it.Name())return slot;
|
if(equip->ActualName()==it.ActualName())return slot;
|
||||||
}
|
}
|
||||||
return EquipSlot::NONE;
|
return EquipSlot::NONE;
|
||||||
};
|
};
|
||||||
Item*Inventory::GetEquip(EquipSlot slot){
|
Item*Inventory::GetEquip(EquipSlot slot){
|
||||||
return Inventory::equipment[slot];
|
return Inventory::equipment[slot];
|
||||||
}
|
}
|
||||||
EquipSlot Item::GetEquipSlot(){
|
const EquipSlot Item::GetEquipSlot()const{
|
||||||
return it->Slot();
|
return it->Slot();
|
||||||
}
|
}
|
||||||
EquipSlot ItemInfo::Slot(){
|
const EquipSlot ItemInfo::Slot()const{
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +618,7 @@ void ItemInfo::InitializeSets(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stats ItemInfo::GetStats(int enhancementLevel){
|
const Stats&ItemInfo::GetStats(int enhancementLevel)const{
|
||||||
if(enhancement.size()<=enhancementLevel){
|
if(enhancement.size()<=enhancementLevel){
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -620,11 +638,11 @@ const std::optional<const ItemSet*const>Item::ItemSet()const{
|
|||||||
return it->ItemSet();
|
return it->ItemSet();
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t Item::EnhancementLevel()const{
|
const uint8_t Item::EnhancementLevel()const{
|
||||||
return enhancementLevel;
|
return enhancementLevel;
|
||||||
};
|
};
|
||||||
void Item::EnhanceItem(){
|
void Item::EnhanceItem(){
|
||||||
if(enhancementLevel+1>"Item.Item Max Enhancement Level"_I)ERR("WARNING! Attempted to enhance "<<Name()<<" beyond the cap of "<<"Item.Item Max Enhancement Level"_I);
|
if(enhancementLevel+1>"Item.Item Max Enhancement Level"_I)ERR("WARNING! Attempted to enhance "<<DisplayName()<<" beyond the cap of "<<"Item.Item Max Enhancement Level"_I);
|
||||||
enhancementLevel++;
|
enhancementLevel++;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -664,4 +682,35 @@ const std::string Stats::GetStatsString(CompactText compact)const{
|
|||||||
ItemInfo&ItemInfo::operator[](const IT&item){
|
ItemInfo&ItemInfo::operator[](const IT&item){
|
||||||
if(!ITEM_DATA.count(item))ERR("Item "<<std::quoted(item)<<" does not exist in the item database!");
|
if(!ITEM_DATA.count(item))ERR("Item "<<std::quoted(item)<<" does not exist in the item database!");
|
||||||
return ITEM_DATA[item];
|
return ITEM_DATA[item];
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t ItemInfo::GetBuyValue()const{
|
||||||
|
return buyValue;
|
||||||
|
}
|
||||||
|
const uint32_t ItemInfo::GetSellValue()const{
|
||||||
|
return sellValue;
|
||||||
|
}
|
||||||
|
const bool ItemInfo::CanBeSold()const{
|
||||||
|
return GetSellValue()>0;
|
||||||
|
}
|
||||||
|
const bool ItemInfo::CanBePurchased()const{
|
||||||
|
return GetBuyValue()>0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t Item::BuyValue()const{
|
||||||
|
return it->GetBuyValue();
|
||||||
|
}
|
||||||
|
const uint32_t Item::SellValue()const{
|
||||||
|
return it->GetSellValue();
|
||||||
|
}
|
||||||
|
const bool Item::CanBeSold()const{
|
||||||
|
return it->CanBeSold();
|
||||||
|
}
|
||||||
|
const bool Item::CanBePurchased()const{
|
||||||
|
return it->CanBePurchased();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item::SetAmt(uint32_t newAmt){
|
||||||
|
amt=newAmt;
|
||||||
}
|
}
|
@ -44,6 +44,7 @@ All rights reserved.
|
|||||||
#include "AttributableStat.h"
|
#include "AttributableStat.h"
|
||||||
#include "BitwiseEnum.h"
|
#include "BitwiseEnum.h"
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include "Merchant.h"
|
||||||
|
|
||||||
class Crawler;
|
class Crawler;
|
||||||
class ItemInfo;
|
class ItemInfo;
|
||||||
@ -129,31 +130,42 @@ class Item{
|
|||||||
friend class Inventory;
|
friend class Inventory;
|
||||||
friend class Crawler;
|
friend class Crawler;
|
||||||
friend class Menu;
|
friend class Menu;
|
||||||
|
friend void Merchant::PurchaseItem(IT item,uint32_t amt);
|
||||||
|
friend void Merchant::SellItem(IT item,uint32_t amt);
|
||||||
private:
|
private:
|
||||||
//The amount in the current item stack.
|
//The amount in the current item stack.
|
||||||
uint32_t amt;
|
uint32_t amt;
|
||||||
uint8_t enhancementLevel;
|
uint8_t enhancementLevel;
|
||||||
ItemInfo*it;
|
ItemInfo*it;
|
||||||
|
void SetAmt(uint32_t newAmt);
|
||||||
public:
|
public:
|
||||||
Item();
|
Item();
|
||||||
Item(uint32_t amt,IT item,uint8_t enhancementLevel=0);
|
Item(uint32_t amt,IT item,uint8_t enhancementLevel=0);
|
||||||
uint32_t Amt();
|
uint32_t Amt()const;
|
||||||
std::string Name();
|
//Use this for places where the item name is used for item tracking. NOT for drawing. Hooks directly into item info's base item name.
|
||||||
std::string Description(CompactText compact=COMPACT);
|
const std::string&ActualName()const;
|
||||||
|
//Use for places where the item name is actually displayed. Provides modified text that shows additional information like enhancement levels.
|
||||||
|
const std::string DisplayName()const;
|
||||||
|
const std::string Description(CompactText compact=COMPACT)const;
|
||||||
const ITCategory Category()const;
|
const ITCategory Category()const;
|
||||||
EquipSlot GetEquipSlot();
|
const EquipSlot GetEquipSlot()const;
|
||||||
::Decal*Decal();
|
const::Decal*const Decal()const;
|
||||||
const Stats GetStats()const;
|
const Stats GetStats()const;
|
||||||
ItemScript&OnUseAction();
|
const ItemScript&OnUseAction()const;
|
||||||
float CastTime();
|
const float CastTime()const;
|
||||||
float CooldownTime();
|
const float CooldownTime()const;
|
||||||
bool IsBlank();
|
const bool IsBlank()const;
|
||||||
uint8_t EnhancementLevel()const;
|
const uint8_t EnhancementLevel()const;
|
||||||
void EnhanceItem();
|
void EnhanceItem();
|
||||||
static Item BLANK;
|
static Item BLANK;
|
||||||
bool operator==(const Item&rhs)const;
|
const bool operator==(const Item&rhs)const;
|
||||||
|
const bool operator==(const IT&rhs)const;
|
||||||
const std::optional<const ::ItemSet *const>ItemSet()const;
|
const std::optional<const ::ItemSet *const>ItemSet()const;
|
||||||
bool IsEquippable()const;
|
const bool IsEquippable()const;
|
||||||
|
const uint32_t BuyValue()const;
|
||||||
|
const uint32_t SellValue()const;
|
||||||
|
const bool CanBeSold()const;
|
||||||
|
const bool CanBePurchased()const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Inventory{
|
class Inventory{
|
||||||
@ -220,7 +232,8 @@ class ItemInfo{
|
|||||||
//Custom properties for this specific item's script.
|
//Custom properties for this specific item's script.
|
||||||
static utils::datafile NOPROPS;
|
static utils::datafile NOPROPS;
|
||||||
ItemProps customProps;
|
ItemProps customProps;
|
||||||
|
uint32_t buyValue=0;
|
||||||
|
uint32_t sellValue=0;
|
||||||
private:
|
private:
|
||||||
static void InitializeScripts();
|
static void InitializeScripts();
|
||||||
static void InitializeSets();
|
static void InitializeSets();
|
||||||
@ -228,20 +241,24 @@ private:
|
|||||||
public:
|
public:
|
||||||
static void InitializeItems();
|
static void InitializeItems();
|
||||||
ItemInfo();
|
ItemInfo();
|
||||||
std::string Name();
|
const std::string&Name()const;
|
||||||
std::string Description();
|
const std::string&Description()const;
|
||||||
ITCategory Category();
|
const ITCategory Category()const;
|
||||||
::Decal*Decal();
|
const::Decal*const Decal()const;
|
||||||
/*
|
/*
|
||||||
For the useFunc, return true if the item can be used, false otherwise.
|
For the useFunc, return true if the item can be used, false otherwise.
|
||||||
*/
|
*/
|
||||||
ItemScript&OnUseAction();
|
const ItemScript&OnUseAction()const;
|
||||||
Stats GetStats(int enhancementLevel);
|
const Stats&GetStats(int enhancementLevel)const;
|
||||||
float CastTime();
|
const float CastTime()const;
|
||||||
float CooldownTime();
|
const float CooldownTime()const;
|
||||||
EquipSlot Slot();
|
const EquipSlot Slot()const;
|
||||||
const std::optional<const ::ItemSet *const>ItemSet()const;
|
const std::optional<const ::ItemSet *const>ItemSet()const;
|
||||||
ItemInfo&operator[](const IT&item);
|
ItemInfo&operator[](const IT&item);
|
||||||
|
const uint32_t GetBuyValue()const;
|
||||||
|
const uint32_t GetSellValue()const;
|
||||||
|
const bool CanBeSold()const;
|
||||||
|
const bool CanBePurchased()const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ItemOverlay{
|
class ItemOverlay{
|
||||||
|
@ -78,9 +78,9 @@ void ItemDrop::Draw(){
|
|||||||
yOffset=sin((game->levelTime+randomSpinOffset)*3)*0.5f;
|
yOffset=sin((game->levelTime+randomSpinOffset)*3)*0.5f;
|
||||||
}
|
}
|
||||||
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()+yOffset},GFX["skill_overlay_icon_overlay.png"].Decal(),0,GFX["skill_overlay_icon_overlay.png"].Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F},YELLOW);
|
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()+yOffset},GFX["skill_overlay_icon_overlay.png"].Decal(),0,GFX["skill_overlay_icon_overlay.png"].Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F},YELLOW);
|
||||||
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()+yOffset},item->Decal(),0,item->Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F},{255,255,255,128});
|
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()+yOffset},const_cast<Decal*>(item->Decal()),0,item->Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F},{255,255,255,128});
|
||||||
game->SetDecalMode(DecalMode::ADDITIVE);
|
game->SetDecalMode(DecalMode::ADDITIVE);
|
||||||
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()+yOffset},item->Decal(),0,item->Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F},{uint8_t(abs(sin(game->levelTime*1.5)*255.f)),uint8_t(abs(sin(game->levelTime*1.5)*255.f)),uint8_t(abs(sin(game->levelTime*1.5)*255.f)),128});
|
game->view.DrawRotatedDecal(pos-vf2d{0,GetZ()+yOffset},const_cast<Decal*>(item->Decal()),0,item->Decal()->sprite->Size()/2,{"ItemDrop.Item Drop Scale"_F,"ItemDrop.Item Drop Scale"_F},{uint8_t(abs(sin(game->levelTime*1.5)*255.f)),uint8_t(abs(sin(game->levelTime*1.5)*255.f)),uint8_t(abs(sin(game->levelTime*1.5)*255.f)),128});
|
||||||
game->SetDecalMode(DecalMode::NORMAL);
|
game->SetDecalMode(DecalMode::NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,12 +60,12 @@ private:
|
|||||||
public:
|
public:
|
||||||
int selected=-1; //0-2 representing which loadout slot this item consumes. -1 means not selected.
|
int selected=-1; //0-2 representing which loadout slot this item consumes. -1 means not selected.
|
||||||
inline MenuItemButton(geom2d::rect<float>rect,std::vector<Item>&invRef,int invIndex,MenuFunc onClick,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
inline MenuItemButton(geom2d::rect<float>rect,std::vector<Item>&invRef,int invIndex,MenuFunc onClick,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
||||||
:MenuIconButton(rect,invRef.size()>invIndex?invRef[invIndex].Decal():nullptr,onClick,attributes),invRef(invRef),inventoryIndex(invIndex),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
:MenuIconButton(rect,invRef.size()>invIndex?const_cast<Decal*>(invRef[invIndex].Decal()):nullptr,onClick,attributes),invRef(invRef),inventoryIndex(invIndex),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
||||||
draggable=false;
|
draggable=false;
|
||||||
valid=invRef.size()>invIndex;
|
valid=invRef.size()>invIndex;
|
||||||
}
|
}
|
||||||
inline MenuItemButton(geom2d::rect<float>rect,std::vector<Item>&invRef,int invIndex,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
inline MenuItemButton(geom2d::rect<float>rect,std::vector<Item>&invRef,int invIndex,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut,MenuType itemDescriptionMenu,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
||||||
:MenuIconButton(rect,invRef.size()>invIndex?invRef[invIndex].Decal():nullptr,onClick,attributes),invRef(invRef),inventoryIndex(invIndex),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
:MenuIconButton(rect,invRef.size()>invIndex?const_cast<Decal*>(invRef[invIndex].Decal()):nullptr,onClick,attributes),invRef(invRef),inventoryIndex(invIndex),itemDescriptionMenu(itemDescriptionMenu),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
||||||
draggable=false;
|
draggable=false;
|
||||||
runHoverFunctions=true;
|
runHoverFunctions=true;
|
||||||
valid=invRef.size()>invIndex;
|
valid=invRef.size()>invIndex;
|
||||||
@ -73,12 +73,12 @@ public:
|
|||||||
SetMouseOutFunc(onMouseOut);
|
SetMouseOutFunc(onMouseOut);
|
||||||
}
|
}
|
||||||
inline Item&GetItem(){
|
inline Item&GetItem(){
|
||||||
return Inventory::GetItem(invRef.at(inventoryIndex).Name());
|
return Inventory::GetItem(invRef.at(inventoryIndex).ActualName());
|
||||||
}
|
}
|
||||||
//Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
|
//Returns true if the item has been consumed completely and there are 0 remaining of that type in our inventory.
|
||||||
inline bool UseItem(uint32_t amt=1){
|
inline bool UseItem(uint32_t amt=1){
|
||||||
if(invRef.size()<=inventoryIndex)return false;
|
if(invRef.size()<=inventoryIndex)return false;
|
||||||
return Inventory::UseItem(invRef.at(inventoryIndex).Name(),amt);
|
return Inventory::UseItem(invRef.at(inventoryIndex).ActualName(),amt);
|
||||||
}
|
}
|
||||||
inline void SetCompactDescriptions(bool compact){
|
inline void SetCompactDescriptions(bool compact){
|
||||||
if(compact)this->compact=COMPACT;
|
if(compact)this->compact=COMPACT;
|
||||||
@ -98,8 +98,8 @@ protected:
|
|||||||
std::string labelNameText;
|
std::string labelNameText;
|
||||||
std::string labelDescriptionText;
|
std::string labelDescriptionText;
|
||||||
if(valid){
|
if(valid){
|
||||||
icon=invRef[inventoryIndex].Decal();
|
icon=const_cast<Decal*>(invRef[inventoryIndex].Decal());
|
||||||
labelNameText=invRef[inventoryIndex].Name();
|
labelNameText=invRef[inventoryIndex].DisplayName();
|
||||||
labelDescriptionText=invRef[inventoryIndex].Description(compact);
|
labelDescriptionText=invRef[inventoryIndex].Description(compact);
|
||||||
}else{
|
}else{
|
||||||
icon=nullptr;
|
icon=nullptr;
|
||||||
@ -120,7 +120,7 @@ protected:
|
|||||||
}
|
}
|
||||||
virtual inline void Update(Crawler*game)override{
|
virtual inline void Update(Crawler*game)override{
|
||||||
MenuIconButton::Update(game);
|
MenuIconButton::Update(game);
|
||||||
valid=invRef.size()>inventoryIndex&&ITEM_DATA.count(invRef[inventoryIndex].Name());
|
valid=invRef.size()>inventoryIndex&&ITEM_DATA.count(invRef[inventoryIndex].ActualName());
|
||||||
|
|
||||||
if(hovered){
|
if(hovered){
|
||||||
UpdateLabel();
|
UpdateLabel();
|
||||||
@ -132,7 +132,7 @@ protected:
|
|||||||
drawutil::DrawCrosshairDecalViewPort(window,{rect.pos,rect.size},0);
|
drawutil::DrawCrosshairDecalViewPort(window,{rect.pos,rect.size},0);
|
||||||
}
|
}
|
||||||
if(valid){
|
if(valid){
|
||||||
int itemQuantity=Inventory::GetItemCount(invRef.at(inventoryIndex).Name()); //Normally we'd retrieve how many of this item we have from our inventory...However Monster Loot and Stage Loot inventories are special and hold their own inventory counts...
|
int itemQuantity=Inventory::GetItemCount(invRef.at(inventoryIndex).ActualName()); //Normally we'd retrieve how many of this item we have from our inventory...However Monster Loot and Stage Loot inventories are special and hold their own inventory counts...
|
||||||
if(&invRef==&Inventory::get("Monster Loot")||&invRef==&Inventory::get("Stage Loot")){
|
if(&invRef==&Inventory::get("Monster Loot")||&invRef==&Inventory::get("Stage Loot")){
|
||||||
itemQuantity=invRef.at(inventoryIndex).Amt(); //So the item quantity comes from the stack itself and not our main inventory.
|
itemQuantity=invRef.at(inventoryIndex).Amt(); //So the item quantity comes from the stack itself and not our main inventory.
|
||||||
}
|
}
|
||||||
|
@ -57,12 +57,12 @@ private:
|
|||||||
CompactText compact=COMPACT;
|
CompactText compact=COMPACT;
|
||||||
public:
|
public:
|
||||||
inline MenuItemItemButton(geom2d::rect<float>rect,Item&itemRef,MenuType menuDest,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
inline MenuItemItemButton(geom2d::rect<float>rect,Item&itemRef,MenuType menuDest,MenuFunc onClick,std::string itemNameLabelName,std::string itemDescriptionLabelName,IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
||||||
:MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
:MenuIconButton(rect,(!itemRef.IsBlank())?const_cast<Decal*>(itemRef.Decal()):nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
||||||
draggable=false;
|
draggable=false;
|
||||||
valid=!itemRef.IsBlank();
|
valid=!itemRef.IsBlank();
|
||||||
}
|
}
|
||||||
inline MenuItemItemButton(geom2d::rect<float>rect,Item&itemRef,MenuType menuDest,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut,std::string itemNameLabelName="",std::string itemDescriptionLabelName="",IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
inline MenuItemItemButton(geom2d::rect<float>rect,Item&itemRef,MenuType menuDest,MenuFunc onClick,MenuFunc onHover,MenuFunc onMouseOut,std::string itemNameLabelName="",std::string itemDescriptionLabelName="",IconButtonAttr attributes=IconButtonAttr::SELECTABLE)
|
||||||
:MenuIconButton(rect,(!itemRef.IsBlank())?itemRef.Decal():nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
:MenuIconButton(rect,(!itemRef.IsBlank())?const_cast<Decal*>(itemRef.Decal()):nullptr,menuDest,onClick,attributes),itemRef(itemRef),itemNameLabelName(itemNameLabelName),itemDescriptionLabelName(itemDescriptionLabelName){
|
||||||
runHoverFunctions=true;
|
runHoverFunctions=true;
|
||||||
draggable=false;
|
draggable=false;
|
||||||
valid=!itemRef.IsBlank();
|
valid=!itemRef.IsBlank();
|
||||||
@ -87,7 +87,7 @@ public:
|
|||||||
icon=nullptr;
|
icon=nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
icon=itemRef.get().Decal();
|
icon=const_cast<Decal*>(itemRef.get().Decal());
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
virtual inline void OnMouseOut()override{
|
virtual inline void OnMouseOut()override{
|
||||||
@ -112,8 +112,8 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
icon=itemRef.get().Decal();
|
icon=const_cast<Decal*>(itemRef.get().Decal());
|
||||||
labelNameText=itemRef.get().Name();
|
labelNameText=itemRef.get().DisplayName();
|
||||||
labelDescriptionText=itemRef.get().Description(compact);
|
labelDescriptionText=itemRef.get().Description(compact);
|
||||||
if(itemNameLabelName!=""){
|
if(itemNameLabelName!=""){
|
||||||
Component<MenuLabel>(parentMenu,itemNameLabelName)->label=labelNameText;
|
Component<MenuLabel>(parentMenu,itemNameLabelName)->label=labelNameText;
|
||||||
|
@ -37,10 +37,16 @@ All rights reserved.
|
|||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#include "Merchant.h"
|
#include "Merchant.h"
|
||||||
|
#include "Crawler.h"
|
||||||
|
|
||||||
|
INCLUDE_game
|
||||||
|
|
||||||
std::map<Chapter,std::vector<Merchant>>Merchant::merchants;
|
std::map<Chapter,std::vector<Merchant>>Merchant::merchants;
|
||||||
|
MerchantFunctionPrimingData Merchant::purchaseFunctionPrimed("CanPurchaseItem()");
|
||||||
|
MerchantFunctionPrimingData Merchant::sellFunctionPrimed("CanSellItem()");
|
||||||
|
Merchant Merchant::travelingMerchant;
|
||||||
|
|
||||||
const Merchant&Merchant::GetRandomMerchant(Chapter chapter)const{
|
const Merchant&Merchant::GetRandomMerchant(Chapter chapter){
|
||||||
return merchants[chapter][rand()%(merchants[chapter].size()-1)];
|
return merchants[chapter][rand()%(merchants[chapter].size()-1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +63,8 @@ Merchant&Merchant::AddMerchant(Chapter chapter){
|
|||||||
return merchants[chapter].back();
|
return merchants[chapter].back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Merchant::AddItem(IT item,uint8_t enhancementLevel){
|
void Merchant::AddItem(IT item,uint32_t amt,uint8_t enhancementLevel){
|
||||||
shopItems.push_back(Item{1,item,enhancementLevel});
|
shopItems.push_back(Item{amt,item,enhancementLevel});
|
||||||
}
|
}
|
||||||
|
|
||||||
INCLUDE_DATA
|
INCLUDE_DATA
|
||||||
@ -82,7 +88,12 @@ void Merchant::Initialize(){
|
|||||||
std::string itemKey=std::format("Item[{}]",itemNumber);
|
std::string itemKey=std::format("Item[{}]",itemNumber);
|
||||||
if(data.HasProperty(itemKey)){
|
if(data.HasProperty(itemKey)){
|
||||||
IT itemName=data[itemKey].GetString();
|
IT itemName=data[itemKey].GetString();
|
||||||
newMerchant.AddItem(itemName);
|
if(data[itemKey].GetValueCount()>1){
|
||||||
|
int qty=data[itemKey].GetInt(1);
|
||||||
|
newMerchant.AddItem(itemName,qty);
|
||||||
|
}else{
|
||||||
|
newMerchant.AddItem(itemName,INFINITE);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
ERR("Could not find item "<<itemNumber<<" in Merchant "<<merchantCount<<" of Chapter "<<chapter<<"!");
|
ERR("Could not find item "<<itemNumber<<" in Merchant "<<merchantCount<<" of Chapter "<<chapter<<"!");
|
||||||
}
|
}
|
||||||
@ -95,4 +106,81 @@ void Merchant::Initialize(){
|
|||||||
}
|
}
|
||||||
std::cout<<std::format("Added {} merchants to Chapter {}",merchantCount,chapter)<<std::endl;
|
std::cout<<std::format("Added {} merchants to Chapter {}",merchantCount,chapter)<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool Merchant::CanPurchaseItem(IT item,uint32_t amt)const{
|
||||||
|
bool itemAvailable=false;
|
||||||
|
const Item*foundItem=nullptr;
|
||||||
|
for(const Item&it:shopItems){
|
||||||
|
if(it==item&&it.Amt()>=amt&&it.CanBePurchased()){
|
||||||
|
itemAvailable=true;
|
||||||
|
foundItem=⁢
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
purchaseFunctionPrimed.amt=amt;
|
||||||
|
purchaseFunctionPrimed.item=item;
|
||||||
|
return purchaseFunctionPrimed=
|
||||||
|
itemAvailable&&
|
||||||
|
foundItem!=nullptr&&
|
||||||
|
game->GetPlayer()->GetMoney()>=foundItem->BuyValue()*amt;
|
||||||
|
};
|
||||||
|
bool Merchant::CanSellItem(IT item,uint32_t amt)const{
|
||||||
|
ItemInfo&it=ITEM_DATA[item];
|
||||||
|
|
||||||
|
sellFunctionPrimed.amt=amt;
|
||||||
|
sellFunctionPrimed.item=item;
|
||||||
|
return sellFunctionPrimed=
|
||||||
|
it.CanBeSold()&&
|
||||||
|
Inventory::GetItemCount(item)>=amt;
|
||||||
|
};
|
||||||
|
void Merchant::PurchaseItem(IT item,uint32_t amt){
|
||||||
|
purchaseFunctionPrimed.Validate(item,amt);
|
||||||
|
|
||||||
|
uint32_t totalCost=0U;
|
||||||
|
for(Item&it:shopItems){
|
||||||
|
if(it==item){
|
||||||
|
if(it.Amt()!=INFINITE){
|
||||||
|
it.SetAmt(it.Amt()-amt);
|
||||||
|
}
|
||||||
|
totalCost=it.BuyValue()*amt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Inventory::AddItem(item,amt);
|
||||||
|
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-totalCost);
|
||||||
|
|
||||||
|
purchaseFunctionPrimed=false;
|
||||||
|
};
|
||||||
|
void Merchant::SellItem(IT item,uint32_t amt){
|
||||||
|
sellFunctionPrimed.Validate(item,amt);
|
||||||
|
|
||||||
|
uint32_t totalCost=0U;
|
||||||
|
bool itemFound=false;
|
||||||
|
for(Item&it:shopItems){
|
||||||
|
if(it==item){
|
||||||
|
if(it.Amt()!=INFINITE){
|
||||||
|
it.SetAmt(it.Amt()+amt);
|
||||||
|
}
|
||||||
|
itemFound=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!itemFound){
|
||||||
|
AddItem(item);
|
||||||
|
}
|
||||||
|
totalCost=ITEM_DATA[item].GetSellValue()*amt;
|
||||||
|
|
||||||
|
Inventory::RemoveItem(item,amt);
|
||||||
|
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()+totalCost);
|
||||||
|
|
||||||
|
sellFunctionPrimed=false;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Merchant::RandomizeTravelingMerchant(){
|
||||||
|
travelingMerchant=GetRandomMerchant(game->GetCurrentChapter());
|
||||||
|
};
|
||||||
|
Merchant&Merchant::GetCurrentTravelingMerchant(){
|
||||||
|
return travelingMerchant;
|
||||||
|
};
|
@ -35,21 +35,33 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
|||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
#pragma once
|
||||||
#include "Crawler.h"
|
#include "olcPixelGameEngine.h"
|
||||||
|
#include "FunctionPriming.h"
|
||||||
|
class Item;
|
||||||
|
|
||||||
using Chapter=int;
|
using Chapter=int;
|
||||||
|
using IT=std::string;
|
||||||
|
|
||||||
class Merchant{
|
class Merchant{
|
||||||
public:
|
public:
|
||||||
const Merchant&GetRandomMerchant(Chapter chapter)const;
|
static void RandomizeTravelingMerchant();
|
||||||
|
static Merchant&GetCurrentTravelingMerchant();
|
||||||
const std::string&GetDisplayName()const;
|
const std::string&GetDisplayName()const;
|
||||||
const std::vector<Item>&GetShopItems()const;
|
const std::vector<Item>&GetShopItems()const;
|
||||||
void AddItem(IT item,uint8_t enhancementLevel=0U);
|
void AddItem(IT item,uint32_t amt=1,uint8_t enhancementLevel=0U);
|
||||||
|
bool CanPurchaseItem(IT item,uint32_t amt=1U)const;
|
||||||
|
bool CanSellItem(IT item,uint32_t amt=1U)const;
|
||||||
|
void PurchaseItem(IT item,uint32_t amt=1U);
|
||||||
|
void SellItem(IT item,uint32_t amt=1U);
|
||||||
public:
|
public:
|
||||||
static void Initialize();
|
static void Initialize();
|
||||||
static Merchant&AddMerchant(Chapter chapter);
|
static Merchant&AddMerchant(Chapter chapter);
|
||||||
private:
|
private:
|
||||||
|
static MerchantFunctionPrimingData purchaseFunctionPrimed;
|
||||||
|
static MerchantFunctionPrimingData sellFunctionPrimed;
|
||||||
|
static Merchant travelingMerchant;
|
||||||
|
static const Merchant&GetRandomMerchant(Chapter chapter);
|
||||||
static std::map<Chapter,std::vector<Merchant>>merchants;
|
static std::map<Chapter,std::vector<Merchant>>merchants;
|
||||||
std::string displayName;
|
std::string displayName;
|
||||||
std::vector<Item>shopItems;
|
std::vector<Item>shopItems;
|
||||||
|
@ -908,4 +908,11 @@ void Player::SetBaseStat(ItemAttribute a,int val){
|
|||||||
|
|
||||||
const std::string&ItemSet::GetSetName()const{
|
const std::string&ItemSet::GetSetName()const{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Player::GetMoney()const{
|
||||||
|
return money;
|
||||||
|
};
|
||||||
|
void Player::SetMoney(uint32_t newMoney){
|
||||||
|
money=newMoney;
|
||||||
|
};
|
@ -115,6 +115,7 @@ private:
|
|||||||
Ability useItem1;
|
Ability useItem1;
|
||||||
Ability useItem2;
|
Ability useItem2;
|
||||||
Ability useItem3;
|
Ability useItem3;
|
||||||
|
uint32_t money=9999;
|
||||||
protected:
|
protected:
|
||||||
const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F;
|
const float ATTACK_COOLDOWN="Warrior.Auto Attack.Cooldown"_F;
|
||||||
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;
|
const float MAGIC_ATTACK_COOLDOWN="Wizard.Auto Attack.Cooldown"_F;
|
||||||
@ -251,6 +252,9 @@ public:
|
|||||||
void SetItem3UseFunc(Ability a);
|
void SetItem3UseFunc(Ability a);
|
||||||
|
|
||||||
static InputGroup KEY_ABILITY1, KEY_ABILITY2, KEY_ABILITY3, KEY_ABILITY4, KEY_DEFENSIVE, KEY_ITEM1, KEY_ITEM2, KEY_ITEM3;
|
static InputGroup KEY_ABILITY1, KEY_ABILITY2, KEY_ABILITY3, KEY_ABILITY4, KEY_DEFENSIVE, KEY_ITEM1, KEY_ITEM2, KEY_ITEM3;
|
||||||
|
|
||||||
|
uint32_t GetMoney()const;
|
||||||
|
void SetMoney(uint32_t newMoney);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Warrior:Player{
|
struct Warrior:Player{
|
||||||
|
@ -57,10 +57,10 @@ public:
|
|||||||
MenuComponent::DrawDecal(window,focused);
|
MenuComponent::DrawDecal(window,focused);
|
||||||
float scaleFactor=(rect.size.y-4)/24;
|
float scaleFactor=(rect.size.y-4)/24;
|
||||||
vf2d iconSize=vf2d{scaleFactor,scaleFactor}*24.f;
|
vf2d iconSize=vf2d{scaleFactor,scaleFactor}*24.f;
|
||||||
window.DrawDecal(rect.pos+vf2d{2,2},itemRef.get().Decal(),{scaleFactor,scaleFactor});
|
window.DrawDecal(rect.pos+vf2d{2,2},const_cast<Decal*>(itemRef.get().Decal()),{scaleFactor,scaleFactor});
|
||||||
window.DrawRectDecal(rect.pos+vf2d{2,2},iconSize);
|
window.DrawRectDecal(rect.pos+vf2d{2,2},iconSize);
|
||||||
|
|
||||||
std::string itemName=itemRef.get().Name();
|
std::string itemName=itemRef.get().DisplayName();
|
||||||
vf2d scaledSize={std::min(1.f,(rect.size.x-6-iconSize.x)/game->GetTextSizeProp(itemName).x),1};
|
vf2d scaledSize={std::min(1.f,(rect.size.x-6-iconSize.x)/game->GetTextSizeProp(itemName).x),1};
|
||||||
|
|
||||||
window.DrawShadowStringPropDecal(rect.pos+vf2d{4,4}+vf2d{iconSize.x,iconSize.y/2-4},itemName,WHITE,BLACK,scaledSize);
|
window.DrawShadowStringPropDecal(rect.pos+vf2d{4,4}+vf2d{iconSize.x,iconSize.y/2-4},itemName,WHITE,BLACK,scaledSize);
|
||||||
@ -109,7 +109,7 @@ public:
|
|||||||
std::string labelNameText;
|
std::string labelNameText;
|
||||||
std::string labelDescriptionText;
|
std::string labelDescriptionText;
|
||||||
if(valid){
|
if(valid){
|
||||||
labelNameText=itemRef.get().Name();
|
labelNameText=itemRef.get().DisplayName();
|
||||||
labelDescriptionText=itemRef.get().Description(compact);
|
labelDescriptionText=itemRef.get().Description(compact);
|
||||||
}else{
|
}else{
|
||||||
labelNameText="";
|
labelNameText="";
|
||||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
|||||||
#define VERSION_MAJOR 0
|
#define VERSION_MAJOR 0
|
||||||
#define VERSION_MINOR 2
|
#define VERSION_MINOR 2
|
||||||
#define VERSION_PATCH 1
|
#define VERSION_PATCH 1
|
||||||
#define VERSION_BUILD 4086
|
#define VERSION_BUILD 4125
|
||||||
|
|
||||||
#define stringify(a) stringify_(a)
|
#define stringify(a) stringify_(a)
|
||||||
#define stringify_(a) #a
|
#define stringify_(a) #a
|
||||||
|
@ -5,25 +5,29 @@ Merchant
|
|||||||
Chapter1_A
|
Chapter1_A
|
||||||
{
|
{
|
||||||
DisplayName = Merchant
|
DisplayName = Merchant
|
||||||
Item[1] = Minor Health Potion
|
# Specify items this merchant sells. Add an optional quantity as a second argument. Not specifying a second argument will give the shop infinite supply.
|
||||||
Item[2] = Minor Mana Potion
|
Item[1] = Minor Health Potion,5
|
||||||
|
Item[2] = Minor Mana Potion,5
|
||||||
}
|
}
|
||||||
Chapter1_B
|
Chapter1_B
|
||||||
{
|
{
|
||||||
DisplayName = Merchant
|
DisplayName = Merchant
|
||||||
Item[1] = Minor Health Potion
|
# Specify items this merchant sells. Add an optional quantity as a second argument. Not specifying a second argument will give the shop infinite supply.
|
||||||
|
Item[1] = Minor Health Potion,5
|
||||||
}
|
}
|
||||||
Chapter1_C
|
Chapter1_C
|
||||||
{
|
{
|
||||||
DisplayName = Merchant
|
DisplayName = Merchant
|
||||||
Item[1] = Minor Mana Potion
|
# Specify items this merchant sells. Add an optional quantity as a second argument. Not specifying a second argument will give the shop infinite supply.
|
||||||
|
Item[1] = Minor Mana Potion,5
|
||||||
}
|
}
|
||||||
Chapter1_D
|
Chapter1_D
|
||||||
{
|
{
|
||||||
DisplayName = Merchant
|
DisplayName = Merchant
|
||||||
Item[1] = Minor Health Potion
|
# Specify items this merchant sells. Add an optional quantity as a second argument. Not specifying a second argument will give the shop infinite supply.
|
||||||
Item[2] = Minor Mana Potion
|
Item[1] = Minor Health Potion,5
|
||||||
Item[3] = Bandages
|
Item[2] = Minor Mana Potion,5
|
||||||
|
Item[3] = Bandages,5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user