From 5e6c7368592c0fbaa4d9d4320767d3cdcfd0261e Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 12 Jun 2012 20:03:46 +0000 Subject: Updated the crafting recipes architecture to better support crafting hooks. Removed the old recipe file and implementation altogether. git-svn-id: http://mc-server.googlecode.com/svn/trunk@597 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/CraftingRecipes.cpp | 271 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 249 insertions(+), 22 deletions(-) (limited to 'source/CraftingRecipes.cpp') diff --git a/source/CraftingRecipes.cpp b/source/CraftingRecipes.cpp index 37d82965e..5fb705296 100644 --- a/source/CraftingRecipes.cpp +++ b/source/CraftingRecipes.cpp @@ -10,60 +10,287 @@ -cCraftingRecipes::cCraftingRecipes(void) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingGrid: + +cCraftingGrid::cCraftingGrid(int a_Width, int a_Height) : + m_Width(a_Width), + m_Height(a_Height), + m_Items(new cItem[a_Width * a_Height]) { - LoadRecipes(); } -cCraftingRecipes::~cCraftingRecipes() +cCraftingGrid::cCraftingGrid(cItem * a_Items, int a_Width, int a_Height) : + m_Width(a_Width), + m_Height(a_Height), + m_Items(new cItem[a_Width * a_Height]) { - ClearRecipes(); + for (int i = a_Width * a_Height - 1; i >= 0; i--) + { + m_Items[i] = a_Items[i]; + } } -/// Offers an item resulting from the crafting grid setup. Doesn't modify the grid -cItem cCraftingRecipes::Offer(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight) +cCraftingGrid::cCraftingGrid(const cCraftingGrid & a_Original) : + m_Width(a_Original.m_Width), + m_Height(a_Original.m_Height), + m_Items(new cItem[a_Original.m_Width * a_Original.m_Height]) { - std::auto_ptr Recipe(FindRecipe(a_CraftingGrid, a_GridWidth, a_GridHeight)); - if (Recipe.get() == NULL) + for (int i = m_Width * m_Height - 1; i >= 0; i--) { - return cItem(); + m_Items[i] = a_Original.m_Items[i]; + } +} + + + + + +cCraftingGrid::~cCraftingGrid() +{ + delete[] m_Items; +} + + + + + +cItem & cCraftingGrid::GetItem(int x, int y) const +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to get an invalid item from a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return m_Items[0]; + } + return m_Items[x + m_Width * y]; +} + + + + + +void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, short a_ItemHealth, int a_ItemCount) +{ + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) + { + LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return; } - return Recipe->m_Result; + m_Items[x + m_Width * y] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); } -/// Crafts the item resulting from the crafting grid setup. Modifies the grid, returns the crafted item -cItem cCraftingRecipes::Craft(cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight) +void cCraftingGrid::SetItem(int x, int y, const cItem & a_Item) { - std::auto_ptr Recipe(FindRecipe(a_CraftingGrid, a_GridWidth, a_GridHeight)); - if (Recipe.get() == NULL) + // Accessible through scripting, must verify parameters: + if ((x < 0) || (x >= m_Width) || (y < 0) || (y >= m_Height)) { - return cItem(); + LOGERROR("Attempted to set an invalid item in a crafting grid: (%d, %d), grid dimensions: (%d, %d).", + x, y, m_Width, m_Height + ); + return; } - // Consume the ingredients from the grid: - for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + m_Items[x + m_Width * y] = a_Item; +} + + + + + +void cCraftingGrid::Clear(void) +{ + for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) { - int GridIdx = itr->x + a_GridWidth * itr->y; - a_CraftingGrid[GridIdx].m_ItemCount -= itr->m_Item.m_ItemCount; - if (a_CraftingGrid[GridIdx].m_ItemCount <= 0) + m_Items[x + m_Width * y].Empty(); + } +} + + + + + +void cCraftingGrid::ConsumeGrid(const cCraftingGrid & a_Grid) +{ + if ((a_Grid.m_Width != m_Width) || (a_Grid.m_Height != m_Height)) + { + LOGWARNING("Consuming a grid of different dimensions: (%d, %d) vs (%d, %d)", + a_Grid.m_Width, a_Grid.m_Height, m_Width, m_Height + ); + } + int MinX = std::min(a_Grid.m_Width, m_Width); + int MinY = std::min(a_Grid.m_Height, m_Height); + for (int y = 0; y < MinY; y++) for (int x = 0; x < MinX; x++) + { + int ThatIdx = x + a_Grid.m_Width * y; + if (a_Grid.m_Items[ThatIdx].IsEmpty()) { - a_CraftingGrid[GridIdx].Empty(); + continue; } + int ThisIdx = x + m_Width * y; + if (a_Grid.m_Items[ThatIdx].m_ItemID != m_Items[ThisIdx].m_ItemID) + { + LOGWARNING("Consuming incompatible grids: item at (%d, %d) is %d in grid and %d in ingredients. Item not consumed.", + x, y, m_Items[ThisIdx].m_ItemID, a_Grid.m_Items[ThatIdx].m_ItemID + ); + continue; + } + char NumWantedItems = a_Grid.m_Items[ThatIdx].m_ItemCount; + if (NumWantedItems > m_Items[ThisIdx].m_ItemCount) + { + LOGWARNING("Consuming more items than there actually are in slot (%d, %d), item %d (want %d, have %d). Item zeroed out.", + x, y, m_Items[ThisIdx].m_ItemID, + NumWantedItems, m_Items[ThisIdx].m_ItemCount + ); + NumWantedItems = m_Items[ThisIdx].m_ItemCount; + } + m_Items[ThisIdx].m_ItemCount -= NumWantedItems; + if (m_Items[ThisIdx].m_ItemCount == 0) + { + m_Items[ThisIdx].Clear(); + } + } // for x, for y +} + + + + + +void cCraftingGrid::CopyToItems(cItem * a_Items) const +{ + for (int i = m_Height * m_Width - 1; i >= 0; i--) + { + a_Items[i] = m_Items[i]; + } // for x, for y +} + + + + + +void cCraftingGrid::Dump(void) +{ + for (int y = 0; y < m_Height; y++) for (int x = 0; x < m_Width; x++) + { + int idx = x + m_Width * y; + LOGD("Slot (%d, %d): Type %d, health %d, count %d", + x, y, m_Items[idx].m_ItemID, m_Items[idx].m_ItemHealth, m_Items[idx].m_ItemCount + ); } - return Recipe->m_Result; +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingRecipe: + +cCraftingRecipe::cCraftingRecipe(const cCraftingGrid & a_CraftingGrid) : + m_Ingredients(a_CraftingGrid) +{ +} + + + + + +void cCraftingRecipe::Clear(void) +{ + m_Ingredients.Clear(); + m_Result.Clear(); +} + + + + + +void cCraftingRecipe::SetResult(ENUM_ITEM_ID a_ItemType, short a_ItemHealth, int a_ItemCount) +{ + m_Result = cItem(a_ItemType, a_ItemCount, a_ItemHealth); +} + + + + + +void cCraftingRecipe::ConsumeIngredients(cCraftingGrid & a_CraftingGrid) +{ + a_CraftingGrid.ConsumeGrid(m_Ingredients); +} + + + + + +void cCraftingRecipe::Dump(void) +{ + LOGD("Recipe ingredients:"); + m_Ingredients.Dump(); + LOGD("Result: Type %d, health %d, count %d", + m_Result.m_ItemID, m_Result.m_ItemHealth, m_Result.m_ItemCount + ); +} + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCraftingRecipes: + +cCraftingRecipes::cCraftingRecipes(void) +{ + LoadRecipes(); +} + + + + + +cCraftingRecipes::~cCraftingRecipes() +{ + ClearRecipes(); +} + + + + + +void cCraftingRecipes::GetRecipe(const cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe) +{ + // TODO: Allow plugins to intercept recipes, add a pre-craft hook here + std::auto_ptr Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); + a_Recipe.Clear(); + if (Recipe.get() == NULL) + { + // TODO: Allow plugins to intercept recipes, add a post-craft hook here + return; + } + for (cRecipeSlots::const_iterator itr = Recipe->m_Ingredients.begin(); itr != Recipe->m_Ingredients.end(); ++itr) + { + a_Recipe.SetIngredient(itr->x, itr->y, itr->m_Item); + } // for itr + a_Recipe.SetResult(Recipe->m_Result); + // TODO: Allow plugins to intercept recipes, add a post-craft hook here } -- cgit v1.2.3