1
0

Smelting Gives Experience (#4094)

* Smelting Exp

Smelting now gives experience

* Furnace.txt update

Exp rewards are entered in furnace.txt, Reward calculation is now done
is the furnaceentity class

* furnace.txt update

Changed alignment tabs to spaces
Included documentation of exp in recipe

* Updated StringToFloat

changed strtod to strtof

* Explicit Float to Int

* Reworked Smelting Rewards

* No C casts

-Adds new function to the api
-Sets reward counter to 0 in furnace constructor

* Style and exp lock removed

-Fixed  style mistakes accoring to PR notes
-XP isn't locked to a single player anymore

* No Smelter API

-Removed SetLastSmelter and GetLastSmelter
-Fixed comments
-Fixed log reward amounts
This commit is contained in:
Alex Sweet 2018-04-10 23:46:11 -07:00 committed by Alexander Harkness
parent 1e312296cc
commit a0896c63d7
9 changed files with 142 additions and 76 deletions

View File

@ -964,6 +964,16 @@ World:ForEachChestInChunk(Player:GetChunkX(), Player:GetChunkZ(),
}, },
Notes = "Returns true if there's time before the current fuel is depleted", Notes = "Returns true if there's time before the current fuel is depleted",
}, },
GetAndResetReward =
{
Returns =
{
{
Type = "number",
},
},
Notes = "Calculates, resets, and returns the experience reward in this furnace",
},
SetFuelSlot = SetFuelSlot =
{ {
Params = Params =

View File

@ -19,12 +19,13 @@
# #
# **** Recipe and result **** # **** Recipe and result ****
# #
# Cobble @ 200 = Stone -> Produces 1 smooth stone from 1 cobblestone in 200 ticks (10 seconds) # Cobble @ 200 = Stone $ 15 -> Produces 1 smooth stone from 1 cobblestone in 200 ticks (10 seconds). Rewards 15 experience.
# #
# Write in full: # Write in full:
# Cobble : 0 , 1 @ 200 = 1 : 1 , 1 # Cobble : 0 , 1 @ 200 = 1 : 1 , 1 $ 10
# ItemType : Damage , Amount @ ticks = ItemType : Damage , Amount # ItemType : Damage , Amount @ ticks = ItemType : Damage , Amount $ Experience
# #
# If the experience paramater isn't included, experience reward will default to zero.
# #
# **** Fuel **** # **** Fuel ****
# #
@ -42,74 +43,73 @@
#-------------------------- #--------------------------
# Smelting recipes # Smelting recipes
Beef = Steak Beef = Steak $ 0.35
BlackTerracotta = BlackGlazedTerracotta BlackTerracotta = BlackGlazedTerracotta $ 0.1
BlueTerracotta = BlueGlazedTerracotta BlueTerracotta = BlueGlazedTerracotta $ 0.1
BrownTerracotta = BrownGlazedTerracotta BrownTerracotta = BrownGlazedTerracotta $ 0.10
Cactus = CactusGreen Cactus = CactusGreen $ 0.2
ChainmailBoots = IronNugget ChainmailBoots = IronNugget $ 0.1
ChainmailChestplate = IronNugget ChainmailChestplate = IronNugget $ 0.1
ChainmailHelmet = IronNugget ChainmailHelmet = IronNugget $ 0.1
ChainmailLeggings = IronNugget ChainmailLeggings = IronNugget $ 0.1
Chicken = CookedChicken Chicken = CookedChicken $ 0.35
ChorusFruit = PoppedChorusFruit ChorusFruit = PoppedChorusFruit $ 0.1
Clay = Brick Clay = Brick $ 0.3
ClayBlock = HardenedClay ClayBlock = HardenedClay $ 0.35
CoalOre = Coal CoalOre = Coal $ 0.1
Cobblestone = Stone Cobblestone = Stone $ 0.1
CrackedStonebrick = Stonebrick CyanTerracotta = CyanGlazedTerracotta $ 0.1
CyanTerracotta = CyanGlazedTerracotta DiamondOre = Diamond $ 1.0
DiamondOre = Diamond EmeraldOre = Emerald $ 1.0
EmeraldOre = Emerald Fish = CookedFish $ 0.35
Fish = CookedFish GoldOre = GoldIngot $ 1.0
GoldOre = GoldIngot GoldAxe = GoldNugget $ 0.1
GoldAxe = GoldNugget GoldBoots = GoldNugget $ 0.1
GoldBoots = GoldNugget GoldChestplate = GoldNugget $ 0.1
GoldChestplate = GoldNugget GoldHorseArmor = GoldNugget $ 0.1
GoldHorseArmor = GoldNugget GoldHelmet = GoldNugget $ 0.1
GoldHelmet = GoldNugget GoldHoe = GoldNugget $ 0.1
GoldHoe = GoldNugget GoldPants = GoldNugget $ 0.1
GoldPants = GoldNugget GoldPickaxe = GoldNugget $ 0.1
GoldPickaxe = GoldNugget GoldShovel = GoldNugget $ 0.1
GoldShovel = GoldNugget GoldSword = GoldNugget $ 0.1
GoldSword = GoldNugget GrayTerracotta = GrayGlazedTerracotta $ 0.1
GrayTerracotta = GrayGlazedTerracotta GreenTerracotta = GreenGlazedTerracotta $ 0.1
GreenTerracotta = GreenGlazedTerracotta IronOre = IronIngot $ 0.7
IronOre = IronIngot IronAxe = IronNugget $ 0.1
IronAxe = IronNugget IronBoots = IronNugget $ 0.1
IronBoots = IronNugget IronChestplate = IronNugget $ 0.1
IronChestplate = IronNugget IronHorseArmor = IronNugget $ 0.1
IronHorseArmor = IronNugget IronHelmet = IronNugget $ 0.1
IronHelmet = IronNugget IronHoe = IronNugget $ 0.1
IronHoe = IronNugget IronLeggings = IronNugget $ 0.1
IronLeggings = IronNugget IronPickaxe = IronNugget $ 0.1
IronPickaxe = IronNugget IronShovel = IronNugget $ 0.1
IronShovel = IronNugget IronSword = IronNugget $ 0.1
IronSword = IronNugget LapisOre = LapisLazuli $ 0.2
LapisOre = LapisLazuli LightBlueTerracotta = LightBlueGlazedTerracotta $ 0.1
LightBlueTerracotta = LightBlueGlazedTerracotta LightGrayTerracotta = LightGrayGlazedTerracotta $ 0.1
LightGrayTerracotta = LightGrayGlazedTerracotta LimeTerracotta = LimeGlazedTerracotta $ 0.1
LimeTerracotta = LimeGlazedTerracotta Log = CharCoal $ 0.15
Log = CharCoal Log2 = CharCoal $ 0.15
Log2 = CharCoal MagentaTerracotta = MagentaGlazedTerracotta $ 0.1
MagentaTerracotta = MagentaGlazedTerracotta Mutton = CookedMutton $ 0.35
Mutton = CookedMutton NetherQuartzOre = NetherQuartz $ 0.2
NetherQuartzOre = NetherQuartz Netherrack = NetherBrick $ 0.1
Netherrack = NetherBrick OrangeTerracotta = OrangeGlazedTerracotta $ 0.1
OrangeTerracotta = OrangeGlazedTerracotta PinkTerracotta = PinkGlazedTerracotta $ 0.1
PinkTerracotta = PinkGlazedTerracotta Porkchop = CookedPorkchop $ 0.35
Porkchop = CookedPorkchop Potato = BakedPotato $ 0.35
Potato = BakedPotato PurpleTerracotta = PurpleGlazedTerracotta $ 0.1
PurpleTerracotta = PurpleGlazedTerracotta Rabbit = CookedRabbit $ 0.35
Rabbit = CookedRabbit RedTerracotta = RedGlazedTerracotta $ 0.1
RedTerracotta = RedGlazedTerracotta RedstoneOre = Redstone $ 0.7
RedstoneOre = Redstone Salmon = CookedSalmon $ 0.35
Salmon = CookedSalmon Sand = Glass $ 0.1
Sand = Glass StoneBrick = CrackedStoneBricks $ 0.1
StoneBrick = CrackedStoneBricks WetSponge = Sponge $ 0.15
WetSponge = Sponge WhiteTerracotta = WhiteGlazedTerracotta $ 0.1
WhiteTerracotta = WhiteGlazedTerracotta YellowTerracotta = YellowGlazedTerracotta $ 0.1
YellowTerracotta = YellowGlazedTerracotta

View File

@ -32,6 +32,7 @@ cFurnaceEntity::cFurnaceEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, in
m_TimeCooked(0), m_TimeCooked(0),
m_FuelBurnTime(0), m_FuelBurnTime(0),
m_TimeBurned(0), m_TimeBurned(0),
m_RewardCounter(0),
m_IsLoading(false) m_IsLoading(false)
{ {
m_Contents.AddListener(*this); 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) void cFurnaceEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
{ {
cWindow * Window = GetWindow(); cWindow * Window = GetWindow();
@ -189,6 +207,7 @@ void cFurnaceEntity::BroadcastProgress(short a_ProgressbarID, short a_Value)
void cFurnaceEntity::FinishOne() void cFurnaceEntity::FinishOne()
{ {
m_TimeCooked = 0; m_TimeCooked = 0;
m_RewardCounter += m_CurrentRecipe->Reward;
if (m_Contents.GetSlot(fsOutput).IsEmpty()) if (m_Contents.GetSlot(fsOutput).IsEmpty())
{ {

View File

@ -84,6 +84,9 @@ public:
/** Returns true if there's time left before the current fuel is depleted */ /** Returns true if there's time left before the current fuel is depleted */
bool HasFuelTimeLeft(void) const { return (GetFuelBurnTimeLeft() > 0); } bool HasFuelTimeLeft(void) const { return (GetFuelBurnTimeLeft() > 0); }
/** Calculates, resets, and returns the experience reward in this furnace */
int GetAndResetReward(void);
// tolua_end // tolua_end
void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned) void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned)
@ -130,6 +133,9 @@ protected:
/** Amount of ticks that the current fuel has been burning */ /** Amount of ticks that the current fuel has been burning */
int m_TimeBurned; int m_TimeBurned;
/** Running total of experience that can be picked up */
float m_RewardCounter;
/** Is the block currently being loaded into the world? */ /** Is the block currently being loaded into the world? */
bool m_IsLoading; bool m_IsLoading;

View File

@ -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()); Line.erase(std::remove_if(Line.begin(), Line.end(), isspace), Line.end());
int CookTime = 200; int CookTime = 200;
float Reward = 0;
std::unique_ptr<cItem> InputItem = cpp14::make_unique<cItem>(); std::unique_ptr<cItem> InputItem = cpp14::make_unique<cItem>();
std::unique_ptr<cItem> OutputItem = 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; return;
} }
} }
const AStringVector & OutputSplit = StringSplit(Sides[1], "$");
if (!ParseItem(Sides[1], *OutputItem)) 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()); LOGINFO("Offending line: \"%s\"", a_Line.c_str());
return; 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; cRecipe Recipe;
Recipe.In = InputItem.release(); Recipe.In = InputItem.release();
Recipe.Out = OutputItem.release(); Recipe.Out = OutputItem.release();
Recipe.CookTime = CookTime; Recipe.CookTime = CookTime;
Recipe.Reward = Reward;
m_pState->Recipes.push_back(Recipe); m_pState->Recipes.push_back(Recipe);
} }

View File

@ -30,6 +30,7 @@ public:
cItem * In; cItem * In;
cItem * Out; cItem * Out;
int CookTime; ///< How long this recipe takes to smelt, in ticks 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 */ /** Returns a recipe for the specified input, nullptr if no recipe found */

View File

@ -1051,3 +1051,15 @@ AString StringsConcat(const AStringVector & a_Strings, char a_Separator)
} }
return res; 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;
}

View File

@ -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. */ /** Concatenates the specified strings into a single string, separated by the specified separator. */
extern AString StringsConcat(const AStringVector & a_Strings, char a_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);

View File

@ -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) void cSlotAreaFurnace::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item)
{ {
UNUSED(a_Player);
m_Furnace->SetSlot(a_SlotNum, a_Item); 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) 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. */ /** TODO 2014-05-12 xdot: Figure out when to call this method. */
switch (a_Result.m_ItemType) switch (a_Result.m_ItemType)
{ {