Add automated script to apply all assets to the unit testing framework each run. Add new runtime warning for RowInventoryScrollableWindowComponent items that have item boxes larger than the actual component. Move testingMode flag for AiL class to be set before game configurations are read. Add branch for reading specific unit test game configuration files. Include unit test-specific images and configs committed to repository. Add Disassemble function to inventory class. Add Disassemble item test. Fix issues with extra stray shared pointers lingering everywhere when adding/removing items and grabbing their references. Make Stage Loot/Monster Loot have brand new shared pointers to items (copy instead of strong reference) so weak pointer references to existing items actually expire and behave as expected. Move Monster Loot and Stage Loot clear calls to the switch to Overworld Map trigger. Release Build 10476.

removeExposedPackKey
sigonasr2 4 months ago
parent 13eeb46000
commit 830b893b1c
  1. 3
      Adventures in Lestoria Tests/Adventures in Lestoria Tests.vcxproj
  2. 13
      Adventures in Lestoria Tests/ItemTests.cpp
  3. 3
      Adventures in Lestoria Tests/MonsterTests.cpp
  4. 3
      Adventures in Lestoria Tests/PlayerTests.cpp
  5. 21
      Adventures in Lestoria/AdventuresInLestoria.cpp
  6. 2
      Adventures in Lestoria/AdventuresInLestoria.h
  7. 2
      Adventures in Lestoria/ArtificerRefineWindow.cpp
  8. 2
      Adventures in Lestoria/InventoryScrollableWindowComponent.h
  9. 77
      Adventures in Lestoria/Item.cpp
  10. 4
      Adventures in Lestoria/Item.h
  11. 5
      Adventures in Lestoria/RowInventoryScrollableWindowComponent.h
  12. 20
      Adventures in Lestoria/ScrollableWindowComponent.h
  13. 3
      Adventures in Lestoria/State_OverworldMap.cpp
  14. 2
      Adventures in Lestoria/Version.h
  15. 6
      Adventures in Lestoria/assets/config/configuration.txt
  16. 6
      Adventures in Lestoria/assets/config/items/Accessories.txt
  17. 2
      unit-testing-prebuild.ps1
  18. BIN
      x64/Release/Adventures in Lestoria.exe
  19. 2792
      x64/Unit Testing/assets/config/items/Equipment-test.txt
  20. 389
      x64/Unit Testing/assets/config/items/ItemDatabase-test.txt
  21. 181
      x64/Unit Testing/assets/config/items/ItemSets-test.txt
  22. 69
      x64/Unit Testing/assets/config/items/items-test.txt
  23. BIN
      x64/Unit Testing/assets/items/Pct Recovery Potion.png
  24. BIN
      x64/Unit Testing/assets/items/Recovery Potion.png
  25. BIN
      x64/Unit Testing/assets/items/Test Armor.png
  26. BIN
      x64/Unit Testing/assets/items/Test Armor2.png
  27. BIN
      x64/Unit Testing/assets/items/Test Armor3.png
  28. BIN
      x64/Unit Testing/assets/items/Test Armor4.png

@ -68,6 +68,9 @@
<SubSystem>Windows</SubSystem>
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File ../unit-testing-prebuild.ps1</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Unit Testing|Win32'">
<ClCompile>

@ -61,8 +61,7 @@ namespace ItemTests
HWButton*testKey;
TEST_METHOD_INITIALIZE(ItemInitialize){
rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run.
testGame.reset(new AiL());
testGame->olc_SetTestingMode(true);
testGame.reset(new AiL(true));
ItemAttribute::Initialize();
ItemInfo::InitializeItems();
testGame->InitializeGraphics();
@ -184,5 +183,15 @@ namespace ItemTests
}
Assert::AreEqual(60,player->GetHealth(),L"Player should not be healed now that the Bandages effect is over.");
}
TEST_METHOD(DisassembleAccessoryTest){
Inventory::AddItem("Ring of the Slime King"s);
std::weak_ptr<Item>disassembleRingTest{Inventory::AddItem("Ring of the Slime King"s)};
Inventory::AddItem("Ring of the Slime King"s);
Inventory::Disassemble(disassembleRingTest);
Assert::AreEqual(2U,Inventory::GetItemCount("Ring of the Slime King"s),L"Disassembly has removed one of the Slime King rings from our inventory.");
Assert::IsTrue(disassembleRingTest.expired(),L"Original reference to disassembled ring should now be invalid.");
Assert::AreEqual(1U,Inventory::GetItemCount(ITEM_DATA["Ring of the Slime King"].FragmentName()),L"Disassembly has given us a Slime King Ring Fragment.");
}
};
}

