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",
},
GetAndResetReward =
{
Returns =
{
{
Type = "number",
},
},
Notes = "Calculates, resets, and returns the experience reward in this furnace",
},
SetFuelSlot =
{
Params =

View File

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

View File

@ -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())
{

View File

@ -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;

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());
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);
}

View File

@ -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 */

View File

@ -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;
}

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. */
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)
{
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)
{