summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/BlockEntities/FurnaceEntity.cpp19
-rw-r--r--src/BlockEntities/FurnaceEntity.h6
-rw-r--r--src/FurnaceRecipe.cpp18
-rw-r--r--src/FurnaceRecipe.h1
-rw-r--r--src/StringUtils.cpp12
-rw-r--r--src/StringUtils.h3
-rw-r--r--src/UI/SlotArea.cpp7
7 files changed, 61 insertions, 5 deletions
diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp
index 1f7f6e023..96a17782a 100644
--- a/src/BlockEntities/FurnaceEntity.cpp
+++ b/src/BlockEntities/FurnaceEntity.cpp
@@ -32,6 +32,7 @@ cFurnaceEntity::cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, in
m_TimeCooked(0),
m_FuelBurnTime(0),
m_TimeBurned(0),
+ m_RewardCounter(0),
m_IsLoading(false)
{
m_Contents.AddListener(*this);
@@ -173,6 +174,23 @@ bool cFurnaceEntity::ContinueCooking(void)
+int cFurnaceEntity::GetAndResetReward(void)
+{
+ int Reward = FloorC(m_RewardCounter);
+ float Remainder = m_RewardCounter - static_cast<float>(Reward);
+ // Remainder is used as the percent chance of getting an extra xp point
+ if (GetRandomProvider().RandBool(Remainder))
+ {
+ Reward++;
+ }
+ m_RewardCounter = 0.0;
+ return Reward;
+}
+
+
+
+
+
void cFurnaceEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
{
cWindow * Window = GetWindow();
@@ -189,6 +207,7 @@ void cFurnaceEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
void cFurnaceEntity::FinishOne()
{
m_TimeCooked = 0;
+ m_RewardCounter += m_CurrentRecipe->Reward;
if (m_Contents.GetSlot(fsOutput).IsEmpty())
{
diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h
index 7b189be85..b1166c3bf 100644
--- a/src/BlockEntities/FurnaceEntity.h
+++ b/src/BlockEntities/FurnaceEntity.h
@@ -84,6 +84,9 @@ public:
/** Returns true if there's time left before the current fuel is depleted */
bool HasFuelTimeLeft(void) const { return (GetFuelBurnTimeLeft() > 0); }
+ /** Calculates, resets, and returns the experience reward in this furnace */
+ int GetAndResetReward(void);
+
// tolua_end
void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned)
@@ -130,6 +133,9 @@ protected:
/** Amount of ticks that the current fuel has been burning */
int m_TimeBurned;
+ /** Running total of experience that can be picked up */
+ float m_RewardCounter;
+
/** Is the block currently being loaded into the world? */
bool m_IsLoading;
diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp
index a2199cd33..a4647b7a0 100644
--- a/src/FurnaceRecipe.cpp
+++ b/src/FurnaceRecipe.cpp
@@ -161,6 +161,7 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li
Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end());
int CookTime = 200;
+ float Reward = 0;
std::unique_ptr<cItem> InputItem = cpp14::make_unique<cItem>();
std::unique_ptr<cItem> OutputItem = cpp14::make_unique<cItem>();
@@ -189,18 +190,27 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li
return;
}
}
-
- if (!ParseItem(Sides[1], *OutputItem))
+ const AStringVector & OutputSplit = StringSplit(Sides[1], "$");
+ if (!ParseItem(OutputSplit[0], *OutputItem))
{
- LOGWARNING("furnace.txt: line %d: Cannot parse output item \"%s\".", a_LineNum, Sides[1].c_str());
+ LOGWARNING("furnace.txt: line %d: Cannot parse output item \"%s\".", a_LineNum, OutputSplit[0].c_str());
LOGINFO("Offending line: \"%s\"", a_Line.c_str());
return;
}
-
+ if (OutputSplit.size() > 1)
+ {
+ if (!StringToFloat(OutputSplit[1], Reward))
+ {
+ LOGWARNING("furnace.txt: line %d: Cannot parse reward \"%s\".", a_LineNum, OutputSplit[1].c_str());
+ LOGINFO("Offending line: \"%s\"", a_Line.c_str());
+ return;
+ }
+ }
cRecipe Recipe;
Recipe.In = InputItem.release();
Recipe.Out = OutputItem.release();
Recipe.CookTime = CookTime;
+ Recipe.Reward = Reward;
m_pState->Recipes.push_back(Recipe);
}
diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h
index 0779e18a4..84ee87092 100644
--- a/src/FurnaceRecipe.h
+++ b/src/FurnaceRecipe.h
@@ -30,6 +30,7 @@ public:
cItem * In;
cItem * Out;
int CookTime; ///< How long this recipe takes to smelt, in ticks
+ float Reward; ///< Experience reward for creating 1 of this item
};
/** Returns a recipe for the specified input, nullptr if no recipe found */
diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp
index b1f58f23c..ae0aec1ad 100644
--- a/src/StringUtils.cpp
+++ b/src/StringUtils.cpp
@@ -1051,3 +1051,15 @@ AString StringsConcat(const AStringVector & a_Strings, char a_Separator)
}
return res;
}
+
+bool StringToFloat(const AString & a_String, float & a_Num)
+{
+ char *err;
+ a_Num = strtof(a_String.c_str(), &err);
+ if (*err != 0)
+ {
+ return false;
+ }
+ return true;
+}
+
diff --git a/src/StringUtils.h b/src/StringUtils.h
index a74239ec8..1c6cdf509 100644
--- a/src/StringUtils.h
+++ b/src/StringUtils.h
@@ -146,6 +146,9 @@ extern AStringVector MergeStringVectors(const AStringVector & a_Strings1, const
/** Concatenates the specified strings into a single string, separated by the specified separator. */
extern AString StringsConcat(const AStringVector & a_Strings, char a_Separator);
+/** Converts a string into a float. Returns false if the conversion fails. */
+extern bool StringToFloat(const AString & a_String, float & a_Num);
+
diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp
index d093bb337..ab1edf595 100644
--- a/src/UI/SlotArea.cpp
+++ b/src/UI/SlotArea.cpp
@@ -1909,7 +1909,6 @@ const cItem * cSlotAreaFurnace::GetSlot(int a_SlotNum, cPlayer & a_Player) const
void cSlotAreaFurnace::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
{
- UNUSED(a_Player);
m_Furnace->SetSlot(a_SlotNum, a_Item);
}
@@ -1932,6 +1931,12 @@ void cSlotAreaFurnace::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum)
void cSlotAreaFurnace::HandleSmeltItem(const cItem & a_Result, cPlayer & a_Player)
{
+ int Reward = m_Furnace->GetAndResetReward();
+ if (Reward > 0)
+ {
+ a_Player.GetWorld()->SpawnExperienceOrb(a_Player.GetPosX(), a_Player.GetPosY(), a_Player.GetPosZ(), Reward);
+ }
+
/** TODO 2014-05-12 xdot: Figure out when to call this method. */
switch (a_Result.m_ItemType)
{