@ -65,8 +65,7 @@ namespace MonsterTests
#pragma region Setup Functions
//Makes MONSTER_DATA["TestName"] available.
void SetupTestMonster(){
testGame.reset(new AiL());
testGame->olc_SetTestingMode(true);
testGame.reset(new AiL(true));
ItemAttribute::Initialize();
ItemInfo::InitializeItems();
testGame->InitializeGraphics();

@ -63,8 +63,7 @@ namespace PlayerTests
HWButton*testKey;
TEST_METHOD_INITIALIZE(PlayerInitialize){
rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run.
testGame.reset(new AiL());
testGame->olc_SetTestingMode(true);
testGame.reset(new AiL(true));
ItemAttribute::Initialize();
ItemInfo::InitializeItems();
testGame->InitializeGraphics();

@ -157,9 +157,11 @@ InputGroup AiL::KEY_TOGGLE_MAP;
float AiL::SIZE_CHANGE_SPEED=1;
AiL::AiL(){
AiL::AiL(bool testingMode){
olc_SetTestingMode(testingMode);
GFX.Reset();
DATA.Reset();
MONSTER_LIST.clear();
InitializeGameConfigurations();
sAppName="GAME_NAME"_S;
game=this;
@ -198,11 +200,18 @@ void AiL::InitializeGameConfigurations(){
std::string THEMES_CONFIG = CONFIG_PATH + "themes_config"_S;
utils::datafile::Read(DATA,THEMES_CONFIG);
std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S;
utils::datafile::Read(DATA,ITEM_CONFIG);
{
std::string ITEM_CONFIG = CONFIG_PATH + "item_config"_S;
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
if(TestingModeEnabled()){ //Unit Test-specific custom configurations.
ITEM_CONFIG = CONFIG_PATH + "item-test_config"_S;
ITEM_SET_CONFIG = CONFIG_PATH + "item_set-test_config"_S;
}
std::string ITEM_SET_CONFIG = CONFIG_PATH + "item_set_config"_S;
utils::datafile::Read(DATA,ITEM_SET_CONFIG);
utils::datafile::Read(DATA,ITEM_CONFIG);
utils::datafile::Read(DATA,ITEM_SET_CONFIG);
}
std::string ITEM_STATS_CONFIG = CONFIG_PATH + "item_stats_config"_S;
utils::datafile::Read(DATA,ITEM_STATS_CONFIG);
@ -2314,8 +2323,6 @@ void AiL::_PrepareLevel(MapName map,MusicChange changeMusic){
encounterStarted=false;
totalBossEncounterMobs=0;
SetWindSpeed({});
Inventory::Clear("Monster Loot");
Inventory::Clear("Stage Loot");
Inventory::ResetLoadoutItemsUsed();
Input::StopVibration();

@ -232,7 +232,7 @@ private:
std::vector<std::tuple<std::weak_ptr<Monster>,StackCount,MarkTime>>lockOnTargets;
float lastLockOnTargetTime{};
public:
AiL();
AiL(bool testingMode=false);
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;
bool OnUserDestroy() override;

@ -52,7 +52,7 @@ void Menu::InitializeArtificerRefineWindow(){
return true;
},DO_NOTHING,DO_NOTHING,
InventoryCreator::RowPlayer_InventoryUpdate,
InventoryWindowOptions{.padding=1,.size={137,28}})END;
InventoryWindowOptions{.padding=1,.size={artificerRefineWindow->size.x/2-5.f,28}})END;
auto backButton=artificerRefineWindow->ADD("Back",MenuComponent)(geom2d::rect<float>{{0.f,artificerRefineWindow->size.y-12.f},{120.f,12.f}},"Back",[](MenuFuncData data){
Menu::CloseMenu();

@ -69,8 +69,8 @@ protected:
std::string itemNameLabelName;
std::string itemDescriptionLabelName;
bool inventoryButtonsActive=true;
private:
InventoryWindowOptions options;
private:
int invWidth;
public:
inline InventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)

@ -361,36 +361,41 @@ void ItemInfo::InitializeItems(){
if(tempItem.Description().length()==0)ERR("WARNING! Item "<<info.name<<" does not have a description!");
}
CreateAccessoryFragments:{
#pragma region Create Accessory Fragments
for(const auto&itemName:ITEM_CATEGORIES.at("Accessories")){
const std::string fragmentName{ITEM_DATA.at(itemName).fragmentName.value()};
ItemInfo&it{ITEM_DATA[fragmentName]};
//olc::Decal*generatedFragmentImage{new olc::Decal(new Sprite(24,24))};
GFX[fragmentName].Create(24,24);
game->SetDrawTarget(GFX.at(fragmentName).Sprite());
std::set<Pixel>colors;
for(int y=0;y<24;y++){
for(int x=0;x<24;x++){
colors.insert(ITEM_DATA.at(itemName).img->sprite->GetPixel(x,y));
}
if(!game->TestingModeEnabled()){
#pragma region Collect colors from source ring image
std::set<Pixel>colors;
for(int y=0;y<24;y++){
for(int x=0;x<24;x++){
colors.insert(ITEM_DATA.at(itemName).img->sprite->GetPixel(x,y));
}
}
colors.erase(BLANK);
#pragma endregion
#pragma region Generate fragment with randomly sampled pixels from the source ring image
game->SetDrawTarget(GFX.at(fragmentName).Sprite());
game->DrawSprite({},GFX.at("items/Fragment.png").Sprite(),1U,0U,[colors](const Pixel&in){
if(in==BLANK)return in;
for(const Pixel&p:colors){
if(util::random()%colors.size()==0)return PixelLerp(in,{p.r,p.g,p.b},0.5f);
}
return in;
});
game->SetDrawTarget(nullptr);
GFX.at(fragmentName).Decal()->Update();
#pragma endregion
}
colors.erase(BLANK);
game->DrawSprite({},GFX.at("items/Fragment.png").Sprite(),1U,0U,[colors](const Pixel&in){
if(in==BLANK)return in;
for(const Pixel&p:colors){
if(util::random()%colors.size()==0)return PixelLerp(in,{p.r,p.g,p.b},0.5f);
}
return in;
});
game->SetDrawTarget(nullptr);
GFX.at(fragmentName).Decal()->Update();
it.img=GFX.at(fragmentName).Decal();
it.name=fragmentName;
it.description="Fragment Description"_S;
it.category="Materials";
LOG(std::format("Item Fragment {} generated...",fragmentName));
}
}
#pragma endregion
ITEM_DATA.SetInitialized();
ITEM_CATEGORIES.SetInitialized();
@ -483,36 +488,31 @@ Item::Item(uint32_t amt,IT item,uint8_t enhancementLevel)
std::weak_ptr<Item>Inventory::AddItem(IT it,uint32_t amt,bool monsterDrop){
if(!ITEM_DATA.count(it))ERR("Item "<<it<<" does not exist in Item Database!");
std::weak_ptr<Item>itemPtr;
std::shared_ptr<Item>newItem;
if(ITEM_DATA[it].IsEquippable()){ //Do not stack equips!
for(uint32_t i=0;i<amt;i++){
newItem=(*_inventory.insert({it,std::make_shared<Item>(1,it)})).second;
newItem->RandomizeStats();
InsertIntoSortedInv(newItem);
itemPtr=newItem;
itemPtr=(*_inventory.insert({it,std::make_shared<Item>(1,it)})).second;
itemPtr.lock()->RandomizeStats();
InsertIntoSortedInv(itemPtr.lock());
InsertIntoStageInventoryCategory(std::make_shared<Item>(*itemPtr.lock()),monsterDrop);
}
goto SkipAddingStackableItem;
}
else{
//There are two places to manipulate items in (Both the sorted inventory and the actual inventory)
if(!_inventory.count(it)){
itemPtr=(*_inventory.insert({it,std::make_shared<Item>(amt,it)})).second;
InsertIntoSortedInv(itemPtr.lock());
newItem=std::make_shared<Item>(amt,it);
}else{
auto inventory=_inventory.equal_range(it);
if(std::accumulate(inventory.first,inventory.second,0,
[&](int counter,std::pair<IT,std::shared_ptr<Item>>item){
(*item.second).amt+=amt;
itemPtr=item.second;
newItem=std::make_shared<Item>(amt,it);
return counter+1;})>1)ERR("WARNING! We should not have more than 1 instance of a stackable item!");
}
InsertIntoStageInventoryCategory(std::make_shared<Item>(amt,it),monsterDrop);
}
SkipAddingStackableItem:
InsertIntoStageInventoryCategory(newItem,monsterDrop);
return itemPtr;
}
@ -1385,4 +1385,21 @@ const bool Inventory::EquipsFullyMaxedOut(int maxWeaponLevel,int maxArmorLevel){
const EquipSlot ItemInfo::StringToEquipSlot(std::string_view slotName){
return nameToEquipSlot[std::string(slotName)];
}
void Inventory::Disassemble(std::weak_ptr<Item>itemRef){
if(ISBLANK(itemRef))ERR(std::format("WARNING! Trying to feed a blank item into the Disassemble function! THIS SHOULD NOT BE HAPPENING!"));
const std::shared_ptr<Item>&currentItem{itemRef.lock()};
if(!currentItem->IsAccessory())ERR(std::format("WARNING! Trying to disassemble Item {} which is not an accessory! THIS SHOULD NOT BE HAPPENING!",currentItem->ActualName()));
Inventory::RemoveItem(itemRef);
Inventory::AddItem(currentItem->FragmentName(),"Fragment Disassemble Gain Amount"_I);
}
const std::string&Item::FragmentName()const{
return ITEM_DATA[ActualName()].FragmentName();
}
const std::string&ItemInfo::FragmentName()const{
if(!fragmentName.has_value())ERR(std::format("WARNING! Item {} does not break down into a fragment (fragment name not set)!",Name()));
return fragmentName.value();
}

@ -237,8 +237,10 @@ public:
//Use ISBLANK macro instead!! This should not be called directly!!
static bool IsBlank(std::weak_ptr<Item>item);
const bool IsLocked()const;
const std::string&FragmentName()const;
void Lock();
void Unlock();
void Disassemble();
friend const bool operator==(std::shared_ptr<Item>lhs,std::shared_ptr<Item>rhs){return lhs->it==rhs->it&&lhs->randomizedStats==rhs->randomizedStats;};
friend const bool operator==(std::shared_ptr<Item>lhs,const IT&rhs){return lhs->ActualName()==const_cast<IT&>(rhs);};
friend const bool operator==(std::weak_ptr<Item>lhs,std::weak_ptr<Item>rhs){return !lhs.expired()&&!rhs.expired()&&lhs.lock()->it==rhs.lock()->it&&lhs.lock()->randomizedStats==rhs.lock()->randomizedStats;};
@ -278,6 +280,7 @@ public:
static void ResetLoadoutItemsUsed();
static void GivePlayerLoadoutItemsUsed();
static const bool EquipsFullyMaxedOut(int maxWeaponLevel=10,int maxArmorLevel=10);
static void Disassemble(std::weak_ptr<Item>itemRef);
static bool SwapItems(ITCategory itemCategory,uint32_t slot1,uint32_t slot2);
//Makes sure this is a valid category. Will error out if it doesn't exist! Use for ERROR HANDLING!
@ -377,6 +380,7 @@ public:
//Get the class that can equip this item.
const std::unordered_set<std::string>&GetClass()const;
Stats RandomizeStats();
const std::string&FragmentName()const;
};
class ItemOverlay{

@ -48,7 +48,10 @@ protected:
public:
inline RowInventoryScrollableWindowComponent(geom2d::rect<float>rect,std::string itemNameLabelName,std::string itemDescriptionLabelName,std::function<bool(MenuFuncData)>inventoryButtonClickAction,std::function<bool(MenuFuncData)>inventoryButtonHoverAction,std::function<bool(MenuFuncData)>inventoryButtonMouseOutAction,const InventoryCreator&creator,InventoryWindowOptions options={.padding=8,.size={24,24}},bool inventoryButtonsActive=true,ComponentAttr attributes=ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)
:InventoryScrollableWindowComponent(rect,itemNameLabelName,itemDescriptionLabelName,inventoryButtonClickAction,inventoryButtonHoverAction,inventoryButtonMouseOutAction,creator,options,inventoryButtonsActive,attributes){}
virtual inline void AfterCreate()override final{
ScrollableWindowComponent::AfterCreate();
if(options.size.x>rect.size.x||options.size.y>rect.size.y)ERR(std::format("WARNING! Component {} has Inventory Option Sizes: {} which is not large enough to fit in the component whose size is {}! Please make the component larger or the items smaller.",name,options.size.str(),rect.size.str()));
}
virtual inline void SetCompactDescriptions(CompactText compact)override final{
this->compact=compact;
for(std::weak_ptr<MenuComponent>component:components){

@ -153,19 +153,15 @@ protected:
upButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+vf2d{rect.size.x-12,0}).str()+"_"+vf2d(12,12).str(),MenuComponent)(geom2d::rect<float>{rect.pos+vf2d{rect.size.x-12,0},{12,12}},"^",[&](MenuFuncData dat){SetScrollAmount(GetScrollAmount()+vf2d{0,"ThemeGlobal.MenuButtonScrollSpeed"_F});return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH depth-1 END;
downButton=Menu::menus[parentMenu]->ADD(name+vf2d(rect.pos+rect.size-vf2d{12,12}).str()+"_"+vf2d(12,12).str(),MenuComponent)(geom2d::rect<float>{rect.pos+rect.size-vf2d{12,12},{12,12}},"v",[&](MenuFuncData dat){SetScrollAmount(GetScrollAmount()-vf2d{0,"ThemeGlobal.MenuButtonScrollSpeed"_F});return true;},ButtonAttr::UNSELECTABLE_VIA_KEYBOARD)DEPTH depth-1 END;
subWindow=ViewPort::rectViewPort({},rect.size,Menu::menus[parentMenu]->pos+rect.pos);
if(!upButton.expired()){
if(IsEnabled()){
upButton.lock()->Enable();
}else{
upButton.lock()->Disable();
}
if(IsEnabled()){
upButton.lock()->Enable();
}else{
upButton.lock()->Disable();
}
if(!downButton.expired()){
if(IsEnabled()){
downButton.lock()->Enable();
}else{
downButton.lock()->Disable();
}
if(IsEnabled()){
downButton.lock()->Enable();
}else{
downButton.lock()->Disable();
}
}
virtual inline void BeforeUpdate(AiL*game)override{

@ -58,6 +58,9 @@ ConnectionPoint*State_OverworldMap::currentConnectionPoint=nullptr;
State_OverworldMap::State_OverworldMap(){}
void State_OverworldMap::OnStateChange(GameState*prevState){
Inventory::Clear("Monster Loot");
Inventory::Clear("Stage Loot");
Component<MenuComponent>(MenuType::PAUSE,"Return to Camp Button")->SetGrayedOut(false);
SaveFile::SaveGame();

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 3
#define VERSION_BUILD 10443
#define VERSION_BUILD 10476
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -58,9 +58,15 @@ class_list = Warrior, Thief, Ranger, Trapper, Wizard, Witch
# Items Config
item_config = items/items.txt
# Items Unit Testing Config
item-test_config = items/items-test.txt
# Item Set Config
item_set_config = items/ItemSets.txt
# Item Set Unit Testing Config
item_set-test_config = items/ItemSets-test.txt
# Path to items configuration
item_directory = items/

@ -1,4 +1,10 @@
Fragment Description = "A small piece of concentrated material from broken down jewelry."
# Number of fragments earned when breaking down an accessory.
Fragment Disassemble Gain Amount = 1
# Number of fragments required to Refine an accessory.
Fragment Refine Cost = 1
# Number of fragments required to Enchant an accessory.
Fragment Enchant Cost = 3
Equipment
{

@ -0,0 +1,2 @@
$ErrorActionPreference = "Stop"
cp -R -Force '../Adventures in Lestoria/assets' '../x64/Unit Testing'

File diff suppressed because it is too large Load Diff

@ -0,0 +1,389 @@
ItemDatabase
{
Berries
{
ItemScript = Restore
Description = Restores 15 health points and 5 mana points.
HP Restore = 15
MP Restore = 5
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 8
UseSound = Consume Item
}
Minor Health Potion
{
ItemScript = Restore
Description = Restores 50 health points.
HP Restore = 50
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 16
BuyValue = 23
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 1
Item[0] = Green Slime Remains,3
Item[1] = Blue Slime Remains,1
Gold = 10
}
}
Minor Mana Potion
{
ItemScript = Restore
Description = Restores 45 mana points over the next 15 seconds.
MP Restore = 3,1,15
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 21
BuyValue = 30
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 2
Item[0] = Red Slime Remains,1
Item[1] = Yellow Slime Remains,1
Gold = 0
}
}
Minor Recovery Potion
{
ItemScript = Restore
Description = Recovers 60 health points over the next 15 seconds.
HP Restore = 12,3,15
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 15
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 1
Item[0] = Blue Slime Remains,1
Item[1] = Red Slime Remains,1
Item[2] = Flower Petals,1
Gold = 0
}
}
Elixir of Bear Strength
{
ItemScript = Buff
Description = Increase your attack by 15% for 30 seconds.
Attack % = 15%,30
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 30
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 1
Item[0] = Bear Claw,1
Item[1] = Bear Blood,1
Gold = 0
}
}
Bandages
{
ItemScript = RestoreDuringCast
Description = Restores 30% health points casting for 6 seconds. The effect can be interrupted.
HP % Restore = 5%,0.9,6
Cast Time = 6.0
Cooldown Time = 5.0
ItemCategory = Consumables
SellValue = 7
BuyValue = 10
UseSound = Consume Item
}
Health Potion
{
ItemScript = Restore
Description = Restores 75 health points.
HP Restore = 75
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 24
BuyValue = 35
UseSound = Consume Potion
}
Mana Potion
{
ItemScript = Restore
Description = Restores 60 mana points over the next 15 seconds.
MP Restore = 4,1,15
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 28
BuyValue = 40
UseSound = Consume Potion
}
Recovery Potion
{
ItemScript = Restore
Description = Recovers 90 health points over the next 15 seconds.
HP Restore = 18,3,15
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 29
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 2
Item[0] = Yellow Slime Remains,1
Item[1] = Stone Heart,1
Gold = 0
}
}
Elixir of the Wind
{
ItemScript = Buff
Description = Increase your Movement Speed by 25% for 30 seconds.
Move Spd % = 25%,30
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 30
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 2
Item[0] = Hawk Feather,3
Gold = 0
}
}
Green Slime Remains
{
Description = The remains of a green slime. It stares at you intently.
ItemCategory = Materials
SellValue = 2
}
Blue Slime Remains
{
Description = The remains of a blue slime. It stares at you intently.
ItemCategory = Materials
SellValue = 4
}
Red Slime Remains
{
Description = The remains of a red slime. It stares at you intently.
ItemCategory = Materials
SellValue = 4
}
Yellow Slime Remains
{
Description = The remains of a yellow slime. It stares at you intently.
ItemCategory = Materials
SellValue = 9
}
Slimy Bun
{
Description = It's cute and hideous at the same time.
ItemCategory = Materials
SellValue = 40
}
Flower Petals
{
Description = Some beautiful petals of a flower.
ItemCategory = Materials
SellValue = 3
}
Frog Skin
{
Description = The skin of a frog.
ItemCategory = Materials
SellValue = 5
}
Bear Claw
{
Description = The claw of a bear.
ItemCategory = Materials
SellValue = 12
}
Bear Blood
{
Description = Some uncontaminated blood of a bear.
ItemCategory = Materials
SellValue = 17
}
Windhound Skin
{
Description = The skin of a windhound with only minor damages.
ItemCategory = Materials
SellValue = 6
# Used in version 6216 and earlier.
Alternative Name[0] = Wolf Skin
}
Logs
{
Description = A small unrefined pile of logs.
ItemCategory = Materials
SellValue = 3
}
High-Quality Logs
{
Description = A small unrefined pile of logs of exceptional quality.
ItemCategory = Materials
SellValue = 7
}
Green Gemstone
{
Description = Radiating with energy from the forest, it is used to refine stronger equipment.
ItemCategory = Materials
SellValue = 180
}
Time Medal
{
Description = A medal provided to top athletes in Lestoria commemorating a huge victory.
ItemCategory = Materials
}
Boar Meat
{
ItemScript = Restore
Description = Recovers 120 health points over the next 120 seconds.
HP Restore = 1,1,120
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 9
UseSound = Consume Potion
}
Broken Dagger
{
Description = A broken weapon, wielded by a goblin.
ItemCategory = Materials
SellValue = 12
}
Broken Bow
{
Description = A broken weapon, wielded by a goblin.
ItemCategory = Materials
SellValue = 13
}
Blackpowder
{
Description = Just some powder found in the pockets of a goblin.
ItemCategory = Materials
SellValue = 18
}
Hawk Feather
{
Description = A Feather of a Hawk. Sadly no longer in perfect condition.
ItemCategory = Materials
SellValue = 7
}
Stone Heart
{
Description = A stone, shaped in the form of an heart.
ItemCategory = Materials
SellValue = 28
}
Flat Recovery Potion
{
ItemScript = Restore
Description = Restores 50 health and mana points.
HP Restore = 50
MP Restore = 50
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 16
BuyValue = 23
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 1
Item[0] = Green Slime Remains,3
Item[1] = Blue Slime Remains,1
Gold = 10
}
}
Pct Recovery Potion
{
ItemScript = Restore
Description = Restores 50% health and mana points.
HP % Restore = 50
MP % Restore = 50
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 16
BuyValue = 23
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 1
Item[0] = Green Slime Remains,3
Item[1] = Blue Slime Remains,1
Gold = 10
}
}
Stat Up Everything Potion
{
ItemScript = Buff
Description = Buffs every stat (Illegally)
Attack = 1,1.0
Attack % = 1%,1.0
Defense = 1,1.0
Defense % = 1%,1.0
Health = 1,1.0
Health % = 1%,1.0
Move Spd % = 1%,1.0
CDR = 1%,1.0
Crit Rate = 1%,1.0
Crit Dmg = 1%,1.0
HP Recovery % = 1%,1.0
HP6 Recovery % = 1%,1.0
HP4 Recovery % = 1%,1.0
Damage Reduction = 1%,1.0
Attack Spd = 1,1.0
Mana = 1,1.0
ItemCategory = Consumables
Cooldown Time = 5.0
Cast Time = 0.0
SellValue = 16
BuyValue = 23
UseSound = Consume Potion
Crafting
{
# When this crafting recipe is available.
AvailableChapter = 1
Item[0] = Green Slime Remains,3
Item[1] = Blue Slime Remains,1
Gold = 10
}
}
}

@ -0,0 +1,181 @@
ItemSet
{
# Wrap the entire set of stats in the number of pieces required. Example:
#
# Example Armor
# {
# 3
# { #Add a 3-set piece bonus for Example Armor of +5 bonus attack.
# Attack = 5
# }
# 5
# { #Add a 5-set piece bonus for Example Armor of +20 Health.
# Health = 20
# }
# }
#
#
# Provide any stat name followed by its increase amount to add it to the set. Valid stat names and value examples are below:
#
# Defense = 5 # Adds 5 defense
# Health = 3 # Adds 3 Health
# Attack = 7 # Adds 7 attack
# Defense % = 2% # Adds 2% defense
# Attack % = 5% # Adds 5% attack
# Move Spd % = 10% # Grants 10% more movement speed.
# CDR = 14% # Grants 14% cooldown reduction.
# Crit Rate = 5% # Grants 5% crit rate.
# Crit Dmg = 25% # Grants 25% bonus crit damage.
# Health % = 30% # Grants 30% Max health
# HP6 Recovery % = 4% # Grants 4% HP recovery every 6 seconds.
# HP4 Recovery % = 2% # Grants 2% HP recovery every 4 seconds.
# Damage Reduction = 2% # Grants 2% direct damage reduction
#
#
# All Possible Stat modifications can be found in ItemStats.txt
#
Leather
{
2
{
Health % = 3%
}
4
{
HP6 Recovery % = 1%
}
}
Copper
{
2
{
Defense = 25
}
4
{
Damage Reduction = 1%
}
}
Shell
{
2
{
Move Spd % = 5%
}
4
{
CDR = 7%
}
}
Bone
{
2
{
Crit Rate = 5%
}
4
{
Crit Dmg = 7%
}
}
???
{
2
{
Crit Rate = 3%
Move Spd % = 5%
Attack = 2%
}
4
{
Crit Dmg = 7%
CDR = 5%
Health % = 2%
}
}
Enchanted Leather
{
2
{
Health % = 10%
}
4
{
HP4 Recovery % = 1%
}
}
Adamantite
{
2
{
Defense = 120
}
4
{
Damage Reduction = 10%
}
}
Iron Shell
{
2
{
Move Spd % = 10%
}
4
{
CDR = 15%
}
}
Cursed Bone
{
2
{
Crit Rate = 10%
}
4
{
Crit Dmg = 15%
}
}
Test
{
1
{
Defense = 100
Health = 1000
Attack = 100
}
}
Test2
{
1
{
Defense % = 100%
Attack % = 100%
Move Spd % = 100%
CDR = 100%
Crit Rate = 100%
Crit Dmg = 100%
Health % = 100%
HP6 Recovery % = 100%
}
}
Test3
{
1
{
HP4 Recovery % = 100%
Damage Reduction = 100%
}
}
Test4
{
1
{
HP Recovery % = 100%
Attack Spd = 50%
Mana = 100
}
}
}

@ -0,0 +1,69 @@
ItemConfiguration
{
Item Database = ItemDatabase-test.txt
Item Scripts = ItemScript.txt
Item Categories = ItemCategory.txt
Equipment = Equipment-test.txt
Weapons = Weapons.txt
Accessories = Accessories.txt
}
Item
{
# Amount of time to wait before an item can be used again (Global).
Item Cooldown Time = 5.0
# The maximum enhancement level of equipment.
Item Max Enhancement Level = 10
# The name of the currency in the game.
Currency Name = Gold
# Text that displays when items are craftable in the Blacksmith.
Craftable Item Text = Can Craft
# Color of the text that displays when items are craftable in the Blacksmith.
Craftable Item Text Color = 0,255,0,255
# Text that displays when items can be upgraded in the Blacksmith.
Upgradeable Item Text = Upgrade!
# Color of the text that displays when items can be upgraded in the Blacksmith.
Upgradeable Item Text Color = 255,255,0,255
# Text that displays when items can be upgraded in the Blacksmith but the player doesn't have enough material.
Missing Upgradeable Item Text = Missing Materials
# Color of the text that displays when items can be upgraded in the Blacksmith but the player doesn't have enough material.
Missing Upgradeable Item Text Color = 192,0,0,255
# Text that displays when items are maxed out at the Blacksmith.
Maxed Item Text = MAX LV
# Color of the text that displays when items are maxed out at the Blacksmith.
Maxed Item Text Color = 0,255,255,255
# The names of items to be sorted for equipment lists.
Equipment Sort Order Primary = Wooden, Leather, Steel, Copper, Shell, Bone, Laser, Plasma, Unknown, Test, Test2, Test3
# The types of the items to be sorted for equipment lists if they have the same primary type.
Equipment Sort Order Secondary = Helmet, Armor, Pants, Gloves, Shoes, Sword, Bow, Staff
}
ItemDrop
{
# Item drops horizontal random speed range
Item Drop Horizontal Speed = -30,30
# Item drops vertical random speed range
Item Drop Vertical Speed = -15,15
# Item drop suction range
Item Drop Suction Range = 360
# Item drop suction strength
Item Drop Suction Strength = 8000
# Item drop initial rise speed
Item Drop Initial Rise Speed = 10
# Item drop gravity
Item Drop Gravity = -9.8
# Item drop scale
Item Drop Scale = 0.4
}
ItemOverlay
{
# Amount of time the item overlay display remains on-screen.
Item Overlay Time = 5.0
# How fast the item overlay display moves into the screen (from the left edge).
Item Overlay Speed = 200
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Loading…
Cancel
Save